import { useEffect, useRef, useState } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { typographyProperties, typographyReferences } from "./reference-data" import { StorySectionGrid } from "../components/story-page" import { colorHex, ReferencePage, ReferenceSection, textTone, textToneProperties, useResolvedProperties } from "./reference" type TypographyReference = (typeof typographyReferences)[number] const weights = [ { property: "--hm-input-font-weight", label: "Regular" }, { property: "--hm-font-weight-medium", label: "Medium" }, { property: "--hm-font-weight-bold", label: "Bold" }, ] // Left column: text styles. Right column: form controls. Together they cover every entry in typographyReferences. const textLabels = ["Page Header · title", "Card · title", "Page Header · description", "Label"] const textRows = typographyReferences.filter(item => textLabels.includes(item.label)) const controlRows = typographyReferences.filter(item => !textLabels.includes(item.label)) // Admin text colors (Web / Chart / OrgChart; not SW). The chip color and HEX read the current token; no color is hardcoded here. const textColorRoles = [ { label: "Primary", name: "기본 텍스트", token: "--hm-sem-fg-primary" }, { label: "Secondary", name: "보조 텍스트", token: "--hm-sem-fg-secondary" }, { label: "Placeholder", name: "입력 안내", token: "--hm-sem-fg-placeholder" }, // Transparent readonly Input on the beige surface uses Secondary (Placeholder is below 4.5:1 there). { label: "Readonly Placeholder", name: "읽기 전용 입력 안내", token: "--hm-sem-fg-secondary" }, ] // Chip colors plus the swatch text candidates (textTone, reference.tsx). const textColorProperties = [...new Set([...textColorRoles.map(item => item.token), ...textToneProperties])] // Same chip as Foundation/가족사 컬러 (separate chips; shared swatch rules in foundation.css via data-text-colors): role name and // usage at the top left, HEX at the bottom right, text tone by contrast. function TextColorChips({ values }: { values: Record }) { return
{textColorRoles.map(item => { const hex = colorHex(values[item.token]) return

{item.label}

{item.name}

{hex}

})}
} function SpecimenRow({ label, size, line, weight }: TypographyReference & { weight?: string }) { const ref = useRef(null) const [metrics, setMetrics] = useState({ main: "", spacing: "" }) useEffect(() => { let mounted = true void document.fonts.ready.then(() => { if (!mounted || !ref.current) return const style = getComputedStyle(ref.current) setMetrics({ main: `${style.fontSize} / ${style.lineHeight} / ${style.fontWeight}`, spacing: `letter-spacing: ${style.letterSpacing}` }) }) return () => { mounted = false } }, []) // The sample at its real component size leads; the item name and the computed metrics sit beside it as secondary text. return
  • {label.split(" · ")[1] ?? label} {metrics.main}{metrics.spacing}
    한맥 Hanmac 0123
  • } // Rows grouped by component, the label part before " · " (Page Header, Card, Label, Input, Button Standard). const groupOf = (item: TypographyReference) => item.label.split(" · ")[0] function SpecimenGroups({ rows }: { rows: readonly TypographyReference[] }) { return
    {[...new Set(rows.map(groupOf))].map(group =>

    {group}

      {rows.filter(item => groupOf(item) === group).map(item => )}
    )}
    } function TypographyReferencePage() { const values = useResolvedProperties(typographyProperties) const colorValues = useResolvedProperties(textColorProperties) // Section rhythm and the content indent (.sb-page-indent) come from the common Story page. Text Colors keeps its chip grid on the edge. return

    Primary Typeface

    Noto Sans KR

    한맥 Hanmac 0123

    --hm-font-family-base: {values["--hm-font-family-base"]}
    {weights.map(({ property, label }) =>

    {label} {values[property]}

    {property}

    한맥 Hanmac 0123

    )}
    } // The sidebar name is "폰트"; `id` keeps the existing Story ID (foundation-typography--all) stable. const meta = { title: "Foundation/폰트", id: "foundation-typography", parameters: { layout: "fullscreen" } } satisfies Meta export default meta export const All: StoryObj = { name: "폰트", render: () => }