style(storybook): tidy CENTER, chart, org chart and SW story pages
- CENTER plain page layout and shorter reference demo notes (spec values moved to the CENTER README); chart specimen descriptions trimmed - Org chart page names and previews; SW width rows follow the 30px frame margin (1980 / 1065 / 727px) and the SW tests match the current layout - Story inventory regenerated and WORKING_CONTEXT updated
This commit is contained in:
1 parent
bad2acfc49
commit
ed7e8790ec
40 files changed
+1525
-333
No files matched your search
@@ -1,16 +1,16 @@
|
||||
import type { ComponentType } from "react"
|
||||
import type { ComponentType, ReactNode } from "react"
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite"
|
||||
import { TunnelFacility } from "@hm-design/center-graphic"
|
||||
import {
|
||||
BridgeReferenceDemo,
|
||||
IntersectionReferenceDemo,
|
||||
InterchangeReferenceDemo,
|
||||
JunctionReferenceDemo,
|
||||
LinkedFacilityReferenceDemo,
|
||||
RoadsideReferenceDemo,
|
||||
TunnelReferenceDemo,
|
||||
} from "@hm-design/center-graphic/reference"
|
||||
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
||||
CompactFacilityConnection,
|
||||
FACILITY_CONFIGS,
|
||||
LocalAssetFacility,
|
||||
RoadsideFacilityTag,
|
||||
TunnelFacility,
|
||||
type FacilityConfig,
|
||||
type RoadsideEntity,
|
||||
} from "@hm-design/center-graphic"
|
||||
import { LinkedFacilityReferenceDemo } from "@hm-design/center-graphic/reference"
|
||||
import { StoryPage, StoryPageHeader } from "@/components/story-page"
|
||||
import { withRepresentation } from "./center-shared"
|
||||
|
||||
// Owners: ui-viz docs/visualization/facility.md and facility-assets.md (128 approved SVG references, shipped unchanged).
|
||||
@@ -25,35 +25,225 @@ export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
// Common Story page. The CENTER representation wraps only the specimen, so the page title is never scaled with the graphic.
|
||||
// 2026-11-13: no visible "개요" section title (사업명 page rule); the specimens keep their indent via the common `sb-page-indent`.
|
||||
const page = (name: string, Demo: ComponentType): Story => ({
|
||||
name,
|
||||
parameters: { layout: "fullscreen", controls: { disable: true } },
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader title={name} />
|
||||
<StorySection title="개요">
|
||||
<div className="sb-page-indent">
|
||||
{withRepresentation(() => <Demo />)}
|
||||
</StorySection>
|
||||
</div>
|
||||
</StoryPage>
|
||||
),
|
||||
})
|
||||
|
||||
// 터널 page layout (2026-11-13): composed here from the public API (same props as the package TunnelReferenceDemo) so the
|
||||
// specimens can be grouped — one width-behaviour section with a Position Map column (SEPARATED → SHORT → MEDIUM → LONG) and an
|
||||
// Actual / Detail column (SEPARATED → ACTUAL SHORT → REF → LONG), same steps on the same row (1 column below a 1180px content
|
||||
// width), and the compact applied example full width below. The former standalone Position Map / Actual examples are the
|
||||
// MEDIUM / ACTUAL REF rows (same default name and length). Package classes are reused so the common title row, 12px title gap and the
|
||||
// 8px local scrollbar still apply; the layout lives in center-stories.css (`.sb-center-tunnel*`).
|
||||
const TUNNEL_WIDTH_NAMES: [string, string, string][] = [
|
||||
["SHORT", "터널", "L=80m"],
|
||||
["MEDIUM", "대산2터널", "L=750m"],
|
||||
["LONG", "서해안고속도로 대산연결 제2터널", "L=12,480m"],
|
||||
]
|
||||
const TUNNEL_ACTUAL_LABELS = ["ACTUAL SHORT", "ACTUAL REF", "ACTUAL LONG"]
|
||||
|
||||
function TunnelSample({ title, note, children }: { title: string; note?: string; children: ReactNode }) {
|
||||
return (
|
||||
<article className="tunnel-reference__sample">
|
||||
<header>
|
||||
<strong>{title}</strong>
|
||||
{note ? <span>{note}</span> : null}
|
||||
</header>
|
||||
<div className="tunnel-reference__stage">{children}</div>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
function TunnelSpecimens() {
|
||||
return (
|
||||
<div className="sb-center-tunnel">
|
||||
<div className="tunnel-reference">
|
||||
{/* 2026-11-13: no "너비 동작" title row; each column carries the common specimen title (English + Korean note). */}
|
||||
<article className="tunnel-reference__sample">
|
||||
<div className="tunnel-reference__stage sb-center-tunnel__width-stage">
|
||||
<div className="sb-center-tunnel__width">
|
||||
{(["positionMap", "actualDetail"] as const).map((variant) => (
|
||||
<div className="tunnel-reference__width-tests sb-center-tunnel__width-group" key={variant}>
|
||||
<header>
|
||||
<strong>{variant === "positionMap" ? "Position Map" : "Actual / Detail"}</strong>
|
||||
<span>{variant === "positionMap" ? "위치도" : "실사화"}</span>
|
||||
</header>
|
||||
<div>
|
||||
<span>SEPARATED</span>
|
||||
<TunnelFacility variant={variant} separated />
|
||||
</div>
|
||||
{TUNNEL_WIDTH_NAMES.map(([size, name, length], index) => (
|
||||
<div key={size}>
|
||||
<span>{variant === "positionMap" ? size : TUNNEL_ACTUAL_LABELS[index]}</span>
|
||||
<TunnelFacility name={name} secondaryText={length} variant={variant} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<TunnelSample title="간략 적용 예제" note="노선 + 연결 + 터널 + 레이블">
|
||||
<CompactFacilityConnection className="tunnel-applied-example" routeMode="inline" segmentShape="tunnel" sourceStatus="SOURCE_RECEIVED" label="노선과 터널 시설물의 간략 적용 예제">
|
||||
<TunnelFacility name="대산2터널" secondaryText="L=750m" variant="positionMap" />
|
||||
</CompactFacilityConnection>
|
||||
</TunnelSample>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 교량 · 교차로 · 분기점 · 나들목 page layout (2026-11-13): the 터널 layout applied to the package FacilityReferenceDemo
|
||||
// specimens, composed from the public API with the same props. Position Map | Actual / Detail columns (SEPARATED first, then
|
||||
// SHORT / MEDIUM / LONG and ACTUAL SHORT / REF / LONG on the same rows), the compact applied example full width below. The former
|
||||
// standalone Position Map / Actual examples are the MEDIUM / ACTUAL REF rows (default name and secondary text) and the former
|
||||
// Separated example is each column's first row. `data-sb-compare-at` raises the 2-column breakpoint when the widest row needs it
|
||||
// (교량 LONG 511px artwork: 1210px); without it the 터널 1180px rule applies.
|
||||
function facilityWidthNames(config: FacilityConfig) {
|
||||
return [
|
||||
config.id === "bridge" ? "1교" : "신시",
|
||||
config.defaultName,
|
||||
config.id === "bridge" ? "서해안고속도로 대산연결 제2교량" : `서해안고속도로 ${config.defaultName}`,
|
||||
]
|
||||
}
|
||||
|
||||
function FacilitySpecimens({ config, compareAt }: { config: FacilityConfig; compareAt?: "1210" }) {
|
||||
const widthNames = facilityWidthNames(config)
|
||||
return (
|
||||
<div className="sb-center-tunnel" data-sb-compare-at={compareAt}>
|
||||
<div className="facility-reference" data-reference-facility={config.id}>
|
||||
<article className="facility-reference__sample">
|
||||
<div className="facility-reference__stage sb-center-tunnel__width-stage">
|
||||
<div className="sb-center-tunnel__width">
|
||||
{(["positionMap", "actualDetail"] as const).map((variant) => (
|
||||
<div className="facility-reference__width-tests sb-center-tunnel__width-group" key={variant}>
|
||||
<header>
|
||||
<strong>{variant === "positionMap" ? "Position Map" : "Actual / Detail"}</strong>
|
||||
<span>{variant === "positionMap" ? "위치도" : "실사화"}</span>
|
||||
</header>
|
||||
<div>
|
||||
<span>SEPARATED</span>
|
||||
<LocalAssetFacility config={config} variant={variant} separated />
|
||||
</div>
|
||||
{widthNames.map((name, index) => (
|
||||
<div key={name}>
|
||||
<span>{variant === "positionMap" ? ["SHORT", "MEDIUM", "LONG"][index] : `ACTUAL ${["SHORT", "REF", "LONG"][index]}`}</span>
|
||||
<LocalAssetFacility config={config} name={name} variant={variant} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<TunnelSample
|
||||
title="간략 적용 예제"
|
||||
note={config.id === "interchange" ? "SOURCE_PENDING · 기존 Preview 전용; 정확한 IC 구성 추론 안 함" : "SOURCE_RECEIVED · 관계 비교, 정확한 픽셀 정합 아님"}
|
||||
>
|
||||
<CompactFacilityConnection
|
||||
className={`facility-applied facility-applied--${config.routeMode}`}
|
||||
routeMode={config.routeMode}
|
||||
segmentShape={config.id === "bridge" ? "bridge" : undefined}
|
||||
sourceStatus={config.id === "interchange" ? "SOURCE_PENDING" : "SOURCE_RECEIVED"}
|
||||
label={`${config.label} 간략 적용 예제`}
|
||||
>
|
||||
<LocalAssetFacility config={config} />
|
||||
</CompactFacilityConnection>
|
||||
</TunnelSample>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 연계 노선 page layout (2026-11-13): the package RoadsideReferenceDemo specimens in the same 2-column structure and the same
|
||||
// single-line row labels as the other facility pages (SHORT / MEDIUM / LONG, ACTUAL SHORT / REF / LONG; the former two-line
|
||||
// "휴게소 · SHORT" meta is replaced — the entity stays in the tag text and its accessible name). Widest row 64px + 16px + 450px
|
||||
// LONG tag, so the 터널 1180px rule applies. Separated exists for Actual / Detail only, so it is that column's first row; at
|
||||
// 2 columns the Position Map column keeps an empty first row so the steps stay on the same rows, at 1 column the empty row is
|
||||
// not rendered. The 연계 / 노선 맥락 example is full width below.
|
||||
const ROADSIDE_TESTS: { size: string; actual: string; entity: RoadsideEntity; label: string }[] = [
|
||||
{ size: "SHORT", actual: "ACTUAL SHORT", entity: "rest-area", label: "휴게소" },
|
||||
{ size: "MEDIUM", actual: "ACTUAL REF", entity: "drowsy-shelter", label: "졸음쉼터" },
|
||||
{ size: "LONG", actual: "ACTUAL LONG", entity: "drowsy-shelter", label: "서해안고속도로 대산방향 졸음쉼터" },
|
||||
]
|
||||
|
||||
function RoadsideSpecimens() {
|
||||
return (
|
||||
<div className="sb-center-tunnel sb-center-roadside">
|
||||
<div className="facility-reference roadside-reference" data-reference-facility="roadside">
|
||||
<article className="facility-reference__sample">
|
||||
<div className="facility-reference__stage sb-center-tunnel__width-stage">
|
||||
<div className="sb-center-tunnel__width">
|
||||
<div className="facility-reference__width-tests sb-center-tunnel__width-group sb-center-roadside__position">
|
||||
<header><strong>Position Map</strong><span>위치도</span></header>
|
||||
<div className="sb-center-roadside__blank" aria-hidden="true" />
|
||||
{ROADSIDE_TESTS.map((test) => (
|
||||
<div key={test.size} data-roadside-test={test.size.toLowerCase()}>
|
||||
<span>{test.size}</span>
|
||||
{/* The tag is itself a span: the wrapper keeps the row-label rule (`> div > span`) off the tag text. */}
|
||||
<div><RoadsideFacilityTag entity={test.entity} label={test.label} /></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="facility-reference__width-tests sb-center-tunnel__width-group">
|
||||
<header><strong>Actual / Detail</strong><span>실사화</span></header>
|
||||
<div data-roadside-actual-test="separated">
|
||||
<span>SEPARATED</span>
|
||||
<RoadsideFacilityTag entity="drowsy-shelter" variant="actualDetail" separated />
|
||||
</div>
|
||||
{ROADSIDE_TESTS.map((test) => (
|
||||
<div key={test.size} data-roadside-actual-test={test.size.toLowerCase()}>
|
||||
<span>{test.actual}</span>
|
||||
<RoadsideFacilityTag entity={test.entity} label={test.label} variant="actualDetail" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<TunnelSample title="연계 / 노선 맥락" note="노선 + 앵커 + 연결선 + 시설물 태그">
|
||||
<CompactFacilityConnection className="facility-applied facility-applied--anchored roadside-applied" routeMode="anchored" sourceStatus="SOURCE_PENDING" label="졸음쉼터 연계 노선 간략 적용 예제">
|
||||
<RoadsideFacilityTag entity="drowsy-shelter" />
|
||||
</CompactFacilityConnection>
|
||||
</TunnelSample>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// `name` is repeated as a literal because Storybook's static indexer cannot read it through page(); it drives the sidebar label.
|
||||
export const Tunnel: Story = { ...page("터널", TunnelReferenceDemo), name: "터널" }
|
||||
export const Bridge: Story = { ...page("교량", BridgeReferenceDemo), name: "교량" }
|
||||
export const Intersection: Story = { ...page("교차로", IntersectionReferenceDemo), name: "교차로" }
|
||||
export const Junction: Story = { ...page("분기점", JunctionReferenceDemo), name: "분기점" }
|
||||
export const Interchange: Story = { ...page("나들목", InterchangeReferenceDemo), name: "나들목" }
|
||||
export const Roadside: Story = { ...page("휴게소 · 졸음쉼터", RoadsideReferenceDemo), name: "휴게소 · 졸음쉼터" }
|
||||
export const Tunnel: Story = { ...page("터널", TunnelSpecimens), name: "터널" }
|
||||
export const Bridge: Story = { ...page("교량", () => <FacilitySpecimens config={FACILITY_CONFIGS.bridge} compareAt="1210" />), name: "교량" }
|
||||
export const Intersection: Story = { ...page("교차로", () => <FacilitySpecimens config={FACILITY_CONFIGS.intersection} />), name: "교차로" }
|
||||
export const Junction: Story = { ...page("분기점", () => <FacilitySpecimens config={FACILITY_CONFIGS.junction} />), name: "분기점" }
|
||||
export const Interchange: Story = { ...page("나들목", () => <FacilitySpecimens config={FACILITY_CONFIGS.interchange} />), name: "나들목" }
|
||||
export const Roadside: Story = { ...page("휴게소 · 졸음쉼터", RoadsideSpecimens), name: "연계 노선" }
|
||||
// Linked facilities are a standalone section heading followed by item cards.
|
||||
// Keep the reference data/artwork and road-class grouping owned by the package.
|
||||
// 2026-11-13: same `sb-page-indent` start as the other facility pages; the page class scopes the Linked-only CSS
|
||||
// (hidden context notice / READY count / duplicate card name, card title and POSITION · ACTUAL label style).
|
||||
export const Linked: Story = {
|
||||
...page("연계 시설물", LinkedFacilityReferenceDemo),
|
||||
name: "연계 시설물",
|
||||
render: () => (
|
||||
<StoryPage className="sb-center-linked-page">
|
||||
<StoryPageHeader title="연계 시설물" />
|
||||
{withRepresentation(() => <LinkedFacilityReferenceDemo />)}
|
||||
<div className="sb-page-indent">
|
||||
{withRepresentation(() => <LinkedFacilityReferenceDemo />)}
|
||||
</div>
|
||||
</StoryPage>
|
||||
),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user