docs(sw): align AI docs and comments with the 2026-10-21 implementation

Documentation and comment-only changes (no component logic, Props or design change):
- VIEWER.md / AI_GUIDE / AI_USAGE / catalog / patterns: the two SWViewerHeader versions
  (default, and minimize/close with SWHeaderWindowControls at the end of `trailing`);
  the earlier "never mix SWHeader parts" rule now names this approved exception.
- collapseBelow / iconOnlyBelow (types.ts JSDoc, VIEWER.md, AI_GUIDE): measured steps,
  the numbers only set the order, not pixel breakpoints. Viewer file open is the
  onDocumentOpen button (logoMenu is compatibility only).
- COMPONENT_CATALOG / DESIGN_RULES: recent files show at most 3 rows; preview caption is
  previewTitle or path + file name; body is the red no-preview sign on the brown panel;
  preview / renderPreview are accepted but not rendered (JSDoc updated to match).
- packages/sw/README.md and sw-header-usage.md: current Story list and counts (40, 14
  shown + 26 verification); 760px+ no-More condition; read-only Property Bar values as
  <output>.
- SWHeader.tsx comment: titles are kept (not hidden) from 760px up.
- AI_GUIDE synced into the package ai/ copies (npm run sync:ai-docs).
This commit is contained in:
shkim4 committed 2026-10-21 17:45:26 +09:00
1 parent 646fb60462
commit 8127cc72c4
16 files changed
+73 -42

No files matched your search

@@ -321,7 +321,8 @@ export const SWHeader = forwardRef<HTMLElement, SWHeaderProps>(function SWHeader
const baseMenu = menuIds.includes("layer") ? "layer" : menuIds[0]
const validPromoted = promoted && enabled(promoted) ? promoted : null
// 2026-10-21 (user decision): no responsive More from 760px up. Nothing moves out of the header there; narrower headers
// hide the field titles, then shrink the file name, then the field values (ellipsis, sw.css "Responsive"). Below 760px
// keep the field titles (they and the values ellipsize), hide the 그리기모드 text and pictures, then shrink the file
// name, then the field values (ellipsis, sw.css "Responsive"). Below 760px
// (phones, e.g. 390) the former breakpoints and More are unchanged.
const breakpointOverflowAt = (id: SWHeaderControlId, width: number) => width < MORE_BELOW && (id === "color" ? width < 900 : ["lineStyle", "textStyle", "dimensionStyle"].includes(id) ? width < 1800 : ["propertyBar", "propertyPanel", "details"].includes(id) ? width < 1080 : ["print", "popupGuide"].includes(id) ? width < 640 : id === "drawingMode" ? width < 1180 : false)
const breakpointOverflow = (id: SWHeaderControlId) => breakpointOverflowAt(id, headerWidth)
@@ -23,7 +23,7 @@ export interface SWRecentFilesProps extends Omit<HTMLAttributes<HTMLDivElement>,
onFileOpen?: (file: SWFileEntry) => void
/** Hover / focus change of the previewed row (null when none). */
onFileHover?: (file: SWFileEntry | null) => void
/** Preview content when a file has no `preview` (e.g. a thumbnail loaded by the host). */
/** Accepted for compatibility, not called (2026-10-21): the preview shows the "no preview" sign, never host content. */
renderPreview?: (file: SWFileEntry) => ReactNode
/** Inside <SWHomeMenu>: close the menu after `onFileOpen`. Default true. */
closeOnOpen?: boolean
@@ -36,7 +36,8 @@ export interface SWRecentFilesProps extends Omit<HTMLAttributes<HTMLDivElement>,
* Figma 최근파일 662:67331: 354px recent-file list (rows 50px: optional 29 x 28 badge, name 14px, path 12px)
* with the 2-depth preview 662:67471 beside the hovered / focused row. The list height follows the rows and is
* capped (`--hm-sw-recent-files-max-height`, Figma 750 = 15 rows); longer lists scroll inside. Only the first 3
* files are shown (2026-10-21).
* files are shown (2026-10-21); the preview caption is `previewTitle` or the `path` + file name, and its body is the
* red "no preview" sign on the brown panel (no image is rendered).
*/
export function SWRecentFiles({
files, onFileOpen, onFileHover, renderPreview, closeOnOpen = true, emptyText = "최근 파일이 없습니다",
@@ -107,7 +107,10 @@ export interface SWFileEntry {
path?: string
/** 29 x 28 slot before the text (Figma icon_dualmonitor: the file is open on monitor 1 / 2). Rows without it keep the text column. */
badge?: ReactNode
/** 2-depth preview shown beside the hovered / focused row (Figma 파일출력 2뎁스 662:67471). */
/**
* Accepted for compatibility, not rendered (2026-10-21): the 2-depth preview beside the hovered / focused row shows the
* "no preview" sign instead of any image (Figma 파일출력 2뎁스 662:67471).
*/
preview?: ReactNode
/** Preview caption; defaults to `path` + `name` (2026-10-21; a `path` already ending with the name is not doubled). */
previewTitle?: string
@@ -70,9 +70,15 @@ interface SWViewerHeaderItemBase {
disabled?: boolean
/** Removed from the header and from More. */
hidden?: boolean
/** Header width (px) below which the item moves into the More dropdown. */
/**
* Moves into the More dropdown when the measured header row has no room left, after the icons-only step. Not a pixel
* breakpoint: the value only sets the order (higher first; same value, rightmost first).
*/
collapseBelow?: number
/** Header width (px) below which only the icon is shown (label kept as the accessible name). */
/**
* Shows only the icon (label kept as tooltip and accessible name) when the measured header row has no room left; all
* such items switch together, before any item moves into More. Needs `icon`. Not a pixel breakpoint: any value.
*/
iconOnlyBelow?: number
/** Always icon only (e.g. the info button). Needs `icon`. */
iconOnly?: boolean