@iyulab/modern-app 0.33.0 → 0.33.2

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,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.33.2] - 2026-10-03
4
+
5
+ ### Changed
6
+
7
+ - **Sidebar transitions follow the motion tokens**, so the sidebar's open/close, group expand and
8
+ hover transitions stop for users who prefer reduced motion (`--u-duration-*` from
9
+ `@iyulab/components` drops to zero under `prefers-reduced-motion: reduce`). The slide-in moves from
10
+ 300ms to the scale's `slow` step (320ms).
11
+
12
+ ## [0.33.1] - 2026-09-30
13
+
14
+ ### Fixed
15
+
16
+ - **Sidebar links with `target: '_blank'` now say so to screen readers** — their accessible name ends
17
+ with a visually hidden "(opens in a new tab)", in the collapsed sidebar too. The text is the new
18
+ `opensInNewTab` string of the `modern-app` locale namespace (English and Korean built in).
19
+
20
+ ### Changed
21
+
22
+ - Optional React peers promise only the tested majors: `@lit/react ^1.0.8` and
23
+ `react ^18.0.0 || ^19.0.0` (were `>=` ranges with no upper bound).
24
+
25
+ ### Documentation
26
+
27
+ - README: the Accessibility section links the KWCAG 2.2 table in `@iyulab/components`.
28
+
3
29
  ## [0.33.0] - 2026-09-30
4
30
 
5
31
  ### Added
package/README.md CHANGED
@@ -277,11 +277,14 @@ conformance claim for the success criteria it does not list.
277
277
  | SC 2.5.8 Target Size (Minimum) | Every pointer target this package renders itself — sidebar links, buttons and group headers (expanded and compact), the sidebar logo and toggle, wizard steps, the page header's back link — is at least 24×24 CSS px or meets the spacing exception (24px between centers), and is actually hit at that position | `tests/browser/target-size.browser.test.ts` (real Chromium) |
278
278
  | SC 2.1.1 Keyboard (pointer-cursor check) | Nothing this package renders shows a pointer cursor without being an interactive element — the sidebar logo is a link | `tests/browser/target-size.browser.test.ts` |
279
279
  | SC 2.4.1 Bypass Blocks | The sidebar layout's first Tab stop is a «Skip to main content» link, visible when focused and at least 24px tall; it moves focus to the screen's `[autofocus]` element or to the route area, which is the page's single `<main>` landmark | `tests/browser/sidebar-layout-skip-link.browser.test.ts` |
280
+ | SC 3.2.5 Change on Request (new tabs) | A sidebar link with `target: '_blank'` ends its accessible name with a localized, visually hidden "(opens in a new tab)" — expanded and collapsed | `tests/browser/sidebar-link-new-tab-name.browser.test.ts` |
280
281
 
281
282
  Buttons placed through slots or rendered as `u-button` without size overrides (wizard back/next, the
282
283
  master-detail close button) follow `@iyulab/components`, which measures them in its own gate. Color
283
284
  contrast likewise comes from that package's tokens.
284
285
 
