Initial commit: HMDesignSystem baseline
This commit is contained in:
commit
b6a0a61103
486 files changed
+68432
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { useEffect, useRef, useState, type ReactNode } from "react"
|
||||
import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
||||
import "./foundation.css"
|
||||
|
||||
export function useResolvedProperties(properties: readonly string[]) {
|
||||
const [values, setValues] = useState<Record<string, string>>({})
|
||||
useEffect(() => {
|
||||
let frame = 0
|
||||
const read = () => {
|
||||
cancelAnimationFrame(frame)
|
||||
frame = requestAnimationFrame(() => {
|
||||
const style = getComputedStyle(document.documentElement)
|
||||
const next = Object.fromEntries(properties.map(property => [property, style.getPropertyValue(property).trim()]))
|
||||
setValues(previous => properties.every(property => previous[property] === next[property]) ? previous : next)
|
||||
})
|
||||
}
|
||||
read()
|
||||
const observer = new MutationObserver(read)
|
||||
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["style", "class", "data-hm-theme"] })
|
||||
window.addEventListener("resize", read)
|
||||
return () => { observer.disconnect(); window.removeEventListener("resize", read); cancelAnimationFrame(frame) }
|
||||
}, [properties])
|
||||
return values
|
||||
}
|
||||
|
||||
// The page frame, title and sections are the common Story page (src/components/story-page.tsx); .hm-foundation styles the reference content.
|
||||
export function ReferencePage({ title, intro, children }: { title: string; intro: string; children: ReactNode }) {
|
||||
return <StoryPage className="hm-foundation"><StoryPageHeader kicker={STORY_KICKER.foundation} title={title} description={intro} />{children}</StoryPage>
|
||||
}
|
||||
export function ReferenceSection({ title, note, children, id }: { title: string; note: string; children: ReactNode; id?: string }) {
|
||||
return <StorySection id={id} title={title} description={note}>{children}</StorySection>
|
||||
}
|
||||
export function Specimen({ label, size, line, weight }: { label: string; size: string; line: string; weight?: string }) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const [metrics, setMetrics] = useState("")
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
void document.fonts.ready.then(() => {
|
||||
if (!mounted || !ref.current) return
|
||||
const style = getComputedStyle(ref.current)
|
||||
setMetrics(`${style.fontSize} / ${style.lineHeight} / ${style.fontWeight} · letter-spacing: ${style.letterSpacing}`)
|
||||
})
|
||||
return () => { mounted = false }
|
||||
}, [])
|
||||
return <div className="hm-foundation-specimen" ref={ref} data-typography-sample={label} style={{ fontSize: `var(${size})`, lineHeight: `var(${line})`, fontWeight: weight ? `var(${weight})` : "normal" }}><p lang="ko">가나다라마바사 아자차카타파하 · 한맥 프로젝트</p><p lang="en">ABCDEFGHIJKLMNOPQRSTUVWXYZ<br />abcdefghijklmnopqrstuvwxyz</p><p>0123456789</p><small className="hm-foundation-note" data-typography-metrics>{metrics}</small></div>
|
||||
}
|
||||
Reference in new issue
Block a user