import { useState, type CSSProperties, type ReactNode } from "react" import { createPortal } from "react-dom" import type { Meta, StoryObj } from "@storybook/react-vite" import { withSWNotice } from "./sw-story-notice" import { SWFooter, SWFooterCommandLine, SWHeader, SWTheme, SWViewerButton, SWViewerHeader, SWViewerHint, SWViewerSection, } from "@hm-design/sw" import "@hm-design/sw/styles.css" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { AUX_ITEMS, CATEGORIES, HISTORY } from "./sw-footer-fixture" import { LayerPanel, OptionsPanel, SAMPLES, VIEWER_STORY_LOGO, useViewerDemo } from "./sw-viewer-fixture" import "./sw-stories.css" import "./sw-viewer-stories.css" // SW theme token inheritance (2026-10-20). The official way to change SW tokens: set them through `style` (or the // consumer's own class) on the OUTERMOST SW scope — around the screen, or the component root when it is // used alone. Nested SW roots (viewer menus, More, panels, footer command line) inherit the value. // Dotum is used here ONLY to make the inheritance visible: the SW default font is Noto Sans KR (2026-10-20 decision). const KICKER = "HM DESIGN SYSTEM / SW" const VERIFY_FONT = 'Dotum, "돋움", sans-serif' const VERIFY_THEME = { "--hm-sw-header-font-family": VERIFY_FONT } as CSSProperties const NESTED_THEME = { "--hm-sw-header-font-family": '"Malgun Gothic", sans-serif' } as CSSProperties const meta = { title: "SW/Theme", parameters: { layout: "fullscreen", controls: { disable: true } }, decorators: [withSWNotice], } satisfies Meta export default meta type Story = StoryObj function Frame({ width, height, header, children, ...rest }: { width: number; height: number; header: ReactNode; children?: ReactNode; [data: `data-${string}`]: string }) { return (
{header}
{children}
) } function ViewerArea({ width, panels, ...rest }: { width: number; panels?: boolean; [data: `data-${string}`]: string }) { const demo = useViewerDemo({ initialDocument: SAMPLES[1].name, initialPanels: panels ? ["layers", "options"] : [] }) return ( }> {panels && <> } ) } function PortalDemo() { const [target, setTarget] = useState(null) const content = (label: string) => ( Portal로 테마 영역 밖에 렌더링한 SW 요소 확인 ) return (
{/* The portals are created inside the themed scope, but their DOM lands in the target below (outside it). */} 이 영역(테마 지정)에서 아래 대상 영역으로 Portal을 만듭니다. {target && createPortal({content("SWTheme만 (테마 미전달 → 기본 글꼴)")}, target)} {target && createPortal({content("SWTheme + 같은 theme style (테마 전달)")}, target)}
) } export const ThemeInheritance: Story = { name: "Theme Inheritance", // 2026-10-21 SW Storybook menu cleanup: hidden from the sidebar; ID and direct URL kept for the existing checks. tags: ["verification"], render: () => ( SW 토큰은 가장 바깥 SW 범위(<SWTheme> 또는 단독 컴포넌트 루트)에서 한 번 선언되고, 안쪽 Dropdown·More·패널·명령창은 그 값을 상속합니다. 토큰은 가장 바깥 범위의 style로만 바꿉니다. 아래 Dotum은 상속 확인용 검증 값이며 SW 기본 글꼴(Noto Sans KR)은 바뀌지 않습니다(Dotum 기본 적용은 디자인 승인 대기).} />
{}} slotGuide={{}} command={} />
영역 A — 검증 글꼴(Dotum) 영역 B — 기본(Noto Sans KR) 영역 C 바깥 — Dotum 영역 C 안쪽 — Malgun Gothic
), }