Merge pull request 'style(storybook): unify content hierarchy and section spacing' (#43) from style/storybook-common-hierarchy into main
Deploy Storybook / deploy (push) Successful in 1m1s
Deploy Storybook / deploy (push) Successful in 1m1s
Reviewed-on: #43
This commit was merged in pull request #43.
This commit is contained in:
commit
3ddacb19d5
14 files changed
+89
-30
No files matched your search
@@ -1,5 +1,14 @@
|
|||||||
# Working Context
|
# Working Context
|
||||||
|
|
||||||
|
## 2026-11-11 — Storybook 섹션 간격·정보 영역 들여쓰기 공통화, Foundation 폰트 위계 (main 기준, 미커밋)
|
||||||
|
|
||||||
|
- 공통 프레임 `src/components/story-page.css`: H2 16/24/700 → 12px → 구분선 → 16px → 콘텐츠(섹션 헤더 padding-bottom 8→12, margin-bottom 12→16), 섹션 사이 `--sb-page-section-gap` 24→28px. `StorySectionGrid`는 row gap만 이 변수를 따르고 column gap 24px은 유지(Chart 2열 미리보기 폭 불변). SW `sw-story-stack`·Footer 너비 행, Foundation Layout도 변수로 28px.
|
||||||
|
- 선택 들여쓰기 `.sb-page-indent`(`--sb-page-indent` 16px, 640px 이하 12px, `padding-left`): 문서 텍스트·사양 표 같은 정보 블록에만 붙인다. 실제 컴포넌트·Pattern·Chart·OrgChart·SW·CENTER 미리보기와 테두리 있는 카드/칩 Grid(한맥·가족사 컬러, Layout, Text Colors)는 들여쓰지 않는다. 현재 사용처는 Foundation/폰트의 Font Family·Font Weight·Specimens.
|
||||||
|
- `StateBoard` H3 라벨 14/20/500 보조색·행 간격 24px 유지(주석만 갱신). 좌우·상단 여백, 접근성 H1, Story ID 불변.
|
||||||
|
- Foundation/폰트(`typography.stories.tsx`, `foundation.css`): Text Colors 칩을 이름(14/700 Primary)·용도(14/400 Secondary)·HEX(12/18/400 Secondary) 3줄로 분리, Font Family 이름+대체 폰트 / CSS 변수 2줄, Font Weight CSS 변수 12px, Specimens 행 위·아래 12px·열 오른쪽 16px·고정폭 숫자. 실제 샘플 스펙(10개)은 불변. 전용 간격 덮어쓰기(`.hm-typo-page`)는 공통 규칙으로 대체해 제거.
|
||||||
|
- 기준 문서: `docs/guidelines/프로젝트-지침.md` §6 Storybook 페이지 프레임 항목.
|
||||||
|
- 하위 그룹 들여쓰기(같은 날 후속): `StateBoard`(`StorySection` 안)·Card `CardBoard`는 `data-sb-board`만 표시하고, `story-page.css`의 `.sb-page-section-body > :is([data-sb-board], :has([data-sb-board]))`가 섹션 본문 직계 블록에 한 번만 `--sb-page-indent`(16px, 640px 이하 12px)를 준다. Story 전용 Grid의 열마다 단일 보드를 둔 34개 Story의 열별 중복 들여쓰기(보이는 그룹 간격 40px)를 제거해 24px 복원. Input·Select·Toggle Sizes Grid는 `.sb-page-indent`(Input·Select의 Small/Medium/Large는 필드 Label #212121 유지). 전체 폭 Pattern 4개(GNB·LNB·Loading Screen·Page Header)는 `indent={false}`, Toggle Group(내부 검증·라벨 없음)과 단일 미리보기는 제외. 섹션 제목 X(1024/1440 60px, 390 16px) 불변, 첫 그룹 X 76px / 28px.
|
||||||
|
|
||||||
## 2026-11-11 — Admin 텍스트 컬러 위계·Foundation Gray (브랜치 `style/admin-text-gray-hierarchy`, 미커밋)
|
## 2026-11-11 — Admin 텍스트 컬러 위계·Foundation Gray (브랜치 `style/admin-text-gray-hierarchy`, 미커밋)
|
||||||
|
|
||||||
- Theme: `themes/default.json`에 `color.palette.gray-900|800|700|600|500`(#212121·#424242·#616161·#757575·#9E9E9E) 추가, `color.fg.primary|secondary|placeholder` 기본값을 #212121 / #616161 / #757575로 변경. 템플릿 텍스트 alias만 Gray를 가리키고 브랜드 Primitive 값은 불변. `contract.ts` 공개 키 5개 추가(기존 키 불변). 생성물은 `generate:theme-defaults`.
|
- Theme: `themes/default.json`에 `color.palette.gray-900|800|700|600|500`(#212121·#424242·#616161·#757575·#9E9E9E) 추가, `color.fg.primary|secondary|placeholder` 기본값을 #212121 / #616161 / #757575로 변경. 템플릿 텍스트 alias만 Gray를 가리키고 브랜드 Primitive 값은 불변. `contract.ts` 공개 키 5개 추가(기존 키 불변). 생성물은 `generate:theme-defaults`.
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ HM 지정값이 있는 색상, radius, control height, typography 등은 Theme T
|
|||||||
- 컴포넌트가 실제 지원하는 default, variant, size, disabled 및 주요 상태를 확인한다. invalid, open 등 해당 컴포넌트에 실제로 있는 상태만 다루고, 없는 상태를 문서화를 위해 만들지 않는다.
|
- 컴포넌트가 실제 지원하는 default, variant, size, disabled 및 주요 상태를 확인한다. invalid, open 등 해당 컴포넌트에 실제로 있는 상태만 다루고, 없는 상태를 문서화를 위해 만들지 않는다.
|
||||||
- Storybook은 구현 Reference Catalog이자 컴포넌트 단위의 검수와 사용법 문서화 도구다. 신규 UI 구현 전 유사 대표/PRIMARY Story를 먼저 확인한다. `Demo/App` 화면은 여러 컴포넌트를 조합한 적용 결과 확인용이며, Demo의 페이지·타일 UI를 Story의 기준으로 쓰지 않는다.
|
- Storybook은 구현 Reference Catalog이자 컴포넌트 단위의 검수와 사용법 문서화 도구다. 신규 UI 구현 전 유사 대표/PRIMARY Story를 먼저 확인한다. `Demo/App` 화면은 여러 컴포넌트를 조합한 적용 결과 확인용이며, Demo의 페이지·타일 UI를 Story의 기준으로 쓰지 않는다.
|
||||||
- 컴포넌트 Story는 현재 HM 대표 Story의 공통 구조를 따른다. 컴포넌트 이름의 대표 Story 하나에 종류·크기·상태를 한 화면으로 모으고, 같은 구역을 `verification` 태그 Story(예: Roles, Sizes, Brand States)로도 둔다. `verification` Story는 메뉴와 검색에서 기본으로 숨기고(`.storybook/main.ts`의 `tags`) 직접 URL과 사이드바 태그 필터로 연다. HM 전용 Story(Playground, Compatibility)도 같은 태그로 숨긴다. 기본 사이드바에는 컴포넌트가 하위 메뉴 없는 1뎁스 항목 하나로만 보이고(대표 Story 하나만 노출되면 Storybook이 컴포넌트 항목에 합친다), 클릭하면 한 페이지에서 전체 검수 내용이 열린다. Story 이름과 순서, 행·열 구성은 현재 HM 유사 대표 Story의 공통 구성을 먼저 따른다. 외부 ui_viz Story는 제공된 경우에만 충돌하지 않는 참고로 사용한다.
|
- 컴포넌트 Story는 현재 HM 대표 Story의 공통 구조를 따른다. 컴포넌트 이름의 대표 Story 하나에 종류·크기·상태를 한 화면으로 모으고, 같은 구역을 `verification` 태그 Story(예: Roles, Sizes, Brand States)로도 둔다. `verification` Story는 메뉴와 검색에서 기본으로 숨기고(`.storybook/main.ts`의 `tags`) 직접 URL과 사이드바 태그 필터로 연다. HM 전용 Story(Playground, Compatibility)도 같은 태그로 숨긴다. 기본 사이드바에는 컴포넌트가 하위 메뉴 없는 1뎁스 항목 하나로만 보이고(대표 Story 하나만 노출되면 Storybook이 컴포넌트 항목에 합친다), 클릭하면 한 페이지에서 전체 검수 내용이 열린다. Story 이름과 순서, 행·열 구성은 현재 HM 유사 대표 Story의 공통 구성을 먼저 따른다. 외부 ui_viz Story는 제공된 경우에만 충돌하지 않는 참고로 사용한다.
|
||||||
- Storybook 페이지 프레임(2026-11-11 확정)은 `src/components/story-page.tsx`·`story-page.css`의 `StoryPage`·`StoryPageHeader`·`StorySection`·`StorySectionGrid`가 공통으로 소유한다. 2026-11-11 사용자 요청으로 `StoryPageHeader`는 H1 페이지 제목·kicker·설명·SW 공통 안내 문구를 표시하지 않으며(호출과 props는 유지), 페이지는 위 여백(16–24px) 바로 아래 첫 섹션부터 시작한다. 단, Preview 문서 제목이 Story ID라 스크린 리더가 페이지를 식별할 수 있도록 `title`만 시각적으로 숨긴 접근성 전용 H1(`.sb-page-a11y-title`, 1px clip·문서 흐름 밖)로 렌더링한다. 검증 스크립트는 이 H1의 시각 스타일에 의존하지 않고 첫 콘텐츠 블록(`.sb-page-inner > :not(h1)`)으로 렌더링을 기다리며, 페이지 식별은 H1 텍스트로 한다. 제품 `PageHeader` 컴포넌트와는 무관하다. Web·Chart·OrgChart(Admin)의 문서 위계는 H2 섹션 제목 16/24/700과 얇은 구분선 → 12px → 예제이며, 섹션 사이는 24px, `StateBoard`의 H3 라벨은 14/20/500 보조색이고 자체 구분선을 두지 않는다. 위·아래 여백은 16–24px, 좌우 여백은 기존 값(480px까지 16px, 768px부터 60px)을 유지한다. 값은 기존 Component Token을 `--sb-page-*`로 참조하며 새 Design Token이 아니다. 섹션을 나란히 놓을 때는 `StorySectionGrid`를 쓰고, Story별 `!important`·`[&_.sb-page-*]` 덮어쓰기로 간격을 바꾸지 않는다. SW와 노선도(CENTER)는 이 페이지 프레임과 섹션 간격만 공유하고 컴포넌트 크기·글꼴·캔버스·카드 규격은 각자 유지한다. 페이지 제목은 사이드바 이름을 따르며, 한 그룹에 Story가 여럿이면 `그룹 — Story 이름`(예: `SW Header — 화면 너비`)으로 쓴다. 섹션 제목은 페이지 제목과 예제 카드 제목을 반복하지 않는 짧은 변형명(예: Chart `Basic`, `Label`, `Solid`)으로 쓴다.
|
- Storybook 페이지 프레임(2026-11-11 확정)은 `src/components/story-page.tsx`·`story-page.css`의 `StoryPage`·`StoryPageHeader`·`StorySection`·`StorySectionGrid`가 공통으로 소유한다. 2026-11-11 사용자 요청으로 `StoryPageHeader`는 H1 페이지 제목·kicker·설명·SW 공통 안내 문구를 표시하지 않으며(호출과 props는 유지), 페이지는 위 여백(16–24px) 바로 아래 첫 섹션부터 시작한다. 단, Preview 문서 제목이 Story ID라 스크린 리더가 페이지를 식별할 수 있도록 `title`만 시각적으로 숨긴 접근성 전용 H1(`.sb-page-a11y-title`, 1px clip·문서 흐름 밖)로 렌더링한다. 검증 스크립트는 이 H1의 시각 스타일에 의존하지 않고 첫 콘텐츠 블록(`.sb-page-inner > :not(h1)`)으로 렌더링을 기다리며, 페이지 식별은 H1 텍스트로 한다. 제품 `PageHeader` 컴포넌트와는 무관하다. Web·Chart·OrgChart(Admin)의 문서 위계는 H2 섹션 제목 16/24/700 → 12px → 얇은 구분선 → 16px → 콘텐츠이며, 섹션 사이는 28px(`--sb-page-section-gap`; `StorySectionGrid`의 column gap 24px은 별도 유지), `StateBoard`의 H3 라벨은 14/20/500 보조색이고 자체 구분선을 두지 않으며 행 사이 24px이다. 구분선 아래 문서 텍스트·사양 표 같은 정보 블록만 `.sb-page-indent`(16px, 640px 이하 12px)로 묶음 단위로 들여쓰고, 실제 컴포넌트·Pattern·Chart·OrgChart·SW·CENTER 미리보기와 테두리 있는 카드/칩 Grid는 섹션 왼쪽 기준선에 둔다. 예외로 그룹 보드(H3 그룹 라벨 + 해당 예제)는 같은 들여쓰기(`--sb-page-indent`)를 받아 섹션 제목(L1) → 그룹 라벨(L2) → 예제(L3) 위계를 만든다. `StateBoard`(`StorySection` 안)와 Card의 `CardBoard`는 `data-sb-board`로 표시만 하고, `story-page.css`가 섹션 본문의 직계 자식 중 보드이거나 보드를 품은 블록 하나에만 들여쓰기를 적용한다. 그래서 Story 전용 Grid의 열마다 단일 그룹 보드를 둔 구성도 Grid 전체가 한 번만 들여써지고 열 간격 24px이 유지된다(열별 중복 들여쓰기 금지). 보드가 없는 Sizes Grid(Input·Select·Toggle)는 Grid에 `.sb-page-indent`를 붙이며, Input·Select의 `Small / Medium / Large`는 실제 필드 Label(Primary)로 유지한다. 전체 폭 Pattern 미리보기(GNB·LNB·Loading Screen·Page Header)는 `indent={false}`로 섹션 기준선을 유지하고, 그룹 라벨 없이 예제만 있는 Toggle Group(내부 검증용)과 단일 미리보기(Menubar·Dropdown Menu·Context Menu 등)는 들여쓰지 않는다. 위·아래 여백은 16–24px, 좌우 여백은 기존 값(480px까지 16px, 768px부터 60px)을 유지한다. 값은 기존 Component Token 또는 Storybook 전용 px 값을 `--sb-page-*`로 이름 붙인 것이며 새 Design Token이 아니다. 섹션을 나란히 놓을 때는 `StorySectionGrid`를 쓰고, Story별 `!important`·`[&_.sb-page-*]` 덮어쓰기로 간격을 바꾸지 않는다. SW와 노선도(CENTER)는 이 페이지 프레임과 섹션 간격만 공유하고 컴포넌트 크기·글꼴·캔버스·카드 규격은 각자 유지한다. 페이지 제목은 사이드바 이름을 따르며, 한 그룹에 Story가 여럿이면 `그룹 — Story 이름`(예: `SW Header — 화면 너비`)으로 쓴다. 섹션 제목은 페이지 제목과 예제 카드 제목을 반복하지 않는 짧은 변형명(예: Chart `Basic`, `Label`, `Solid`)으로 쓴다.
|
||||||
- 대표 Story의 Focus 구역은 pseudo-state 복제 대신 `play` 함수로 실제 요소에 focus를 준다(ui_viz도 Focus는 정적 specimen을 만들지 않는다). hover 같은 상태가 ui_viz에 없으면 `.storybook/pseudo-states.ts`를 쓰지 않는다. 구역 배치 helper는 `src/components/story-board.tsx`의 `StateBoard`를 쓴다.
|
- 대표 Story의 Focus 구역은 pseudo-state 복제 대신 `play` 함수로 실제 요소에 focus를 준다(ui_viz도 Focus는 정적 specimen을 만들지 않는다). hover 같은 상태가 ui_viz에 없으면 `.storybook/pseudo-states.ts`를 쓰지 않는다. 구역 배치 helper는 `src/components/story-board.tsx`의 `StateBoard`를 쓴다.
|
||||||
- hover, pressed 같은 pseudo state는 Storybook이 `:hover`/`:active` 규칙을 `data-sb-hover`/`data-sb-active` 규칙으로 복제해 고정한다(`.storybook/pseudo-states.ts`). 복제만 하고 값을 새로 정의하지 않으므로 실제 디자인을 보정하는 용도로 쓰지 않는다. Story에서는 `data-sb-*` 속성만 붙인다.
|
- hover, pressed 같은 pseudo state는 Storybook이 `:hover`/`:active` 규칙을 `data-sb-hover`/`data-sb-active` 규칙으로 복제해 고정한다(`.storybook/pseudo-states.ts`). 복제만 하고 값을 새로 정의하지 않으므로 실제 디자인을 보정하는 용도로 쓰지 않는다. Story에서는 `data-sb-*` 속성만 붙인다.
|
||||||
- ui_viz에서 값이 `TBD`인 상태(예: Button Focus)는 별도 specimen을 만들지 않고 키보드로 확인하는 안내만 둔다. ui_viz에 없는 상태(예: Button `aria-invalid`)와 `REFERENCE_ONLY` 항목은 검수 Story에 넣지 않는다. shadcn 호환 API는 `Compatibility` Story로 분리한다.
|
- ui_viz에서 값이 `TBD`인 상태(예: Button Focus)는 별도 specimen을 만들지 않고 키보드로 확인하는 안내만 둔다. ui_viz에 없는 상태(예: Button `aria-invalid`)와 `REFERENCE_ONLY` 항목은 검수 Story에 넣지 않는다. shadcn 호환 API는 `Compatibility` Story로 분리한다.
|
||||||
|
|||||||
@@ -36,9 +36,10 @@ function Specimen({ surface = "surface", action, title = "프로젝트 정보",
|
|||||||
|
|
||||||
// Story-only equal-column board for this page: 3 columns on PC, 2 / 1 on narrower widths. Variants and Usage share it,
|
// Story-only equal-column board for this page: 3 columns on PC, 2 / 1 on narrower widths. Variants and Usage share it,
|
||||||
// so a Usage cell has the same width as one Variants cell. Label markup/colors match StateBoard (shared component untouched).
|
// so a Usage cell has the same width as one Variants cell. Label markup/colors match StateBoard (shared component untouched).
|
||||||
|
// `data-sb-board` gives it the same common group indent as StateBoard (story-page.css).
|
||||||
function CardBoard({ states }: { states: BoardState[] }) {
|
function CardBoard({ states }: { states: BoardState[] }) {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 items-start gap-x-6 gap-y-8 min-[640px]:grid-cols-2 min-[900px]:grid-cols-3">
|
<div data-sb-board="" className="grid grid-cols-1 items-start gap-x-6 gap-y-8 min-[640px]:grid-cols-2 min-[900px]:grid-cols-3">
|
||||||
{states.map(({ id, label, children }) => (
|
{states.map(({ id, label, children }) => (
|
||||||
<section className="grid min-w-0 content-start gap-3" key={id} data-overview-state={id} aria-label={label}>
|
<section className="grid min-w-0 content-start gap-3" key={id} data-overview-state={id} aria-label={label}>
|
||||||
<header className="grid gap-2 border-b border-black/10 pb-2">
|
<header className="grid gap-2 border-b border-black/10 pb-2">
|
||||||
|
|||||||
@@ -134,7 +134,10 @@ export const All: Story = {
|
|||||||
<StoryPage>
|
<StoryPage>
|
||||||
<StoryPageHeader title="Input" />
|
<StoryPageHeader title="Input" />
|
||||||
<StorySection title="Sizes">
|
<StorySection title="Sizes">
|
||||||
<SizeComparison showSpec={false} />
|
{/* Same common indent as the group boards below; Small / Medium / Large stay the fields' own Labels. */}
|
||||||
|
<div className="sb-page-indent">
|
||||||
|
<SizeComparison showSpec={false} />
|
||||||
|
</div>
|
||||||
</StorySection>
|
</StorySection>
|
||||||
<StorySection title="States">
|
<StorySection title="States">
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
|||||||
@@ -176,8 +176,9 @@ export const All: Story = {
|
|||||||
<StoryPage>
|
<StoryPage>
|
||||||
<StoryPageHeader title="Select" />
|
<StoryPageHeader title="Select" />
|
||||||
<StorySection title="Sizes">
|
<StorySection title="Sizes">
|
||||||
{/* Same 3-column track as States / Validation: Medium and Large take the first two columns, the third stays empty. */}
|
{/* Same 3-column track as States / Validation: Medium and Large take the first two columns, the third stays empty.
|
||||||
<div className="grid items-start gap-6 [grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))] min-[1000px]:grid-cols-3">
|
The grid takes the same common indent as the group boards (.sb-page-indent); Medium / Large stay field Labels. */}
|
||||||
|
<div className="grid items-start gap-6 sb-page-indent [grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))] min-[1000px]:grid-cols-3">
|
||||||
{sizes.map((spec) => (
|
{sizes.map((spec) => (
|
||||||
<SizeCard key={spec.size} spec={spec} showSpec={false} />
|
<SizeCard key={spec.size} spec={spec} showSpec={false} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -11,12 +11,19 @@ export type BoardState = { id: string; label: string; note?: string; noteAfter?:
|
|||||||
// trigger need whole-pixel columns: a fractional column (e.g. 358.4px) puts the trigger edge between device pixels while the
|
// trigger need whole-pixel columns: a fractional column (e.g. 358.4px) puts the trigger edge between device pixels while the
|
||||||
// popper rounds the popup to whole pixels, so the two outlines end up 1px apart.
|
// popper rounds the popup to whole pixels, so the two outlines end up 1px apart.
|
||||||
// The labels are H3 (14/20/500, secondary) under the section's divider: they carry no divider of their own, and rows sit
|
// The labels are H3 (14/20/500, secondary) under the section's divider: they carry no divider of their own, and rows sit
|
||||||
// 24px apart (the section gap of story-page.css).
|
// 24px apart (one step tighter than the 28px section gap of story-page.css).
|
||||||
export function StateBoard({ states, min = 320, fixed = false }: { states: BoardState[]; min?: number; fixed?: boolean }) {
|
// 2026-11-11: inside a StorySection the board is marked `data-sb-board`; story-page.css then indents, once, the block directly
|
||||||
|
// under the section body that is or holds the board (16px / 12px at 640px and below, --sb-page-indent). Stories that put one
|
||||||
|
// single-group board per column of their own grid therefore get one indent for the whole grid, not one per column, and keep
|
||||||
|
// their 24px column gap. Section title (L1) → group label (L2) → specimen (L3). `indent={false}` leaves the mark off and keeps
|
||||||
|
// the board on the section edge (full-width Pattern previews such as GNB / Page Header).
|
||||||
|
export function StateBoard({ states, min = 320, fixed = false, indent = true }: { states: BoardState[]; min?: number; fixed?: boolean; indent?: boolean }) {
|
||||||
// Inside a StorySection the labels sit one heading level below the section title.
|
// Inside a StorySection the labels sit one heading level below the section title.
|
||||||
const Label = useContext(StorySectionContext) ? "h3" : "h2"
|
const inSection = useContext(StorySectionContext)
|
||||||
|
const Label = inSection ? "h3" : "h2"
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
data-sb-board={inSection && indent ? "" : undefined}
|
||||||
className={`grid items-start gap-x-6 gap-y-6 ${fixed ? "[grid-template-columns:repeat(auto-fill,min(100%,var(--sb-state-min,320px)))]" : "[grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--sb-state-min,320px)),1fr))]"}`}
|
className={`grid items-start gap-x-6 gap-y-6 ${fixed ? "[grid-template-columns:repeat(auto-fill,min(100%,var(--sb-state-min,320px)))]" : "[grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--sb-state-min,320px)),1fr))]"}`}
|
||||||
style={{ "--sb-state-min": `${min}px` } as CSSProperties}
|
style={{ "--sb-state-min": `${min}px` } as CSSProperties}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
/* Storybook presentation only. Common page frame for representative Stories; all selectors stay inside .sb-page.
|
/* Storybook presentation only. Common page frame for representative Stories; all selectors stay inside .sb-page.
|
||||||
2026-11-11 compact document rhythm, shared by Web / Chart / OrgChart (SW and CENTER pages use the same frame only):
|
2026-11-11 compact document rhythm, shared by Web / Chart / OrgChart (SW and CENTER pages use the same frame only):
|
||||||
2026-11-11: the H1 page title / description header is no longer shown (the H1 stays for screen readers only); pages start with the
|
2026-11-11: the H1 page title / description header is no longer shown (the H1 stays for screen readers only); pages start with the
|
||||||
H2 section title 16/24/700 (body-md) over a thin divider → 12px → specimen; sections 24px apart (Dashboard gap);
|
H2 section title 16/24/700 (body-md) → 12px → thin divider → 16px → content; sections 28px apart (2026-11-11 rhythm, first applied
|
||||||
H3 specimen labels 14/20/500 secondary, no divider of their own (story-board.tsx). Top / bottom gutter 16–24px.
|
on Foundation / 폰트); H3 specimen labels 14/20/500 secondary, no divider of their own (story-board.tsx). Top / bottom gutter 16–24px.
|
||||||
Side margins are unchanged (16px up to 480px, growing to 60px at 768px): the SW breakpoints 2040 / 1125 / 787 depend on them.
|
Side margins are unchanged (16px up to 480px, growing to 60px at 768px): the SW breakpoints 2040 / 1125 / 787 depend on them.
|
||||||
No design token is added; --sb-page-* only names existing component token values for this Storybook frame. */
|
Only information blocks (text, spec tables) opt in to the content indent (.sb-page-indent); previews stay on the section edge,
|
||||||
|
except group boards (H3 label + its specimens, marked data-sb-board by StateBoard / CardBoard), indented once per section block below.
|
||||||
|
No design token is added; --sb-page-* only names this Storybook frame's values (component token values or plain px). */
|
||||||
.sb-page {
|
.sb-page {
|
||||||
--sb-page-gutter: clamp(16px, 2vw, 24px);
|
--sb-page-gutter: clamp(16px, 2vw, 24px);
|
||||||
--sb-page-section-gap: 24px;
|
--sb-page-section-gap: 28px;
|
||||||
|
--sb-page-indent: 16px;
|
||||||
--sb-page-section-title-font-size: var(--hm-dialog-body-font-size);
|
--sb-page-section-title-font-size: var(--hm-dialog-body-font-size);
|
||||||
--sb-page-section-title-line-height: var(--hm-dialog-body-line-height);
|
--sb-page-section-title-line-height: var(--hm-dialog-body-line-height);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -46,8 +49,8 @@
|
|||||||
|
|
||||||
.sb-page .sb-page-section { margin-top: var(--sb-page-section-gap); scroll-margin-top: 16px; }
|
.sb-page .sb-page-section { margin-top: var(--sb-page-section-gap); scroll-margin-top: 16px; }
|
||||||
.sb-page .sb-page-section-header {
|
.sb-page .sb-page-section-header {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 12px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 16px;
|
||||||
border-bottom: 1px solid var(--hm-sem-stroke-input-default);
|
border-bottom: 1px solid var(--hm-sem-stroke-input-default);
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
@@ -65,7 +68,16 @@
|
|||||||
font-weight: var(--hm-input-font-weight);
|
font-weight: var(--hm-input-font-weight);
|
||||||
}
|
}
|
||||||
.sb-page .sb-page-section-body { min-width: 0; }
|
.sb-page .sb-page-section-body { min-width: 0; }
|
||||||
|
/* Opt-in content indent for information blocks under a section divider (title and divider stay on the edge). Put it on the block
|
||||||
|
that holds the whole group (a grid, a table pair), not on single cells. Never on previews, bordered card grids or SW full-width examples. */
|
||||||
|
.sb-page .sb-page-indent { padding-left: var(--sb-page-indent); }
|
||||||
|
/* Group boards (StateBoard / CardBoard mark themselves data-sb-board): the same indent, applied once to the section body's direct
|
||||||
|
child that is or holds a board, so a Story grid with one board per column is indented as a whole and keeps its column gap.
|
||||||
|
Scoped to direct children of a section body; unmarked blocks (full-width Pattern previews, charts, canvases) are untouched. */
|
||||||
|
.sb-page .sb-page-section-body > :is([data-sb-board], :has([data-sb-board])) { padding-left: var(--sb-page-indent); }
|
||||||
|
@media (max-width: 640px) { .sb-page { --sb-page-indent: 12px; } }
|
||||||
/* Sections side by side (StorySectionGrid): grid items keep their margins, so the grid owns the row gap instead.
|
/* Sections side by side (StorySectionGrid): grid items keep their margins, so the grid owns the row gap instead.
|
||||||
|
Only the row gap follows the section gap; the column gap stays 24px so side-by-side preview widths do not change.
|
||||||
Columns and alignment stay with the Story (className): this unlayered rule would override Tailwind's layered grid-cols-*. */
|
Columns and alignment stay with the Story (className): this unlayered rule would override Tailwind's layered grid-cols-*. */
|
||||||
.sb-page .sb-page-section-grid { display: grid; gap: var(--sb-page-section-gap) 24px; margin-top: var(--sb-page-section-gap); }
|
.sb-page .sb-page-section-grid { display: grid; gap: var(--sb-page-section-gap) 24px; margin-top: var(--sb-page-section-gap); }
|
||||||
.sb-page .sb-page-section-grid > .sb-page-section { margin-top: 0; }
|
.sb-page .sb-page-section-grid > .sb-page-section { margin-top: 0; }
|
||||||
@@ -40,7 +40,8 @@ function WithIcon() {
|
|||||||
function Sizes() {
|
function Sizes() {
|
||||||
return (
|
return (
|
||||||
// 3 equal columns on PC (iframe width 1000px and up): sm / default / lg; fewer columns below that (240px minimum).
|
// 3 equal columns on PC (iframe width 1000px and up): sm / default / lg; fewer columns below that (240px minimum).
|
||||||
<div className="grid items-start gap-6 [grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))] min-[1000px]:grid-cols-3">
|
// Same common indent as the group boards of the page (.sb-page-indent).
|
||||||
|
<div className="grid items-start gap-6 sb-page-indent [grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))] min-[1000px]:grid-cols-3">
|
||||||
{(["sm", "default", "lg"] as const).map((size) => (
|
{(["sm", "default", "lg"] as const).map((size) => (
|
||||||
<div key={size} data-toggle-size={size} className="flex flex-wrap items-center gap-3">
|
<div key={size} data-toggle-size={size} className="flex flex-wrap items-center gap-3">
|
||||||
<Toggle size={size} variant="outline" aria-label={`${size} icon-only`}><StarIcon /></Toggle>
|
<Toggle size={size} variant="outline" aria-label={`${size} icon-only`}><StarIcon /></Toggle>
|
||||||
|
|||||||
Vendored
+24
-9
@@ -49,29 +49,44 @@
|
|||||||
.hm-foundation .hm-company-grid > #company-jangheon-industry { grid-column-start: 1; }
|
.hm-foundation .hm-company-grid > #company-jangheon-industry { grid-column-start: 1; }
|
||||||
.hm-foundation .hm-brand-color-row[data-company-id] { display: grid; gap: 8px; overflow: visible; padding-bottom: 0; grid-template-columns: repeat(auto-fill, minmax(max(100px, (100% - 16px) / 3), 1fr)); }
|
.hm-foundation .hm-brand-color-row[data-company-id] { display: grid; gap: 8px; overflow: visible; padding-bottom: 0; grid-template-columns: repeat(auto-fill, minmax(max(100px, (100% - 16px) / 3), 1fr)); }
|
||||||
|
|
||||||
/* Typography: compact specification page. Font Family one line, Font Weight as three plain columns (no card box; the
|
/* Typography: compact specification page. Font Family as family + fallback over the CSS variable, Font Weight as three plain columns (no card box;
|
||||||
section divider already frames them), Specimens as comparison tables (two columns on wide screens, stacked rows on narrow screens). */
|
the section divider already frames them), Specimens as comparison tables (two columns on wide screens, stacked rows on narrow screens).
|
||||||
.hm-foundation .hm-typo-family { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin: 0; }
|
Document text levels (presentation only, existing tokens): item name 14/700 primary, description 14/400 secondary,
|
||||||
|
token / HEX / extra info 12/18/400 secondary (.hm-typo-token). Section titles stay on the common Story page H2 (16/24/700). */
|
||||||
|
/* Section rhythm (title → 12px → divider → 16px → content, sections 28px apart) and the content indent (.sb-page-indent on Font Family,
|
||||||
|
Font Weight and Specimens; Text Colors chips stay on the edge) come from the common Story page (story-page.css). */
|
||||||
|
.hm-foundation .hm-typo-family { display: grid; gap: 4px; margin: 0; }
|
||||||
|
.hm-foundation .hm-typo-family p { margin: 0; }
|
||||||
|
.hm-foundation .hm-typo-family strong { font-weight: var(--hm-font-weight-bold); }
|
||||||
|
.hm-foundation .hm-typo-token { font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); }
|
||||||
.hm-foundation .hm-typo-weights { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 12px 24px; }
|
.hm-foundation .hm-typo-weights { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 12px 24px; }
|
||||||
.hm-foundation .hm-typo-weight { min-width: 0; }
|
.hm-foundation .hm-typo-weight { min-width: 0; }
|
||||||
.hm-foundation .hm-typo-weight p { margin: 0; }
|
.hm-foundation .hm-typo-weight p { margin: 0; }
|
||||||
.hm-foundation .hm-typo-weight-preview { margin: 4px 0 !important; font-size: var(--hm-card-title-font-size); line-height: var(--hm-card-title-line-height); }
|
.hm-foundation .hm-typo-weight-preview { margin: 6px 0 4px !important; font-size: var(--hm-card-title-font-size); line-height: var(--hm-card-title-line-height); }
|
||||||
.hm-foundation .hm-typo-tables { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px 32px; align-items: start; }
|
.hm-foundation .hm-typo-tables { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px 32px; align-items: start; }
|
||||||
.hm-foundation .hm-typo-table { width: 100%; border-collapse: collapse; }
|
.hm-foundation .hm-typo-table { width: 100%; border-collapse: collapse; }
|
||||||
.hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { padding: 8px 12px 8px 0; border-bottom: 1px solid var(--hm-sem-stroke-input-default); text-align: left; vertical-align: baseline; font-weight: var(--hm-input-font-weight); }
|
.hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { padding: 12px 16px 12px 0; border-bottom: 1px solid var(--hm-sem-stroke-input-default); text-align: left; vertical-align: baseline; font-weight: var(--hm-input-font-weight); }
|
||||||
.hm-foundation .hm-typo-table thead th { color: var(--hm-sem-fg-secondary); font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); }
|
.hm-foundation .hm-typo-table thead th { color: var(--hm-sem-fg-secondary); font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); }
|
||||||
.hm-foundation .hm-typo-table tbody th { width: 27%; font-weight: var(--hm-font-weight-bold); }
|
.hm-foundation .hm-typo-table tbody th { width: 27%; font-weight: var(--hm-font-weight-bold); }
|
||||||
.hm-foundation .hm-typo-table td:last-child { width: 26%; padding-right: 0; }
|
.hm-foundation .hm-typo-table td:last-child { width: 26%; padding-right: 0; }
|
||||||
.hm-foundation .hm-typo-metrics span, .hm-foundation .hm-typo-metrics small { display: block; }
|
.hm-foundation .hm-typo-metrics span, .hm-foundation .hm-typo-metrics small { display: block; font-variant-numeric: tabular-nums; }
|
||||||
.hm-foundation .hm-typo-metrics small { font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); }
|
.hm-foundation .hm-typo-metrics small { font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); }
|
||||||
@media (min-width: 1100px) { .hm-foundation .hm-typo-tables { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
@media (min-width: 1100px) { .hm-foundation .hm-typo-tables { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||||
/* Typography Text Colors reuse the Hanmac color chips (.hm-brand-color-chip). Four equal tracks keep "name · 설명" on one line on wide screens;
|
/* Typography Text Colors reuse the Hanmac color chips (.hm-brand-color-chip). Four equal tracks on wide screens;
|
||||||
narrow screens fall back to 150px tracks (2 columns at 390px) and wrap the label inside the chip instead of scrolling. */
|
narrow screens fall back to 150px tracks (2 columns at 390px) and wrap the text inside the chip instead of scrolling. */
|
||||||
.hm-foundation .hm-text-color-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(150px, (100% - 24px) / 4), 1fr)); overflow: visible; padding-bottom: 0; }
|
.hm-foundation .hm-text-color-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(150px, (100% - 24px) / 4), 1fr)); overflow: visible; padding-bottom: 0; }
|
||||||
|
/* Text Colors chip content only (the shared 13px chip text of the color pages is untouched): role name → usage → HEX as three levels.
|
||||||
|
Grid rows stretch, so the four chips keep one height; keep-all wraps the long Readonly usage between words. */
|
||||||
|
.hm-foundation .hm-text-color-row { grid-auto-rows: 1fr; }
|
||||||
|
.hm-foundation .hm-text-color-row .hm-brand-color-chip { padding: 12px; word-break: keep-all; }
|
||||||
|
.hm-foundation .hm-text-color-row .hm-foundation-swatch { margin-bottom: 12px; }
|
||||||
|
.hm-foundation .hm-text-color-row h3 { margin: 0; font-size: var(--hm-label-font-size); line-height: var(--hm-label-line-height); font-weight: var(--hm-font-weight-bold); color: var(--hm-sem-fg-primary); }
|
||||||
|
.hm-foundation .hm-text-color-row p { margin: 4px 0 0; font-size: var(--hm-label-font-size); line-height: var(--hm-label-line-height); color: var(--hm-sem-fg-secondary); }
|
||||||
|
.hm-foundation .hm-text-color-row p[data-color-value] { margin-top: 4px; font-size: var(--hm-button-font-size-sm); line-height: var(--hm-button-line-height-sm); font-variant-numeric: tabular-nums; }
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.hm-foundation .hm-typo-table thead { display: none; }
|
.hm-foundation .hm-typo-table thead { display: none; }
|
||||||
.hm-foundation .hm-typo-table, .hm-foundation .hm-typo-table tbody, .hm-foundation .hm-typo-table tr, .hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { display: block; width: auto !important; }
|
.hm-foundation .hm-typo-table, .hm-foundation .hm-typo-table tbody, .hm-foundation .hm-typo-table tr, .hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { display: block; width: auto !important; }
|
||||||
.hm-foundation .hm-typo-table tr { padding: 8px 0; border-bottom: 1px solid var(--hm-sem-stroke-input-default); }
|
.hm-foundation .hm-typo-table tr { padding: 12px 0; border-bottom: 1px solid var(--hm-sem-stroke-input-default); }
|
||||||
.hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { padding: 2px 0; border-bottom: 0; }
|
.hm-foundation .hm-typo-table th, .hm-foundation .hm-typo-table td { padding: 2px 0; border-bottom: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,12 @@ function toHex(value: string | undefined) {
|
|||||||
return rgb ? `#${rgb.slice(1).map(channel => Number(channel).toString(16).padStart(2, "0")).join("").toUpperCase()}` : value
|
return rgb ? `#${rgb.slice(1).map(channel => Number(channel).toString(16).padStart(2, "0")).join("").toUpperCase()}` : value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same chip markup and classes as Foundation/한맥 컬러 and 가족사 컬러 (foundation.css): swatch, name, HEX.
|
// Same chip classes as Foundation/한맥 컬러 and 가족사 컬러 (foundation.css): swatch, then role name / usage / HEX on separate lines
|
||||||
|
// so the item name, its description and the HEX value read as three levels (styles scoped to .hm-text-color-row).
|
||||||
function TextColorChips({ values }: { values: Record<string, string> }) {
|
function TextColorChips({ values }: { values: Record<string, string> }) {
|
||||||
return <div className="hm-brand-color-row hm-text-color-row">{textColorRoles.map(item => <article className="hm-brand-color-chip" key={item.label} data-text-color={item.label} data-color-token={item.token}>
|
return <div className="hm-brand-color-row hm-text-color-row">{textColorRoles.map(item => <article className="hm-brand-color-chip" key={item.label} data-text-color={item.label} data-color-token={item.token}>
|
||||||
<div className="hm-foundation-swatch" style={{ background: `var(${item.token})` }} />
|
<div className="hm-foundation-swatch" style={{ background: `var(${item.token})` }} />
|
||||||
<h3>{item.label} · {item.name}</h3><p data-color-value>{toHex(values[item.token])}</p>
|
<h3>{item.label}</h3><p data-color-name>{item.name}</p><p data-color-value>{toHex(values[item.token])}</p>
|
||||||
</article>)}</div>
|
</article>)}</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,22 +70,26 @@ function SpecimenTable({ rows }: { rows: readonly TypographyReference[] }) {
|
|||||||
function TypographyReferencePage() {
|
function TypographyReferencePage() {
|
||||||
const values = useResolvedProperties(typographyProperties)
|
const values = useResolvedProperties(typographyProperties)
|
||||||
const colorValues = useResolvedProperties(textColorProperties)
|
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 <ReferencePage title="폰트">
|
return <ReferencePage title="폰트">
|
||||||
<ReferenceSection title="Text Colors" note="">
|
<ReferenceSection title="Text Colors" note="">
|
||||||
<TextColorChips values={colorValues} />
|
<TextColorChips values={colorValues} />
|
||||||
</ReferenceSection>
|
</ReferenceSection>
|
||||||
<ReferenceSection title="Font Family">
|
<ReferenceSection title="Font Family">
|
||||||
<p className="hm-typo-family"><span>Noto Sans KR → 맑은 고딕 → 시스템 sans-serif</span><code className="hm-foundation-note">--hm-font-family-base: {values["--hm-font-family-base"]}</code></p>
|
<div className="hm-typo-family sb-page-indent">
|
||||||
|
<p><strong>Noto Sans KR</strong> <span className="hm-foundation-note">→ 맑은 고딕 → 시스템 sans-serif</span></p>
|
||||||
|
<code className="hm-foundation-note hm-typo-token">--hm-font-family-base: {values["--hm-font-family-base"]}</code>
|
||||||
|
</div>
|
||||||
</ReferenceSection>
|
</ReferenceSection>
|
||||||
<ReferenceSection title="Font Weight">
|
<ReferenceSection title="Font Weight">
|
||||||
<div className="hm-typo-weights">{weights.map(({ property, label }) => <article className="hm-typo-weight" key={property}>
|
<div className="hm-typo-weights sb-page-indent">{weights.map(({ property, label }) => <article className="hm-typo-weight" key={property}>
|
||||||
<p className="hm-typo-weight-meta"><strong>{label}</strong> <span className="hm-foundation-note">{values[property]}</span></p>
|
<p className="hm-typo-weight-meta"><strong>{label}</strong> <span className="hm-foundation-note">{values[property]}</span></p>
|
||||||
<p className="hm-typo-weight-preview" style={{ fontWeight: `var(${property})` }}>한맥 Hanmac 0123</p>
|
<p className="hm-typo-weight-preview" style={{ fontWeight: `var(${property})` }}>한맥 Hanmac 0123</p>
|
||||||
<code className="hm-foundation-note">{property}</code>
|
<code className="hm-foundation-note hm-typo-token">{property}</code>
|
||||||
</article>)}</div>
|
</article>)}</div>
|
||||||
</ReferenceSection>
|
</ReferenceSection>
|
||||||
<ReferenceSection title="Typography Specimens">
|
<ReferenceSection title="Typography Specimens">
|
||||||
<div className="hm-typo-tables"><SpecimenTable rows={textRows} /><SpecimenTable rows={controlRows} /></div>
|
<div className="hm-typo-tables sb-page-indent"><SpecimenTable rows={textRows} /><SpecimenTable rows={controlRows} /></div>
|
||||||
</ReferenceSection>
|
</ReferenceSection>
|
||||||
</ReferencePage>
|
</ReferencePage>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,6 +440,7 @@ export const All: Story = {
|
|||||||
<StoryPageHeader title="GNB" />
|
<StoryPageHeader title="GNB" />
|
||||||
<StorySection title="Variants">
|
<StorySection title="Variants">
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
indent={false}
|
||||||
states={[
|
states={[
|
||||||
{
|
{
|
||||||
id: "default",
|
id: "default",
|
||||||
@@ -467,6 +468,7 @@ export const All: Story = {
|
|||||||
{/* The open 2-depth panel ends 238px below the bar's top; the wrapper reserves that room so it never overlaps the page below. */}
|
{/* The open 2-depth panel ends 238px below the bar's top; the wrapper reserves that room so it never overlaps the page below. */}
|
||||||
<StorySection title="States">
|
<StorySection title="States">
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
indent={false}
|
||||||
states={[
|
states={[
|
||||||
{
|
{
|
||||||
id: "navigation-menu-open",
|
id: "navigation-menu-open",
|
||||||
|
|||||||
@@ -634,6 +634,7 @@ export const All: Story = {
|
|||||||
<StoryPageHeader title="LNB" />
|
<StoryPageHeader title="LNB" />
|
||||||
<StorySection title="States">
|
<StorySection title="States">
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
indent={false}
|
||||||
min={560}
|
min={560}
|
||||||
states={[
|
states={[
|
||||||
{ id: "selected", label: "Selected", children: <ResponsiveSpecimen nodes={simpleNav()} initial="overview" initialOpen={{ tasks: true }} dividers={false} /> },
|
{ id: "selected", label: "Selected", children: <ResponsiveSpecimen nodes={simpleNav()} initial="overview" initialOpen={{ tasks: true }} dividers={false} /> },
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const All: Story = {
|
|||||||
<StorySection title="Variants">
|
<StorySection title="Variants">
|
||||||
{/* Default spans the full width; the other two share an equal 2-column row (1 column below 2 × 560px). */}
|
{/* Default spans the full width; the other two share an equal 2-column row (1 column below 2 × 560px). */}
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
indent={false}
|
||||||
min={560}
|
min={560}
|
||||||
states={[
|
states={[
|
||||||
{ id: "default", label: "Default", wide: true, children: <LoadingScreen /> },
|
{ id: "default", label: "Default", wide: true, children: <LoadingScreen /> },
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ export const All: Story = {
|
|||||||
<StoryPageHeader title="Page Header" />
|
<StoryPageHeader title="Page Header" />
|
||||||
<StorySection title="Variants">
|
<StorySection title="Variants">
|
||||||
<StateBoard
|
<StateBoard
|
||||||
|
indent={false}
|
||||||
states={[
|
states={[
|
||||||
{ id: "basic", label: "Basic", wide: true, children: <PageHeader><PageHeaderContent><PageHeaderTitle>업무 현황</PageHeaderTitle></PageHeaderContent></PageHeader> },
|
{ id: "basic", label: "Basic", wide: true, children: <PageHeader><PageHeaderContent><PageHeaderTitle>업무 현황</PageHeaderTitle></PageHeaderContent></PageHeader> },
|
||||||
{ id: "with-breadcrumb", label: "With Breadcrumb", wide: true, children: <BreadcrumbHeader /> },
|
{ id: "with-breadcrumb", label: "With Breadcrumb", wide: true, children: <BreadcrumbHeader /> },
|
||||||
|
|||||||
Reference in new issue
Block a user