286
+ For **KWCAG 2.2** (the Korean web accessibility standard), the `@iyulab/components` README has a table of all 33 check items — which are guaranteed by a test across the sibling packages, which are shared with the app, and which do not apply: [KWCAG 2.2 대응표](https://github.com/iyulab/node-components#kwcag-22-대응표).
287
+
285
288
  ## Documentation
286
289
 
287
290
  | Guide | Description |
@@ -1,4 +1,4 @@
1
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
1
+ //#region \0@oxc-project+runtime@0.152.0/helpers/esm/decorate.js
2
2
  function e(e, t, n, r) {
3
3
  var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
4
4
  if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
@@ -1,4 +1,4 @@
1
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
1
+ //#region \0@oxc-project+runtime@0.152.0/helpers/esm/decorateMetadata.js
2
2
  function e(e, t) {
3
3
  if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
4
4
  }
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { slotHasContent as r } from "../internals/slotted.js";
5
5
  import { styles as i } from "./ActionBar.styles.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { getLocaleStrings as r } from "../internals/locale.js";
5
5
  import { slotHasContent as i } from "../internals/slotted.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { slotHasContent as r } from "../internals/slotted.js";
5
5
  import { styles as i } from "./GroupBox.styles.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { styles as r } from "./InfoField.styles.js";
5
5
  import { html as i } from "lit";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { styles as r } from "./InfoSection.styles.js";
5
5
  import { html as i } from "lit";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { getLocaleStrings as r } from "../internals/locale.js";
5
5
  import { slotHasContent as i } from "../internals/slotted.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { getLocaleStrings as r } from "../internals/locale.js";
5
5
  import { slotHasContent as i } from "../internals/slotted.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { DEFAULT_NAV_ICON as r } from "../internals/nav-icon.js";
5
5
  import { styles as i } from "./SidebarButton.styles.js";
@@ -8,7 +8,7 @@ var t = e`
8
8
  background-color: transparent;
9
9
  border: none;
10
10
  border-radius: 8px;
11
- transition: all 0.2s ease;
11
+ transition: all var(--u-duration-normal, 220ms) ease;
12
12
  cursor: pointer;
13
13
  }
14
14
  :host(:hover) {
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { DEFAULT_NAV_ICON as r } from "../internals/nav-icon.js";
5
5
  import { SidebarLink as i } from "./SidebarLink.js";
@@ -22,7 +22,7 @@ var t = e`
22
22
  background-color: transparent;
23
23
  border: none;
24
24
  border-radius: 8px;
25
- transition: all 0.2s ease;
25
+ transition: all var(--u-duration-normal, 220ms) ease;
26
26
  cursor: pointer;
27
27
  }
28
28
  button[compact] {
@@ -71,7 +71,7 @@ var t = e`
71
71
  .caret {
72
72
  color: inherit;
73
73
  font-size: 16px !important;
74
- transition: transform 0.2s ease;
74
+ transition: transform var(--u-duration-normal, 220ms) ease;
75
75
  }
76
76
  .caret[collapsed] {
77
77
  transform: rotate(-90deg);
@@ -86,7 +86,7 @@ var t = e`
86
86
  border-left: 2px solid var(--u-border-color-weak, #EEEEEE);
87
87
  padding-left: 8px;
88
88
  overflow: hidden;
89
- transition: all 0.3s ease;
89
+ transition: all var(--u-duration-slow, 320ms) ease;
90
90
  }
91
91
  .items[collapsed] {
92
92
  margin-top: 0;
@@ -1,45 +1,47 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
- import { DEFAULT_NAV_ICON as r } from "../internals/nav-icon.js";
5
- import { styles as i } from "./SidebarLink.styles.js";
4
+ import { getLocaleStrings as r } from "../internals/locale.js";
5
+ import { DEFAULT_NAV_ICON as i } from "../internals/nav-icon.js";
6
+ import { styles as a } from "./SidebarLink.styles.js";
6
7
  import "@iyulab/router";
7
- import { html as a, nothing as o } from "lit";
8
- import { customElement as s, property as c } from "lit/decorators.js";
8
+ import { html as o, nothing as s } from "lit";
9
+ import { customElement as c, property as l } from "lit/decorators.js";
9
10
  import "@iyulab/components/dist/components/icon/UIcon.js";
10
11
  //#region src/components/SidebarLink.ts
11
- var l = class extends n {
12
+ var u = class extends n {
12
13
  constructor(...e) {
13
14
  super(...e), this.selected = !1, this.compact = !1;
14
15
  }
15
16
  static {
16
- this.styles = [super.styles, i];
17
+ this.styles = [super.styles, a];
17
18
  }
18
19
  render() {
19
- return a`
20
+ return o`
20
21
  <u-link
21
22
  .href=${this.href || "#"}
22
23
  .navigate=${this.navigate}
23
24
  .target=${this.target}
24
- aria-current=${this.selected ? "page" : o}
25
+ aria-current=${this.selected ? "page" : s}
25
26
  >
26
27
  <div class="container" part="base" ?compact=${this.compact}>
27
28
  <u-icon part="icon"
28
29
  .lib=${this.lib}
29
30
  .name=${this.icon}
30
- .fallback=${r}
31
+ .fallback=${i}
31
32
  ></u-icon>
32
33
  <span part="label" ?compact=${this.compact}>
33
34
  ${this.label}
34
35
  </span>
36
+ ${this.target === "_blank" ? o`<span class="new-tab-hint">${r().opensInNewTab}</span>` : s}
35
37
  </div>
36
38
  </u-link>
37
39
  `;
38
40
  }
39
41
  };
40
- t([c({
42
+ t([l({
41
43
  type: Boolean,
42
44
  reflect: !0
43
- }), e("design:type", Object)], l.prototype, "selected", void 0), t([c({ type: Boolean }), e("design:type", Object)], l.prototype, "compact", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "icon", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "lib", void 0), t([c({ type: String }), e("design:type", Object)], l.prototype, "label", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "href", void 0), t([c({ type: String }), e("design:type", Object)], l.prototype, "pattern", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "navigate", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "target", void 0), l = t([s("u-sidebar-link")], l);
45
+ }), e("design:type", Object)], u.prototype, "selected", void 0), t([l({ type: Boolean }), e("design:type", Object)], u.prototype, "compact", void 0), t([l({ type: String }), e("design:type", String)], u.prototype, "icon", void 0), t([l({ type: String }), e("design:type", String)], u.prototype, "lib", void 0), t([l({ type: String }), e("design:type", Object)], u.prototype, "label", void 0), t([l({ type: String }), e("design:type", String)], u.prototype, "href", void 0), t([l({ type: String }), e("design:type", Object)], u.prototype, "pattern", void 0), t([l({ type: String }), e("design:type", String)], u.prototype, "navigate", void 0), t([l({ type: String }), e("design:type", String)], u.prototype, "target", void 0), u = t([c("u-sidebar-link")], u);
44
46
  //#endregion
45
- export { l as SidebarLink };
47
+ export { u as SidebarLink };
@@ -12,7 +12,7 @@ var t = e`
12
12
  color: var(--app-sidebar-fg, var(--u-txt-color, #212121));
13
13
  background-color: transparent;
14
14
  border-radius: 8px;
15
- transition: all 0.2s ease;
15
+ transition: all var(--u-duration-normal, 220ms) ease;
16
16
  cursor: pointer;
17
17
  }
18
18
  :host(:hover) {
@@ -74,6 +74,8 @@ var t = e`
74
74
  * 접힌 상태의 라벨 - 시각적으로만 숨긴다. 접근성 트리에는 남아 항목의 이름이 된다
75
75
  * (hidden 은 트리에서도 빼서 이름 없는 항목을 만들었다). 절대배치라 flex 배치와 gap 에 끼지 않는다.
76
76
  */
77
+ /* 새 창 알림 — 화면에는 없고 링크의 접근성 이름에만 붙는다(KWCAG 7.2.1). */
78
+ .new-tab-hint,
77
79
  [part~='label'][compact] {
78
80
  position: absolute;
79
81
  width: 1px;
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { styles as r } from "./SidebarSection.styles.js";
5
5
  import { html as i } from "lit";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { StyledElement as n } from "../internals/StyledElement.js";
4
4
  import { getLocaleStrings as r } from "../internals/locale.js";
5
5
  import { styles as i } from "./Wizard.styles.js";
@@ -1,5 +1,5 @@
1
- import e from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
- import t from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
1
+ import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
2
+ import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
3
3
  import { property as n } from "lit/decorators.js";
4
4
  import { UElement as r } from "@iyulab/components/dist/components/UElement.js";
5
5
  //#region src/internals/StyledElement.ts
@@ -15,6 +15,8 @@ export interface ModernAppLocaleStrings {
15
15
  toggleSidebar: string;
16
16
  /** Sidebar layout — the «skip to main content» link, the first Tab stop of the shell. */
17
17
  skipToContent: string;
18
+ /** Sidebar links with `target: '_blank'` — appended to the link's accessible name (visually hidden). */
19
+ opensInNewTab: string;
18
20
  /** Wizard — default Back/Next action labels ("Submit" wording is the consumer's call). */
19
21
  wizardBack: string;
20
22
  wizardNext: string;
@@ -10,6 +10,7 @@ var t = {
10
10
  toggleMobileMenu: "Toggle menu",
11
11
  toggleSidebar: "Toggle sidebar",
12
12
  skipToContent: "Skip to main content",
13
+ opensInNewTab: "(opens in a new tab)",
13
14
  wizardBack: "Back",
14
15
  wizardNext: "Next",
15
16
  wizardStepAnnouncement: "Step {index} of {total}: {label}"
@@ -24,6 +25,7 @@ n.register("en", t), n.register("ko", {
24
25
  toggleMobileMenu: "메뉴 열고 닫기",
25
26
  toggleSidebar: "사이드바 열고 닫기",
26
27
  skipToContent: "본문으로 건너뛰기",
28
+ opensInNewTab: "(새 창에서 열림)",
27
29
  wizardBack: "이전",
28
30
  wizardNext: "다음",
29
31
  wizardStepAnnouncement: "{total}단계 중 {index}단계: {label}"
@@ -56,6 +58,7 @@ function l(e) {
56
58
  toggleMobileMenu: t("toggleMobileMenu"),
57
59
  toggleSidebar: t("toggleSidebar"),
58
60
  skipToContent: t("skipToContent"),
61
+ opensInNewTab: t("opensInNewTab"),
59
62
  wizardBack: t("wizardBack"),
60
63
  wizardNext: t("wizardNext"),
61
64
  wizardStepAnnouncement: (t, n, r) => {
@@ -1,7 +1,7 @@
1
1
  import { app as e } from "../App.js";
2
2
  import { filterSidebarItems as t } from "./filterSidebarItems.js";
3
- import n from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
4
- import r from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
+ import n from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
4
+ import r from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
5
5
  import { StyledElement as i } from "../internals/StyledElement.js";
6
6
  import { getLocaleStrings as a } from "../internals/locale.js";
7
7
  import { slotHasContent as o } from "../internals/slotted.js";
@@ -117,7 +117,7 @@ var t = e`
117
117
  background: var(--app-sidebar-bg, var(--u-bg-color-raised, #FAFAFA));
118
118
  color: var(--app-sidebar-fg, var(--u-txt-color, #212121));
119
119
  border-right: 1px solid var(--u-border-color, #E0E0E0);
120
- transition: all 0.3s ease;
120
+ transition: all var(--u-duration-slow, 320ms) ease;
121
121
  }
122
122
  /* Sidebar states */
123
123
  .sidebar[state="default"] {
@@ -327,7 +327,7 @@ var t = e`
327
327
  right: 0;
328
328
  opacity: 0;
329
329
  transform: translateY(-4px);
330
- transition: opacity 0.3s ease, transform 0.3s ease;
330
+ transition: opacity var(--u-duration-slow, 320ms) ease, transform var(--u-duration-slow, 320ms) ease;
331
331
  pointer-events: none;
332
332
  }
333
333
  .main u-progress-bar[visible] {
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.33.0",
4
+ "version": "0.33.2",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "web-framework",
@@ -65,8 +65,8 @@
65
65
  },
66
66
  "peerDependencies": {
67
67
  "@iyulab/components": ">=1.49.0",
68
- "@lit/react": ">=1.0.8",
69
- "react": ">=18.0.0"
68
+ "@lit/react": "^1.0.8",
69
+ "react": "^18.0.0 || ^19.0.0"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "@lit/react": {