docs(storybook): tidy SW Storybook gauges, responsive rows and page titles
Deploy Storybook / deploy (push) Successful in 1m11s
Deploy Storybook / deploy (push) Successful in 1m11s
- SWPopup Custom Content and the SW Viewer options panel use SWSlider style B (appearance="property") only; the A/B comparison, the style select and the green panel gauge are gone (SWViewerSlider itself is unchanged). - SW Header / Viewer / Footer Responsive More: the 1920px row shows only when the content Inner is 1920px or wider (container query); Footer rows fit the page width without scrollers so ▲ More handles narrow widths. - Logo pages fit without scrollers; SW Header Logo Slot is "Logo" in the sidebar with the title "SW Header — 로고" (ID sw-header--logo-slot kept). - Property Panel (was "Property Panel · 4개 비교"): no Inner scroller, the page scrolls, 2 × 2 grid with one column below 720px. - SW Footer drops the "실제 Footer 조합 (동작)" heading; SW Viewer Header page is titled "SW Viewer Header" with 기본형 and 최소화 · 닫기 버튼 only. - Browser tests, inventory and README follow these changes; visual baselines are not updated.
This commit is contained in:
1 parent
ccafc6e332
commit
258e0a4b68
14 files changed
+123
-109
No files matched your search
+20
-33
@@ -2,7 +2,7 @@ import { useId, useState } from "react"
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite"
|
||||
import {
|
||||
SWHeaderInput, SWHeaderPropertyPanel, SWPopup, SWPopupPropertyRow, SWPopupRow, SWPopupSection, SWSelect, SWSlider, SWTheme,
|
||||
type SWHeaderColorOption, type SWHeaderLayer, type SWHeaderProperty, type SWSliderAppearance,
|
||||
type SWHeaderColorOption, type SWHeaderLayer, type SWHeaderProperty,
|
||||
} from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
import { Button, Switch } from "@hm-design/ui"
|
||||
@@ -26,7 +26,6 @@ const COLORS: SWHeaderColorOption[] = [
|
||||
const UNITS = ["mm", "cm", "m"].map(value => ({ value }))
|
||||
const MENUS = { layers: LAYERS, colors: COLORS }
|
||||
const layerProperty = (value: string): SWHeaderProperty => ({ id: "layer", name: "레이어", value, type: "select", groupId: "popup", picker: "layer", options: LAYERS.map(({ id, name }) => ({ id, name })) })
|
||||
const APPEARANCES = [{ value: "panel", label: "A · panel (기본)" }, { value: "property", label: "B · property" }]
|
||||
|
||||
const meta = {
|
||||
title: "SW/Popup",
|
||||
@@ -71,13 +70,14 @@ function SettingsPopup({ record }: { record: (line: string) => void }) {
|
||||
<SWPopupPropertyRow property={{ id: "color", name: "색상", value: color, type: "color", groupId: "popup" }} menus={MENUS}
|
||||
onPropertyChange={(_, value) => { setColor(value); record(`color=${value}`) }} />
|
||||
</SWPopupSection>
|
||||
{/* 2026-10-20: the gauge is the SW gauge (SWSlider). SW has no normal-mode switch, so 스냅 stays the HM UI Switch. */}
|
||||
{/* 2026-10-20: the gauge is the SW gauge (SWSlider; 2026-10-22: style B, appearance="property", on this page).
|
||||
SW has no normal-mode switch, so 스냅 stays the HM UI Switch. */}
|
||||
<SWPopupSection title="스냅 · 투명도">
|
||||
<SWPopupRow label="스냅" htmlFor={ids.snap} field="none">
|
||||
<Switch id={ids.snap} checked={snap} onCheckedChange={next => { setSnap(next); record(`snap=${next}`) }} data-ui-switch="" />
|
||||
</SWPopupRow>
|
||||
<SWPopupRow label="투명도" field="none">
|
||||
<SWSlider value={opacity} min={0} max={100} step={10} onValueChange={setOpacity} onValueCommit={next => record(`opacity=${next}`)} aria-label="투명도" data-popup-slider="" />
|
||||
<SWSlider appearance="property" value={opacity} min={0} max={100} step={10} onValueChange={setOpacity} onValueCommit={next => record(`opacity=${next}`)} aria-label="투명도" data-popup-slider="" />
|
||||
</SWPopupRow>
|
||||
</SWPopupSection>
|
||||
<div className="sw-story-popup-actions">
|
||||
@@ -122,35 +122,22 @@ function PanelWithChildren({ record }: { record: (line: string) => void }) {
|
||||
)
|
||||
}
|
||||
|
||||
/** SWSlider: the same value and events in both looks; the host only picks `appearance`. */
|
||||
function OpacityStylePopups({ record }: { record: (line: string) => void }) {
|
||||
/** SWSlider style B (appearance="property", 2026-10-22: the only gauge look on this page): value, entry and disabled. */
|
||||
function OpacityPopup({ record }: { record: (line: string) => void }) {
|
||||
const [opacity, setOpacity] = useState(40)
|
||||
const [appearance, setAppearance] = useState<SWSliderAppearance>("panel")
|
||||
const slider = (look: SWSliderAppearance, label: string) => (
|
||||
<SWSlider appearance={look} value={opacity} min={0} max={100} step={10} aria-label={label} data-sw-slider={look}
|
||||
onValueChange={setOpacity} onValueCommit={next => record(`opacity(${look})=${next}`)} />
|
||||
)
|
||||
return (
|
||||
<>
|
||||
<SWPopup title="투명도 · 스타일 비교" data-popup="opacity-compare">
|
||||
<SWPopupSection title="A = panel · B = property (같은 값)">
|
||||
<SWPopupRow label="스타일 A" field="none" unit="%">{slider("panel", "투명도 A")}</SWPopupRow>
|
||||
<SWPopupRow label="스타일 B" field="none" unit="%">{slider("property", "투명도 B")}</SWPopupRow>
|
||||
<SWPopupRow label="값" field="compact" unit="%">
|
||||
<SWHeaderInput valueType="number" value={String(opacity)} aria-label="투명도 값" onCommit={next => { setOpacity(Math.min(100, Math.max(0, Number(next)))); record(`opacity=${next}`) }} />
|
||||
</SWPopupRow>
|
||||
</SWPopupSection>
|
||||
</SWPopup>
|
||||
<SWPopup title="투명도 · 선택 결과" data-popup="opacity-select">
|
||||
<SWPopupSection title="appearance">
|
||||
<SWPopupRow label="스타일" field="none">
|
||||
<SWSelect aria-label="게이지바 스타일" value={appearance} options={APPEARANCES} onValueChange={next => { setAppearance(next as SWSliderAppearance); record(`appearance=${next}`) }} />
|
||||
</SWPopupRow>
|
||||
<SWPopupRow label="투명도" field="none" unit="%">{slider(appearance, "투명도 (선택한 스타일)")}</SWPopupRow>
|
||||
<SWPopupRow label="비활성" field="none" unit="%" disabled><SWSlider appearance={appearance} value={opacity} disabled aria-label="투명도 (비활성)" /></SWPopupRow>
|
||||
</SWPopupSection>
|
||||
</SWPopup>
|
||||
</>
|
||||
<SWPopup title="투명도" data-popup="opacity">
|
||||
<SWPopupSection title="투명도">
|
||||
<SWPopupRow label="투명도" field="none" unit="%">
|
||||
<SWSlider appearance="property" value={opacity} min={0} max={100} step={10} aria-label="투명도 B" data-sw-slider="property"
|
||||
onValueChange={setOpacity} onValueCommit={next => record(`opacity(property)=${next}`)} />
|
||||
</SWPopupRow>
|
||||
<SWPopupRow label="값" field="compact" unit="%">
|
||||
<SWHeaderInput valueType="number" value={String(opacity)} aria-label="투명도 값" onCommit={next => { setOpacity(Math.min(100, Math.max(0, Number(next)))); record(`opacity=${next}`) }} />
|
||||
</SWPopupRow>
|
||||
<SWPopupRow label="비활성" field="none" unit="%" disabled><SWSlider appearance="property" value={opacity} disabled aria-label="투명도 (비활성)" /></SWPopupRow>
|
||||
</SWPopupSection>
|
||||
</SWPopup>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -168,9 +155,9 @@ function PopupPage() {
|
||||
<PanelWithChildren record={record} />
|
||||
</SWTheme>
|
||||
</StorySection>
|
||||
<StorySection title="투명도 게이지바 스타일 (SWSlider appearance)" description={<><code>appearance="panel"</code>(기본, A) = 지금까지 Popup에서 쓰던 게이지바(6px 트랙 · 18px 흰 Thumb · 녹색 Range, SWViewerSlider와 같은 모양). <code>appearance="property"</code>(B) = 속성창 4개 상태 비교의 게이지바(베이지 트랙 · 빨강 채움 · Figma Thumb). 값·<code>onValueChange</code>·<code>onValueCommit</code>·키보드는 같고 모양만 바뀝니다. 색은 SW 토큰(<code>--hm-sw-slider-panel-*</code>, <code>--hm-sw-property-range-*</code>)을 따릅니다.</>}>
|
||||
<StorySection title="투명도 게이지바 (SWSlider)">
|
||||
<SWTheme className="sw-story-popups" data-slider-popups="">
|
||||
<OpacityStylePopups record={record} />
|
||||
<OpacityPopup record={record} />
|
||||
</SWTheme>
|
||||
</StorySection>
|
||||
</StoryPage>
|
||||
|
||||
Reference in new issue
Block a user