Files
HMDesign/src/foundation/color.stories.tsx
T
shkim4 65cc256cfd style(storybook): refine foundation color chips and typography layout
- Hanmac Color: continuous spectrum band (8/4/2 columns by width), 120px
  swatches with name, role and HEX inside, Default/Light 4 role lines
- Company Colors: separate 120px chips (12px padding, 4px radius),
  name top left and HEX bottom right; company layout and data unchanged
- Typography: Font Family/Weight in two columns with info | preview rows,
  vertically centered specimens grouped by component, Text Colors chips
  with 14px Medium names
- Shared colorHex/textTone helpers pick the first text tone reaching 4.5:1
- Update brand color guide and WORKING_CONTEXT
2026-11-12 14:50:34 +09:00

48 lines
2.9 KiB
TypeScript

import type { Meta, StoryObj } from "@storybook/react-vite"
import { runtimeThemeContract, type RuntimeThemeToken } from "@hm-design/ui/theme"
import { colorHex, ReferencePage, ReferenceSection, textTone, textToneProperties, useResolvedProperties } from "./reference"
// Keep the confirmed eight stages; presentation changes never alter Theme values.
const stages = ["light-4", "light-3", "light-2", "light-1", "default", "dark-1", "dark-2", "dark-3"] as const
const palettes = [
{ name: "한맥그린", prefix: "green" },
{ name: "한맥브라운", prefix: "brown" },
{ name: "한맥오렌지", prefix: "orange" },
] as const
type ColorStage = typeof stages[number]
type PalettePrefix = typeof palettes[number]["prefix"]
// Stage names stay plain; Default and Light 4 add a role line under the name (ColorChip).
const stageLabel = (stage: ColorStage) => stage.replaceAll("-", " ").replace(/^./, letter => letter.toUpperCase())
const stageNote: Partial<Record<ColorStage, string>> = { "light-4": "보더 하이라이트용", default: "기본색" }
const paletteToken = (prefix: PalettePrefix, stage: ColorStage) => `color.palette.${prefix}-${stage}` as RuntimeThemeToken
// Palette values plus the swatch text candidates (textTone, reference.tsx).
const colorProperties = [...palettes.flatMap(palette => stages.map(stage => runtimeThemeContract[paletteToken(palette.prefix, stage)].property)), ...textToneProperties]
function ColorChip({ prefix, stage, values }: { prefix: PalettePrefix; stage: ColorStage; values: Record<string, string> }) {
const token = paletteToken(prefix, stage)
const definition = runtimeThemeContract[token]
const hex = colorHex(values[definition.property])
return <article className="hm-brand-color-chip" data-color-stage={stage} data-color-token={token} data-text-tone={textTone(hex, values)}>
<div className="hm-foundation-swatch" style={{ background: `var(${definition.property})` }}>
<div className="hm-color-name">
<h3>{stageLabel(stage)}</h3>
{stageNote[stage] && <p className="hm-color-note">{stageNote[stage]}</p>}
</div>
<p data-color-value>{hex}</p>
</div>
</article>
}
function ColorReferencePage() {
const values = useResolvedProperties(colorProperties)
return <ReferencePage title="한맥 컬러">
{palettes.map(palette => <ReferenceSection key={palette.name} title={palette.name} note="">
<div className="hm-brand-color-row" data-palette={palette.prefix}>{stages.map(stage => <ColorChip key={stage} prefix={palette.prefix} stage={stage} values={values} />)}</div>
</ReferenceSection>)}
</ReferencePage>
}
// The sidebar name is "한맥 컬러"; `id` keeps the existing Story ID (foundation-color--all) stable.
const meta = { title: "Foundation/한맥 컬러", id: "foundation-color", parameters: { layout: "fullscreen" } } satisfies Meta
export default meta
export const All: StoryObj<typeof meta> = { name: "한맥 컬러", render: () => <ColorReferencePage /> }