@iyulab/modern-app 0.19.5 → 0.19.7

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,42 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.19.7] - 2026-09-16
4
+
5
+ ### Changed
6
+
7
+ - **Follow `@iyulab/router` 0.14.0, which declares the outlet's own box model.** Until now the
8
+ route outlet the shell inserts had no `display` declaration, so it fell back to the default
9
+ `inline` — a box that stays in layout but does not pass a height down. The shell gives its
10
+ content area the full height, and that chain stopped at the outlet: a route screen asking for
11
+ `height: 100%` resolved against the shell instead, or not at all. Router 0.14.0 declares
12
+ `:where(u-outlet) { display: block; height: 100%; }`, and this release widens the dependency
13
+ range so the fix actually reaches apps that install the shell rather than the router directly
14
+ (a `^0.13.0` range does not admit 0.14.0 — semver treats a 0.x minor as a major).
15
+ Override either declaration from your own stylesheet without `!important`; the rule carries
16
+ zero specificity.
17
+
18
+ ## [0.19.6] - 2026-09-15
19
+
20
+ ### Fixed
21
+
22
+ - **Printing an `app.load()` screen printed the sidebar and cut the page off after one sheet.** The
23
+ shell is a viewport-height box whose `main` area scrolls, and `app.load()` pinned `document.body`
24
+ to `100vh` with inline styles — on paper the sidebar took a third of the width and anything below
25
+ the first page's height was lost. `u-sidebar-layout` now has print rules: the sidebar, mobile
26
+ header, modal backdrop and progress bar are hidden, the host is no longer a fixed-height box, and
27
+ `main` stops scrolling and drops its screen padding (page margins come from `@page`), so content
28
+ flows across pages. A part can be brought back on paper with
29
+ `@media print { u-sidebar-layout::part(sidebar) { display: flex; } }`.
30
+ - **A narrow `u-master-detail-layout` printed its overlay detail cut off at the master's height**,
31
+ with the close button on the page. In overlay mode the detail is an absolutely positioned box
32
+ over the master; on print it now returns to the flow and prints in full, instead of the covered
33
+ master and without the close button. An empty detail still prints the master.
34
+ - **`document.body` sizing from `app.load()` could only be overridden with `!important`.** It is now
35
+ a document stylesheet instead of inline styles — `margin: 0` always, `width: 100vw; height: 100vh`
36
+ on screen only — at zero specificity, so any `body { … }` rule of your own takes precedence. The
37
+ sheet is adopted (`document.adoptedStyleSheets`), so it is not blocked by a CSP that disallows
38
+ inline styles.
39
+
3
40
  ## [0.19.5] - 2026-09-15
4
41
 
5
42
  ### Fixed
package/dist/App.js CHANGED
@@ -4,7 +4,20 @@ import { Router as n } from "@iyulab/router";
4
4
  import { setDefaultBaseUrl as r } from "@iyulab/components/dist/utilities/icons.js";
5
5
  import { Theme as i } from "@iyulab/components/dist/utilities/Theme.js";
6
6
  import { Toast as a } from "@iyulab/components/dist/utilities/Toast.js";
