diff --git a/.claude/rules/no-responsive.md b/.claude/rules/no-responsive.md new file mode 100644 index 0000000..bef7133 --- /dev/null +++ b/.claude/rules/no-responsive.md @@ -0,0 +1,20 @@ +--- +paths: + - "src/**/*.ts" +--- + +# 렌더링 철학: 고정 레이아웃 + +wireweave는 와이어프레임 DSL이다. 와이어프레임은 특정 화면 크기(width x height)를 기준으로 설계되며, 브라우저나 뷰포트 크기에 따라 레이아웃이 변하면 안 된다. + +## 핵심 원칙 + +1. **페이지는 고정 크기다** — `page`에 지정된 width/height는 어떤 환경에서든 유지되어야 한다. 부모 컨테이너가 작아도 페이지 크기가 줄어들면 안 된다. + +2. **축소는 비율 유지로만** — 뷰포트가 페이지보다 작을 때는 `transform: scale()` 등으로 전체를 동일 비율로 축소하거나, 그대로 clipping한다. 내부 컴포넌트가 재배치되어서는 안 된다. + +3. **렌더링 결과는 환경에 독립적이다** — 에디터, Storybook, VSCode, 브라우저 어디서 열든 동일한 레이아웃이어야 한다. 각 환경이 scale/scroll을 처리하는 것은 허용하지만, 렌더러가 출력하는 HTML/CSS 자체가 환경에 따라 달라지면 안 된다. + +## 과거 사례 + +`.wf-page`에 `flex-shrink: 0`이 없어서, body가 flex container인 환경에서 viewport < page width일 때 페이지가 자동 축소되고 내부 컴포넌트가 재배치되는 문제가 있었다. 렌더러의 CSS를 수정할 때 이 원칙이 깨지지 않는지 항상 확인할 것. diff --git a/CHANGELOG.md b/CHANGELOG.md index b533425..9392d04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [2.7.1-beta.0](https://github.com/wireweave/core/compare/v2.7.0...v2.7.1-beta.0) (2026-03-21) + +### Bug Fixes + +* **renderer:** prevent page shrinking in flex containers ([9d23737](https://github.com/wireweave/core/commit/9d2373786c57215bbfcfa67533ee47fe9d8298ff)) + +### Documentation + +* **rules:** add fixed layout rendering philosophy ([96a503f](https://github.com/wireweave/core/commit/96a503f3154a7fcf68c1eefda2849bb6b0a534fa)) + ## [2.7.0](https://github.com/wireweave/core/compare/v2.7.0-beta.0...v2.7.0) (2026-03-17) ## [2.7.0-beta.0](https://github.com/wireweave/core/compare/v2.6.2...v2.7.0-beta.0) (2026-03-17) diff --git a/__tests__/snapshots/__snapshots__/render.test.ts.snap b/__tests__/snapshots/__snapshots__/render.test.ts.snap index 9daf1d8..a07913f 100644 --- a/__tests__/snapshots/__snapshots__/render.test.ts.snap +++ b/__tests__/snapshots/__snapshots__/render.test.ts.snap @@ -29,6 +29,7 @@ exports[`Render Snapshots > CSS Snapshots > should generate dark theme CSS 1`] = position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -1972,6 +1973,7 @@ exports[`Render Snapshots > CSS Snapshots > should generate light theme CSS 1`] position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -3992,6 +3994,7 @@ body { position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -5965,6 +5968,7 @@ body { position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -8060,6 +8064,7 @@ exports[`Render Snapshots > SVG Snapshots > should render buttons to SVG 1`] = ` position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -10027,6 +10032,7 @@ exports[`Render Snapshots > SVG Snapshots > should render card to SVG 1`] = ` position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -11995,6 +12001,7 @@ exports[`Render Snapshots > SVG Snapshots > should render form to SVG 1`] = ` position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -13964,6 +13971,7 @@ exports[`Render Snapshots > SVG Snapshots > should render layout to SVG 1`] = ` position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -15937,6 +15945,7 @@ exports[`Render Snapshots > SVG Snapshots > should render simple text to SVG 1`] position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -17902,6 +17911,7 @@ exports[`Render Snapshots > SVG Snapshots > should respect padding option 1`] = position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; diff --git a/package.json b/package.json index fa17a2b..732665f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wireweave/core", - "version": "2.7.0", + "version": "2.7.1-beta.0", "description": "Core parser and renderer for wireweave", "type": "module", "main": "dist/index.js", diff --git a/src/renderer/styles.ts b/src/renderer/styles.ts index dd63a72..687325c 100644 --- a/src/renderer/styles.ts +++ b/src/renderer/styles.ts @@ -66,6 +66,7 @@ function generateBaseStyles(prefix: string): string { position: relative; display: flex; flex-direction: column; + flex-shrink: 0; /* Wireframe boundary visualization */ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px;