feat(storybook): add shared SW notice and refine SW previews

- Add StoryNotice and a withSWNotice decorator so every visible SW Story
  shows the common notice above its title; non-SW Stories are unaffected.
- Align the SW Header overview with the common SW Story page layout, let the
  preview Stage fill the available width and keep inner scroll on narrow screens.
- Rename SW/Footer to SW/하단 명령어바 (sidebar title only, Story IDs fixed via
  id: "sw-footer"), drop the top SWHeader from its preview and lower the
  workspace height bounds by the removed 49px.
This commit is contained in:
shkim4 committed 2026-11-09 19:23:17 +09:00
1 parent a460426535
commit 9394050c72
16 files changed
+113 -22

No files matched your search

+26
View File
@@ -61,3 +61,29 @@
font-weight: var(--hm-input-font-weight);
}
.sb-page .sb-page-section-body { min-width: 0; }
/* Notice above a page title (StoryNotice). Reuses .sb-page / .sb-page-inner (width and side margin are not redefined).
The frame drops its bottom gutter and pulls the next page up so the notice sits 24px above the title block's own top gutter. */
.sb-page.sb-page-notice {
padding-bottom: 0;
margin-bottom: calc(24px - var(--sb-page-gutter));
}
.sb-page .sb-notice {
display: flex;
align-items: flex-start;
gap: 8px;
margin: 0;
font-size: var(--hm-label-font-size);
line-height: var(--hm-label-line-height);
font-weight: var(--hm-input-font-weight);
color: var(--hm-sem-fg-primary);
overflow-wrap: anywhere;
}
.sb-page .sb-notice-icon {
flex: none;
width: 20px;
height: 20px;
/* centers the icon on the first text line even when the line height differs from 20px */
margin-block: calc((var(--hm-label-line-height) - 20px) / 2);
}
.sb-page .sb-notice-text { min-width: 0; }
+20
View File
@@ -25,6 +25,26 @@ export function StoryPageHeader({ kicker, title, description }: { kicker?: strin
)
}
// Notice row (icon + text) shown above a Story page title. Reusable by any Story group through a decorator
// (e.g. src/sw/sw-story-notice.tsx); nothing renders it unless a group opts in. It owns a page frame whose Inner is the
// same as StoryPage's, and cancels its own bottom gutter so the page title below stays where it was.
// Icon: Group 1171290812.svg (circle + "!"), colors via currentColor.
export function StoryNotice({ children }: { children: ReactNode }) {
return (
<div className="sb-page sb-page-notice" data-story-notice="">
<div className="sb-page-inner">
<p className="sb-notice">
<svg className="sb-notice-icon" width="20" height="20" viewBox="0 0 29 29" fill="none" aria-hidden="true" focusable="false">
<path d="M15.7415 6L15.5383 17.3984H13.3743L13.1711 6H15.7415ZM14.4602 22.1484C14.0279 22.1484 13.6581 21.9974 13.3508 21.6953C13.0435 21.388 12.8925 21.0182 12.8977 20.5859C12.8925 20.1589 13.0435 19.7943 13.3508 19.4922C13.6581 19.1849 14.0279 19.0312 14.4602 19.0312C14.8821 19.0312 15.2467 19.1849 15.554 19.4922C15.8612 19.7943 16.0175 20.1589 16.0227 20.5859C16.0175 20.8724 15.942 21.1354 15.7961 21.375C15.6555 21.6094 15.468 21.7969 15.2336 21.9375C14.9993 22.0781 14.7415 22.1484 14.4602 22.1484Z" fill="currentColor" />
<circle cx="14.5" cy="14.5" r="13.5" stroke="currentColor" strokeWidth="2" />
</svg>
<span className="sb-notice-text">{children}</span>
</p>
</div>
</div>
)
}
// Headings and specimens share StoryPage's single Inner. Wide specimens own their local scroll frame.
export function StorySection({
title,