7
- var o = class o {
7
+ //#region src/App.ts
8
+ var o = "\n:where(body) { margin: 0; }\n@media screen {\n :where(body) { width: 100vw; height: 100vh; }\n}\n", s;
9
+ function c() {
10
+ if (!s) {
11
+ if ("adoptedStyleSheets" in document && typeof CSSStyleSheet < "u" && typeof CSSStyleSheet.prototype.replaceSync == "function") {
12
+ let e = new CSSStyleSheet();
13
+ e.replaceSync(o), document.adoptedStyleSheets = [...document.adoptedStyleSheets, e], s = e;
14
+ } else {
15
+ let e = document.createElement("style");
16
+ e.textContent = o, document.head.prepend(e), s = e;
17
+ }
18
+ }
19
+ }
20
+ var l = class o {
8
21
  constructor() {}
9
22
  static get instance() {
10
23
  return o._instance ||= new o(), o._instance;
@@ -84,7 +97,7 @@ var o = class o {
84
97
  await a.error(e, { ...t });
85
98
  }
86
99
  async createLayout(e, t) {
87
- e === document.body && (document.body.style.margin = "0", document.body.style.width = "100vw", document.body.style.height = "100vh");
100
+ e === document.body && c();
88
101
  let n;
89
102
  if (t.type === "sidebar") {
90
103
  let { SidebarLayout: e } = await import("./layouts/SidebarLayout.js"), r = new e();
@@ -94,4 +107,4 @@ var o = class o {
94
107
  }
95
108
  }.instance;
96
109
  //#endregion
97
- export { o as app };
110
+ export { l as app };
@@ -36,7 +36,7 @@ var u = class extends n {
36
36
  }
37
37
  render() {
38
38
  return o`
39
- <div class="master" part="master"><slot></slot></div>
39
+ <div class="master ${this.hasDetail ? "covered" : ""}" part="master"><slot></slot></div>
40
40
  <div class="divider ${this.hasDetail ? "" : "empty"}" part="divider"></div>
41
41
  <div class="detail ${this.hasDetail ? "" : "empty"}" part="detail">
42
42
  <u-button class="detail-close" part="detail-close" variant="ghost"
@@ -67,6 +67,25 @@ var t = e`
67
67
  :host([overlay]) .detail-close {
68
68
  display: inline-flex;
69
69
  }
70
+
71
+ /*
72
+ * 인쇄 — 오버레이 모드의 detail 은 host 전체를 덮는 절대배치 상자라, 높이가 master 내용에
73
+ * 묶이고(그 밖은 잘린다) 닫기 버튼까지 종이에 찍힌다. 화면에 보이는 것(detail)을 흐름에
74
+ * 되돌려 전부 인쇄한다 — 덮여 있던 master 는 찍지 않는다. detail 이 비어 있으면 master 가
75
+ * 화면 그대로 인쇄된다(covered 는 detail 이 채워졌을 때만 붙는다).
76
+ * 나란히 배치 모드는 바꾸지 않는다 — 두 판이 부모 높이를 따라 풀린다.
77
+ */
78
+ @media print {
79
+ .detail-close,
80
+ :host([overlay]) .detail-close,
81
+ :host([overlay]) .master.covered {
82
+ display: none;
83
+ }
84
+ :host([overlay]) .detail {
85
+ position: static;
86
+ box-shadow: none;
87
+ }
88
+ }
70
89
  `;
71
90
  //#endregion
72
91
  export { t as styles };
@@ -221,6 +221,32 @@ var t = e`
221
221
  bottom: 0;
222
222
  background: var(--u-overlay-bg-color, rgba(0, 0, 0, 0.5));
223
223
  }
224
+
225
+ /*
226
+ * 인쇄 — 화면의 «뷰포트를 채우는 고정 상자 + 스크롤하는 본문» 모델을 풀어 준다.
227
+ * 그대로 두면 사이드바가 종이에 찍히고, 본문이 스크롤 컨테이너라 첫 쪽 높이 밖이 잘린다.
228
+ * ★!important 를 쓰지 않는다 — 섀도 안의 important 선언은 바깥 ::part 의 important 보다 이겨
229
+ * 소비자가 인쇄물에 크롬을 되살릴 길(::part(sidebar) 재정의)을 막는다. 대가로 config.styles 의
230
+ * 인라인 스타일은 이 규칙보다 앞선다(그 자리에 높이·overflow 를 적는 소비자는 드물다).
231
+ * ⚠본문 패딩도 푼다 — 종이의 여백은 @page 가 준다. 화면 여백이 그 위에 겹치면 폭을 잃는다.
232
+ */
233
+ @media print {
234
+ :host {
235
+ display: block;
236
+ height: auto;
237
+ overflow: visible;
238
+ }
239
+ .sidebar,
240
+ .mobile-header,
241
+ .backdrop,
242
+ .main u-progress-bar {
243
+ display: none;
244
+ }
245
+ .main {
246
+ padding: 0;
247
+ overflow: visible;
248
+ }
249
+ }
224
250
  `;
225
251
  //#endregion
226
252
  export { t as styles };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/modern-app",
3
3
  "description": "web-framework by iyulab based on lit-element",
4
- "version": "0.19.5",
4
+ "version": "0.19.7",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "web-framework",
@@ -60,7 +60,7 @@
60
60
  "typecheck": "tsc --noEmit"
61
61
  },
62
62
  "dependencies": {
63
- "@iyulab/router": "^0.13.0",
63
+ "@iyulab/router": "^0.14.0",
64
64
  "i18next": "^26.3.6",
65
65
  "lit": "^3.3.3"
66
66
  },
@@ -51,6 +51,14 @@ constrained.
51
51
  .page { height: 100%; } /* or any constrained height on the parent */
52
52
  ```
53
53
 
54
+ ## Printing
55
+
56
+ On print media the panes follow what was on screen. Side by side, both panes print and grow
57
+ with their content once the page shell releases its height (`u-sidebar-layout` does on print).
58
+ In overlay mode, a filled detail prints in full, in flow, instead of the covered master, and the
59
+ close button is not printed; with the detail empty, the master prints. The overlay state is the
60
+ one measured on screen when printing starts.
61
+
54
62
  ## Slots
55
63
 
56
64
  | Name | Description |
@@ -265,17 +265,39 @@ Parts available for `styles` overrides on the root layout:
265
265
 
266
266
  `<u-sidebar-layout>` is a shell: `:host` is `height: 100%` with `overflow: hidden`, so **its
267
267
  height comes from the parent** — it never sizes itself. `app.load()` covers the default case: when
268
- `root` is `document.body` it sets `margin: 0; width: 100vw; height: 100vh` on the body for you.
268
+ `root` is `document.body` it gives the body `margin: 0`, and on screen `width: 100vw; height: 100vh`.
269
+ These come from a document stylesheet at zero specificity, not inline styles — any `body { … }`
270
+ rule of your own wins.
269
271
 
270
272
  ⚠ **A custom `root` receives no styling.** Hand it a container with no height of its own and
271
273
  `height: 100%` has nothing to resolve against: the shell renders at whatever its own chrome
272
274
  resolves to (measured: about 133px) instead of filling the screen — with no error and nothing in
273
- the console. Give that container a height:
275
+ the console. Give that container a height — for screen only, so printing is not cut at one page:
274
276
 
275
277
  ```css
276
- #app { height: 100vh; } /* or 100%, inside an already-constrained ancestor */
278
+ @media screen {
279
+ #app { height: 100vh; } /* or 100%, inside an already-constrained ancestor */
280
+ }
277
281
  ```
278
282
 
283
+ ## Printing
284
+
285
+ On print media the shell drops its app chrome and lets the content flow across pages: the
286
+ `sidebar`, `mobile-header`, modal backdrop and `progress` bar are hidden, the host is no longer a
287
+ fixed-height box, and `main` stops being a scroll container and loses its screen padding (page
288
+ margins come from `@page`). Nothing to configure.
289
+
290
+ To keep a piece of chrome on paper, restore it through its part:
291
+
292
+ ```css
293
+ @media print {
294
+ u-sidebar-layout::part(sidebar) { display: flex; }
295
+ }
296
+ ```
297
+
298
+ ⚠ Heights or `overflow` set through `layout.styles` are inline styles and still apply when
299
+ printing — scope such values to the screen in your own CSS instead.
300
+
279
301
  ## Responsive behaviour
280
302
 
281
303
  | Screen width | Sidebar state |