@iyulab/router 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.15.1] - 2026-09-17
4
+
5
+ ### Fixed
6
+
7
+ - **Printing no longer adds a trailing blank page when a screen's last block has a bottom
8
+ margin.** 0.15.0 made `<u-outlet>` a grid container in every medium. A grid container keeps
9
+ its children's margins inside its own box, so the last block's bottom margin added to the
10
+ outlet's height; when the content ended within that margin of a page boundary, the outlet
11
+ spilled onto a page that held only the margin. In print media the outlet is now a block box,
12
+ which lets the margin collapse past it and be truncated at the page break:
13
+
14
+ ```css
15
+ @media print { :where(u-outlet) { display: block; } }
16
+ ```
17
+
18
+ Screen layout is unchanged. The grid only matters when the parent has a definite height, and
19
+ an application shell normally sets one for screen media only.
20
+
3
21
  ## [0.15.0] - 2026-09-16
4
22
 
5
23
  ### Changed
package/README.md CHANGED
@@ -144,12 +144,13 @@ const routes = [
144
144
  ## Outlet Layout
145
145
 
146
146
  `<u-outlet>` declares its own box model. A custom element's UA default is `inline`, which
147
- would put a route's block-level screen inside an inline box — so the outlet adopts a single
148
- rule on whichever tree it is connected to (the document, or the shadow root if it lives in
147
+ would put a route's block-level screen inside an inline box — so the outlet adopts its
148
+ rules on whichever tree it is connected to (the document, or the shadow root if it lives in
149
149
  one):
150
150
 
151
151
  ```css
152
152
  :where(u-outlet) { display: grid; min-height: 100%; }
153
+ @media print { :where(u-outlet) { display: block; } }
153
154
  ```
154
155
 
155
156
  The outlet has to be two things at once, and no single declaration gives both:
@@ -178,11 +179,25 @@ The rule deliberately omits `align-content`; it relies on the initial `normal`.
178
179
  `align-content: start` stops the track from stretching and silently voids case 1.
179
180
 
180
181
  When the parent's own height is `auto`, `min-height: 100%` resolves to `auto` too, so ordinary
181
- document flow and printing are unaffected.
182
+ document flow is unaffected.
183
+
184
+ ### Printing
185
+
186
+ In print media the outlet is a plain block box instead of a grid container. A grid container is
187
+ an independent formatting context, so the bottom margin of a screen's last block cannot collapse
188
+ through it — the margin lands *inside* the outlet's box and adds to its height. On screen that is
189
+ harmless. On paper it is not: when content ends within that margin of a page boundary, the box
190
+ spills onto a new page that holds nothing but the margin. As a block box, the outlet lets the
191
+ margin collapse past it to the end of the document, and a margin that meets a page break is
192
+ truncated there, so no trailing blank page appears.
193
+
194
+ Print loses nothing by this. The grid exists to pass a *sized* parent's height down, and an
195
+ application shell normally sizes itself to the viewport only for screen media; in print the
196
+ parent's height is `auto`, and `min-height: 100%` resolves to nothing.
182
197
 
183
198
  ### Overriding it
184
199
 
185
- The `:where()` wrapper makes the rule's specificity zero, so **any** `u-outlet { … }` rule your
200
+ The `:where()` wrapper makes both rules' specificity zero, so **any** `u-outlet { … }` rule your
186
201
  application writes wins, regardless of sheet order and without `!important`:
187
202
 
188
203
  ```css
@@ -190,7 +205,7 @@ u-outlet { display: flex; } /* wins */
190
205
  u-outlet { display: contents; } /* remove the box entirely */
191
206
  u-outlet { display: block; height: 100%; } /* restores the 0.14.0 behavior */
192
207
  u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
193
- @media print { u-outlet { } } /* wins */
208
+ @media print { u-outlet { display: grid; } } /* restores the 0.15.0 print behavior */
194
209
  ```
195
210
 
196
211
  > **Making the outlet *smaller* takes two declarations, not one.** `min-height` is a floor, so
@@ -198,7 +213,6 @@ u-outlet { display: inline; } /* restores the pre-0.14.0 behavi
198
213
  > `u-outlet { min-height: 0; height: 200px }`. Making it *larger*, or replacing `display`, needs
199
214
  > nothing extra. This is the only contract addition in 0.15.0.
200
215
 
201
- The rule is not media-scoped: the outlet is a block-level box on screen and in print alike.
202
216
 
203
217
  `<u-link>` supports `href`, `target`, `rel`, and `navigate`.
204
218
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-RyrbTDel.js";
1
+ import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-Cwn-vX3y.js";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { customElement, property } from "lit/decorators.js";
4
4
  //#region src/types/RouteError.ts
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { s as UOutlet$1, t as ULink$1 } from "./share-RyrbTDel.js";
1
+ import { s as UOutlet$1, t as ULink$1 } from "./share-Cwn-vX3y.js";
2
2
  import React from "react";
3
3
  import { createComponent } from "@lit/react";
4
4
  //#region src/react.ts
@@ -12,9 +12,10 @@ import { ifDefined } from "lit/directives/if-defined.js";
12
12
  * 무관하게 `!important` 없이 이긴다.
13
13
  * ⚠constructable 시트(`adoptedStyleSheets`)를 쓴다 — `<style>` 요소와 달리 CSP 의 인라인
14
14
  * 스타일 제한에 걸리지 않는다. 지원하지 않는 환경에서는 `<style>` 로 대신한다.
15
- * ⚠매체를 가르지 않는다 — 인라인 컨테이너는 화면에서도 의도된 적이 없다(라인 박스 때문에
16
- * 높이를 줄 수도, 백분율로 채울 수도 없었다). 인쇄에만 한정하면 화면·인쇄가 서로 다른
17
- * 상자 모델을 갖게 되어 같은 부류의 차이가 다음에 또 난다.
15
+ * ⚠«인라인이 아니다» 는 매체를 가르지 않는다 — 인라인 컨테이너는 화면에서도 의도된 적이 없다
16
+ * (라인 박스 때문에 높이를 줄 수도, 백분율로 채울 수도 없었다). 인라인 결함을 인쇄에만 고치면
17
+ * 화면에 같은 결함이 남는다.
18
+ * 🔴**그러나 «어떤 블록 레벨 상자인가» 는 매체를 가른다** — 아래 「인쇄 매체」 절.
18
19
  *
19
20
  * ## 왜 `grid` + `min-height` 인가 — 두 요구가 한 선언으로는 안 된다
20
21
  *
@@ -56,8 +57,20 @@ import { ifDefined } from "lit/directives/if-defined.js";
56
57
  * 가두지 않는다.
57
58
  * 🔴**소비자가 아웃렛을 «줄이려면» `height` 만으로는 부족하고 `min-height: 0` 이 함께 필요하다**
58
59
  * — 0.14.0 대비 유일한 계약 추가이며 README·CHANGELOG·참조 문서에 적혀 있다.
60
+ *
61
+ * ## 인쇄 매체 — `block` 으로 돌아간다 (0.15.1)
62
+ *
63
+ * 🔴**grid 는 자기 안에서 여백 접힘을 막는다.** 라우트 화면의 마지막 블록이 `margin-bottom` 을
64
+ * 가지면 그 여백이 아웃렛 높이 «안으로» 들어온다(실측: 내용 300 + 여백 24 → 아웃렛 324).
65
+ * 화면에서는 무해하지만, 인쇄에서는 내용 끝이 쪽 경계에서 그 여백 이내에 있으면 **빈 꼬리 쪽**
66
+ * 이 생긴다. `block` 이면 여백이 문서 끝까지 접혀 나가고, 쪽 경계에 닿은 여백은 조각화에서
67
+ * 잘린다(CSS Fragmentation §5.2) — 소비자 실측: `block` 1쪽 ↔ `grid` 2쪽.
68
+ * ✅**인쇄에서 grid 가 주던 이득은 없다.** grid 의 존재 이유는 ⑴(정해진 부모 높이를 자손에게)
69
+ * 인데, 셸은 뷰포트 높이를 `@media screen` 안에서만 건다 — 인쇄에서 부모 높이는 `auto` 이고
70
+ * `min-height: 100%` 도 0 으로 풀린다. ⇒ 인쇄에서 grid 는 **여백을 가두기만** 한다.
71
+ * ⚠같은 `:where()` 라 특이도 0 그대로다 — 소비자 규칙은 인쇄에서도 `!important` 없이 이긴다.
59
72
  */
60
- var OUTLET_DISPLAY_CSS = ":where(u-outlet) { display: grid; min-height: 100%; }";
73
+ var OUTLET_DISPLAY_CSS = [":where(u-outlet) { display: grid; min-height: 100%; }", "@media print { :where(u-outlet) { display: block; } }"].join("\n");
61
74
  /** 시트를 이미 채택한 트리 — 같은 트리에 두 번 넣지 않는다. */
62
75
  var styledRoots = /* @__PURE__ */ new WeakSet();
63
76
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/router",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "A modern client-side router for web applications with support for Lit and React components",
5
5
  "keywords": [
6
6
  "lit",
@@ -41,12 +41,13 @@ export function AppRoot() {
41
41
  ## Outlet Layout
42
42
 
43
43
  `<u-outlet>` declares its own box model. A custom element's UA default is `inline`, which
44
- would put a route's block-level screen inside an inline box — so the outlet adopts a single
45
- rule on whichever tree it is connected to (the document, or the shadow root if it lives in
44
+ would put a route's block-level screen inside an inline box — so the outlet adopts its
45
+ rules on whichever tree it is connected to (the document, or the shadow root if it lives in
46
46
  one):
47
47
 
48
48
  ```css
49
49
  :where(u-outlet) { display: grid; min-height: 100%; }
50
+ @media print { :where(u-outlet) { display: block; } }
50
51
  ```
51
52
 
52
53
  The outlet has to be two things at once, and no single declaration gives both:
@@ -75,11 +76,25 @@ The rule deliberately omits `align-content`; it relies on the initial `normal`.
75
76
  `align-content: start` stops the track from stretching and silently voids case 1.
76
77
 
77
78
  When the parent's own height is `auto`, `min-height: 100%` resolves to `auto` too, so ordinary
78
- document flow and printing are unaffected.
79
+ document flow is unaffected.
80
+
81
+ ### Printing
82
+
83
+ In print media the outlet is a plain block box instead of a grid container. A grid container is
84
+ an independent formatting context, so the bottom margin of a screen's last block cannot collapse
85
+ through it — the margin lands *inside* the outlet's box and adds to its height. On screen that is
86
+ harmless. On paper it is not: when content ends within that margin of a page boundary, the box
87
+ spills onto a new page that holds nothing but the margin. As a block box, the outlet lets the
88
+ margin collapse past it to the end of the document, and a margin that meets a page break is
89
+ truncated there, so no trailing blank page appears.
90
+
91
+ Print loses nothing by this. The grid exists to pass a *sized* parent's height down, and an
92
+ application shell normally sizes itself to the viewport only for screen media; in print the
93
+ parent's height is `auto`, and `min-height: 100%` resolves to nothing.
79
94
 
80
95
  ### Overriding it
81
96
 
82
- The `:where()` wrapper makes the rule's specificity zero, so **any** `u-outlet { … }` rule your
97
+ The `:where()` wrapper makes both rules' specificity zero, so **any** `u-outlet { … }` rule your
83
98
  application writes wins, regardless of sheet order and without `!important`:
84
99
 
85
100
  ```css
@@ -87,7 +102,7 @@ u-outlet { display: flex; } /* wins */
87
102
  u-outlet { display: contents; } /* remove the box entirely */
88
103
  u-outlet { display: block; height: 100%; } /* restores the 0.14.0 behavior */
89
104
  u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
90
- @media print { u-outlet { } } /* wins */
105
+ @media print { u-outlet { display: grid; } } /* restores the 0.15.0 print behavior */
91
106
  ```
92
107
 
93
108
  > **Making the outlet *smaller* takes two declarations, not one.** `min-height` is a floor, so
@@ -95,7 +110,6 @@ u-outlet { display: inline; } /* restores the pre-0.14.0 behavi
95
110
  > `u-outlet { min-height: 0; height: 200px }`. Making it *larger*, or replacing `display`, needs
96
111
  > nothing extra. This is the only contract addition in 0.15.0.
97
112
 
98
- The rule is not media-scoped: the outlet is a block-level box on screen and in print alike.
99
113
 
100
114
 
101
115
  ## Nested Outlet Rule