@iyulab/modern-app 0.17.0 → 0.18.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 +49 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.143.0 → _@oxc-project_runtime@0.146.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.143.0 → _@oxc-project_runtime@0.146.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/components/ActionBar.js +2 -2
- package/dist/components/EmptyState.js +2 -2
- package/dist/components/GroupBox.js +2 -2
- package/dist/components/GroupBox.styles.js +1 -1
- package/dist/components/InfoField.d.ts +4 -0
- package/dist/components/InfoField.js +3 -3
- package/dist/components/InfoField.styles.js +11 -0
- package/dist/components/InfoSection.js +2 -2
- package/dist/components/MasterDetailLayout.js +2 -2
- package/dist/components/PageHeader.js +2 -2
- package/dist/components/SidebarButton.d.ts +3 -0
- package/dist/components/SidebarButton.js +2 -2
- package/dist/components/SidebarGroup.js +2 -2
- package/dist/components/SidebarLink.d.ts +1 -1
- package/dist/components/SidebarLink.js +9 -8
- package/dist/components/SidebarSection.js +2 -2
- package/dist/components/Wizard.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -13
- package/dist/internals/StyledElement.js +2 -2
- package/dist/internals/locale.d.ts +4 -0
- package/dist/internals/locale.js +2 -0
- package/dist/layouts/SidebarLayout.d.ts +3 -1
- package/dist/layouts/SidebarLayout.js +40 -34
- package/dist/layouts/SidebarLayout.types.d.ts +7 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +12 -11
- package/package.json +1 -1
- package/skills/modern-app/references/components/info-field.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.18.2] - 2026-08-19
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **`SidebarLayout`'s mobile-header and sidebar-header toggle buttons now have an accessible
|
|
8
|
+
name.** Both are icon-only `<u-button>`s with no `aria-label`, text, or `title` — a
|
|
9
|
+
screen-reader user only ever heard an unnamed "button". Wired through the same locale
|
|
10
|
+
registry `MasterDetailLayout.detailClose` already uses (`toggleMobileMenu` /
|
|
11
|
+
`toggleSidebar`), so translations follow `registerLocale` automatically; default English
|
|
12
|
+
labels preserve current behavior for everyone who hasn't set a `locale`.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`SidebarButtonConfig.id?: string`.** Passed straight through to the rendered
|
|
17
|
+
`<u-sidebar-button>` host, so a consumer can anchor a `u-popover` (or any `for="#id"`
|
|
18
|
+
pattern) to a sidebar button using only public API — previously the only way to get an
|
|
19
|
+
anchorable id was to reach into the internal, unexported `<u-sidebar-button>` tag name.
|
|
20
|
+
Unset behaves exactly as before (no `id` attribute) — not a breaking change.
|
|
21
|
+
|
|
22
|
+
## [0.18.1] - 2026-08-19
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **`GroupBox`'s background no longer matches the surrounding page/sidebar in light mode, or
|
|
27
|
+
input fields in dark mode.** It referenced the same token as those surfaces
|
|
28
|
+
(`--u-panel-bg-color`); switched to `--u-bg-color-raised`, which both themes already define
|
|
29
|
+
distinctly.
|
|
30
|
+
|
|
31
|
+
## [0.18.0] - 2026-08-17
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **`SidebarLink` now sets `aria-current="page"` on its inner `<u-link>` when `selected` is
|
|
36
|
+
true.** Previously `selected` only drove visual emphasis (a host attribute for CSS) — a
|
|
37
|
+
screen-reader user had no way to tell which item was the current page.
|
|
38
|
+
- **`SidebarLayoutConfig.mainAriaLabel?: string`.** When set, it's reflected as `aria-label`
|
|
39
|
+
on the sidebar's main `<nav>` landmark. That `<nav>` lives inside `SidebarLayout`'s shadow
|
|
40
|
+
root, so a consumer had no way to name it from the outside. Unset behaves exactly as
|
|
41
|
+
before (no landmark name) — not a breaking change.
|
|
42
|
+
- **`InfoField`'s `tone` now colors the value text itself, not just the trend indicator.**
|
|
43
|
+
Previously `.trend.tone-*` was the only CSS surface for `tone`, so a static figure shown
|
|
44
|
+
without a `trend` (e.g. a balance due) couldn't be toned at all. `trend`'s existing
|
|
45
|
+
behavior is unchanged; this only widens where `tone` is visible.
|
|
46
|
+
- **`ScreenObserver` is now exported from both the main entry and `/react`.** `SidebarLayout`'s
|
|
47
|
+
responsive state (large→slim, medium→modal, small→mobile) depends entirely on the
|
|
48
|
+
`screen-resize` event this class dispatches; `app.load()` instantiates it internally, but a
|
|
49
|
+
consumer mounting `SidebarLayout` standalone through `/react` (without `app.load()`) had no
|
|
50
|
+
public way to drive that behavior.
|
|
51
|
+
|
|
3
52
|
## [0.17.0] - 2026-08-11
|
|
4
53
|
|
|
5
54
|
### Added
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.146.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.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
|
@@ -7,7 +7,7 @@ var t = e`
|
|
|
7
7
|
사이드바가 열린 1280px 화면의 좁은 본문에서도, 넓은 본문을 가진 태블릿에서도
|
|
8
8
|
같은 판단을 하려면 기준이 자기 폭이어야 한다. */
|
|
9
9
|
container-type: inline-size;
|
|
10
|
-
background-color: var(--u-
|
|
10
|
+
background-color: var(--u-bg-color-raised, #FAFAFA);
|
|
11
11
|
border: 1px solid var(--u-border-color-weak, #EEEEEE);
|
|
12
12
|
/* 면(surface) 단 — 컨트롤과 같은 반경을 쓰면 큰 사각형이 각져 보인다. */
|
|
13
13
|
border-radius: var(--u-radius-2xl, 12px);
|
|
@@ -77,6 +77,10 @@ export declare class InfoField extends StyledElement<ElementParts> {
|
|
|
77
77
|
* Explicit tone override. When unset, resolves from `trend` (`up→positive`, `down→negative`,
|
|
78
78
|
* `flat`/unset→`neutral`). **Always wins over inference** — some metrics invert the usual
|
|
79
79
|
* direction-to-sentiment mapping (e.g. a falling "open tickets" count is `positive`).
|
|
80
|
+
*
|
|
81
|
+
* Colors the value text itself, independent of `trend` — a static "balance due" figure can be
|
|
82
|
+
* toned `negative` without a trend arrow. `neutral` has no visual effect on the value text
|
|
83
|
+
* (it already renders at full strength; only `positive`/`negative` stand out from it).
|
|
80
84
|
*/
|
|
81
85
|
tone?: InfoFieldTone;
|
|
82
86
|
private get hasSlotted();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
|
@@ -29,7 +29,7 @@ var f = class extends n {
|
|
|
29
29
|
let e = !this.hasSlotted && d(this.value), t = this.numeric || this.format === "number" || this.format === "currency", n = this.trend !== void 0 || this.trendLabel !== void 0, r = this.tone ?? u(this.trend), a = this.trend === "up" ? "▲" : this.trend === "down" ? "▼" : "";
|
|
30
30
|
return i`
|
|
31
31
|
<div class="label" part="label">${this.label}</div>
|
|
32
|
-
<div class="value ${t ? "numeric" : ""} ${e ? "blank" : ""}" part="value">
|
|
32
|
+
<div class="value ${t ? "numeric" : ""} ${e ? "blank" : ""} tone-${r}" part="value">
|
|
33
33
|
${this.hasSlotted ? i`<slot></slot>` : e ? this.blank : this.formatValue()}
|
|
34
34
|
</div>
|
|
35
35
|
${n ? i`
|
|
@@ -46,6 +46,17 @@ var t = e`
|
|
|
46
46
|
font-weight: var(--u-text-body-weight, 400);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/* tone은 trend 유무와 무관하게 값 텍스트 자체에도 적용된다(neutral은 무규칙 — 기본
|
|
50
|
+
.value 색과 시각적으로 같은 자리라 별도 규칙을 두면 오히려 "옅어 보이는" 부작용이
|
|
51
|
+
생긴다, .trend.tone-neutral과 달리 .value는 이미 강한 색이 기본값이다). */
|
|
52
|
+
.value.tone-positive {
|
|
53
|
+
color: var(--u-success-color-strong, #1B5E20);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.value.tone-negative {
|
|
57
|
+
color: var(--u-danger-color-strong, #C62828);
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
.trend {
|
|
50
61
|
font-size: var(--u-text-caption-size, 12px);
|
|
51
62
|
margin-top: var(--u-space-3xs, 2px);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
|
@@ -6,6 +6,9 @@ type ElementParts = 'host' | 'base' | 'icon' | 'label';
|
|
|
6
6
|
/** 버튼 항목 구성 */
|
|
7
7
|
export interface SidebarButtonConfig extends SidebarPermissionGuard {
|
|
8
8
|
type: 'button';
|
|
9
|
+
/** 렌더된 `<u-sidebar-button>` 호스트에 그대로 전달된다 — `u-popover[for="#id"]` 같은
|
|
10
|
+
* 외부 앵커링에 쓴다. */
|
|
11
|
+
id?: string;
|
|
9
12
|
icon?: string;
|
|
10
13
|
/** `icon`을 어느 등록 라이브러리에서 찾을지. 미지정 시 `u-icon`의 기본 URL 경로로
|
|
11
14
|
* 해석된다(`IconRegistry.register()`로 등록한 이름 있는 세트를 쓰려면 지정해야 함). */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
|
@@ -37,7 +37,7 @@ export interface SidebarLinkConfig extends SidebarPermissionGuard {
|
|
|
37
37
|
*/
|
|
38
38
|
export declare class SidebarLink extends StyledElement<ElementParts> {
|
|
39
39
|
static styles: import('lit').CSSResultGroup[];
|
|
40
|
-
/** selected
|
|
40
|
+
/** selected 상태. `true`면 내부 `<u-link>`에 `aria-current="page"`도 함께 세팅한다. */
|
|
41
41
|
selected: boolean;
|
|
42
42
|
/** 콤팩트 모드 여부 */
|
|
43
43
|
compact: boolean;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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 "./SidebarLink.styles.js";
|
|
6
|
-
import { html as a } from "lit";
|
|
7
|
-
import { customElement as
|
|
6
|
+
import { html as a, nothing as o } from "lit";
|
|
7
|
+
import { customElement as s, property as c } from "lit/decorators.js";
|
|
8
8
|
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
9
9
|
//#region src/components/SidebarLink.ts
|
|
10
|
-
var
|
|
10
|
+
var l = class extends n {
|
|
11
11
|
constructor(...e) {
|
|
12
12
|
super(...e), this.selected = !1, this.compact = !1;
|
|
13
13
|
}
|
|
@@ -20,6 +20,7 @@ var c = class extends n {
|
|
|
20
20
|
.href=${this.href || "#"}
|
|
21
21
|
.navigate=${this.navigate}
|
|
22
22
|
.target=${this.target}
|
|
23
|
+
aria-current=${this.selected ? "page" : o}
|
|
23
24
|
>
|
|
24
25
|
<div class="container" part="base" ?compact=${this.compact}>
|
|
25
26
|
<u-icon part="icon"
|
|
@@ -35,9 +36,9 @@ var c = class extends n {
|
|
|
35
36
|
`;
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
|
-
t([
|
|
39
|
+
t([c({
|
|
39
40
|
type: Boolean,
|
|
40
41
|
reflect: !0
|
|
41
|
-
}), e("design:type", Object)],
|
|
42
|
+
}), 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);
|
|
42
43
|
//#endregion
|
|
43
|
-
export {
|
|
44
|
+
export { l as SidebarLink };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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";
|
package/dist/index.d.ts
CHANGED
|
@@ -15,5 +15,7 @@ export { Wizard } from './components/Wizard.js';
|
|
|
15
15
|
export type { WizardStep, WizardStepState, WizardStepChangeDetail } from './components/Wizard.js';
|
|
16
16
|
export { registerLocale, setDefaultLocale, getLocaleStrings, getDefaultLocale, } from './internals/locale.js';
|
|
17
17
|
export type { ModernAppLocaleStrings } from './internals/locale.js';
|
|
18
|
+
export { ScreenObserver } from './internals/ScreenObserver.js';
|
|
19
|
+
export type { ScreenSize, ScreenObserverConfig, ScreenResizeEvent } from './internals/ScreenObserver.js';
|
|
18
20
|
export { app };
|
|
19
21
|
export default app;
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
1
|
+
import { ScreenObserver as e } from "./internals/ScreenObserver.js";
|
|
2
|
+
import { app as t } from "./App.js";
|
|
3
|
+
import { filterSidebarItems as n } from "./layouts/filterSidebarItems.js";
|
|
4
|
+
import { getDefaultLocale as r, getLocaleStrings as i, registerLocale as a, setDefaultLocale as o } from "./internals/locale.js";
|
|
5
|
+
import { PageHeader as s } from "./components/PageHeader.js";
|
|
6
|
+
import { GroupBox as c } from "./components/GroupBox.js";
|
|
7
|
+
import { InfoSection as l } from "./components/InfoSection.js";
|
|
8
|
+
import { InfoField as u, isBlank as d } from "./components/InfoField.js";
|
|
9
|
+
import { EmptyState as f } from "./components/EmptyState.js";
|
|
10
|
+
import { ActionBar as p } from "./components/ActionBar.js";
|
|
11
|
+
import { MasterDetailLayout as m } from "./components/MasterDetailLayout.js";
|
|
12
|
+
import { Wizard as h } from "./components/Wizard.js";
|
|
12
13
|
//#region src/index.ts
|
|
13
|
-
var
|
|
14
|
+
var g = t;
|
|
14
15
|
//#endregion
|
|
15
|
-
export {
|
|
16
|
+
export { p as ActionBar, f as EmptyState, c as GroupBox, u as InfoField, l as InfoSection, m as MasterDetailLayout, s as PageHeader, e as ScreenObserver, h as Wizard, t as app, g as default, n as filterSidebarItems, r as getDefaultLocale, i as getLocaleStrings, d as isBlank, a as registerLocale, o as setDefaultLocale };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import t from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.146.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
|
|
@@ -28,6 +28,10 @@ export interface ModernAppLocaleStrings {
|
|
|
28
28
|
noResultsDescription: string;
|
|
29
29
|
/** Master-detail layout — accessible label for the overlay-mode close button. */
|
|
30
30
|
detailClose: string;
|
|
31
|
+
/** Sidebar layout — accessible label for the mobile-header menu toggle button. */
|
|
32
|
+
toggleMobileMenu: string;
|
|
33
|
+
/** Sidebar layout — accessible label for the sidebar-header collapse/expand toggle button. */
|
|
34
|
+
toggleSidebar: string;
|
|
31
35
|
/** Wizard — default Back/Next action labels ("Submit" wording is the consumer's call). */
|
|
32
36
|
wizardBack: string;
|
|
33
37
|
wizardNext: string;
|
package/dist/internals/locale.js
CHANGED
|
@@ -6,6 +6,8 @@ var e = {
|
|
|
6
6
|
noResultsTitle: "No matching results",
|
|
7
7
|
noResultsDescription: "Try changing your search terms or filters.",
|
|
8
8
|
detailClose: "Close",
|
|
9
|
+
toggleMobileMenu: "Toggle menu",
|
|
10
|
+
toggleSidebar: "Toggle sidebar",
|
|
9
11
|
wizardBack: "Back",
|
|
10
12
|
wizardNext: "Next",
|
|
11
13
|
wizardStepAnnouncement: (e, t, n) => `Step ${e} of ${t}: ${n}`
|
|
@@ -9,13 +9,15 @@ export declare class SidebarLayout extends StyledElement<SidebarParts> {
|
|
|
9
9
|
state: SidebarState;
|
|
10
10
|
/** 사이드바 레이아웃 설정 */
|
|
11
11
|
config?: SidebarLayoutConfig;
|
|
12
|
+
/** 크롬 문자열(토글 버튼 접근성 라벨 등) 로케일 — `registerLocale`로 등록한 언어 태그 */
|
|
13
|
+
locale: string;
|
|
12
14
|
progressBarEl: UProgressBar;
|
|
13
15
|
/** 현재 라우터 컨텍스트 */
|
|
14
16
|
context: RouteContext | null;
|
|
15
17
|
connectedCallback(): void;
|
|
16
18
|
disconnectedCallback(): void;
|
|
17
19
|
protected willUpdate(changedProperties: PropertyValues): void;
|
|
18
|
-
render(): import('lit-html').TemplateResult<1
|
|
20
|
+
render(): typeof nothing | import('lit-html').TemplateResult<1>;
|
|
19
21
|
/** 사이드바 아이템 렌더링 */
|
|
20
22
|
private renderItem;
|
|
21
23
|
/** 현재 경로와 패턴 매칭 여부 확인 */
|
|
@@ -1,30 +1,32 @@
|
|
|
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.
|
|
4
|
-
import r from "../_virtual/_@oxc-project_runtime@0.
|
|
3
|
+
import n from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorateMetadata.js";
|
|
4
|
+
import r from "../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorate.js";
|
|
5
5
|
import { StyledElement as i } from "../internals/StyledElement.js";
|
|
6
|
+
import { getLocaleStrings as a } from "../internals/locale.js";
|
|
6
7
|
import "../components/SidebarSection.js";
|
|
7
8
|
import "../components/SidebarLink.js";
|
|
8
9
|
import "../components/SidebarGroup.js";
|
|
9
10
|
import "../components/SidebarButton.js";
|
|
10
|
-
import { styles as
|
|
11
|
-
import { html as
|
|
12
|
-
import { customElement as
|
|
11
|
+
import { styles as o } from "./SidebarLayout.styles.js";
|
|
12
|
+
import { html as s, nothing as c } from "lit";
|
|
13
|
+
import { customElement as l, property as u, query as d, state as f } from "lit/decorators.js";
|
|
13
14
|
import "@iyulab/components/dist/components/button/UButton.js";
|
|
14
15
|
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
15
|
-
import { unsafeHTML as
|
|
16
|
-
import { repeat as
|
|
17
|
-
import {
|
|
16
|
+
import { unsafeHTML as p } from "lit/directives/unsafe-html.js";
|
|
17
|
+
import { repeat as m } from "lit/directives/repeat.js";
|
|
18
|
+
import { ifDefined as h } from "lit/directives/if-defined.js";
|
|
19
|
+
import { UProgressBar as g } from "@iyulab/components/dist/components/progress-bar/UProgressBar.js";
|
|
18
20
|
//#region src/layouts/SidebarLayout.ts
|
|
19
|
-
function
|
|
21
|
+
function _(e) {
|
|
20
22
|
let t = e.tagName;
|
|
21
23
|
if (t === "INPUT" || t === "TEXTAREA" || t === "SELECT" || e.isContentEditable) return !0;
|
|
22
24
|
let n = e.getAttribute("role");
|
|
23
25
|
return n === "textbox" || n === "searchbox" || n === "combobox" || n === "spinbutton";
|
|
24
26
|
}
|
|
25
|
-
var
|
|
27
|
+
var v = class extends i {
|
|
26
28
|
constructor(...t) {
|
|
27
|
-
super(...t), this.state = "default", this.context = null, this.isMatchedLink = (e) => !this.context || !e ? !1 : (e = typeof e == "string" ? new URLPattern(e, window.location.origin) : e, e.test(this.context.path, window.location.origin)), this.handleBrandLogoClick = (t) => () => {
|
|
29
|
+
super(...t), this.state = "default", this.locale = "", this.context = null, this.isMatchedLink = (e) => !this.context || !e ? !1 : (e = typeof e == "string" ? new URLPattern(e, window.location.origin) : e, e.test(this.context.path, window.location.origin)), this.handleBrandLogoClick = (t) => () => {
|
|
28
30
|
e.navigate(t ?? "");
|
|
29
31
|
}, this.handleToggleButtonClick = () => {
|
|
30
32
|
let t = e.screen ?? "large";
|
|
@@ -45,7 +47,7 @@ var g = class extends i {
|
|
|
45
47
|
}, 300);
|
|
46
48
|
}, this._handleMainKeydown = (e) => {
|
|
47
49
|
let t = e.composedPath()[0];
|
|
48
|
-
if (t instanceof HTMLElement &&
|
|
50
|
+
if (t instanceof HTMLElement && _(t)) return;
|
|
49
51
|
let n = this.shadowRoot?.querySelector(".main");
|
|
50
52
|
if (!n) return;
|
|
51
53
|
let r = n.clientHeight;
|
|
@@ -78,7 +80,7 @@ var g = class extends i {
|
|
|
78
80
|
};
|
|
79
81
|
}
|
|
80
82
|
static {
|
|
81
|
-
this.styles = [super.styles,
|
|
83
|
+
this.styles = [super.styles, o];
|
|
82
84
|
}
|
|
83
85
|
connectedCallback() {
|
|
84
86
|
super.connectedCallback(), window.addEventListener("route-begin", this.handleRouteBegin), window.addEventListener("route-done", this.handleRouteDone), window.addEventListener("route-progress", this.handleRouteProgress), window.addEventListener("route-error", this.handleRouteError), window.addEventListener("screen-resize", this.handleScreenResize);
|
|
@@ -90,7 +92,7 @@ var g = class extends i {
|
|
|
90
92
|
super.willUpdate(e), e.has("config") && (this.styles = this.config?.styles);
|
|
91
93
|
}
|
|
92
94
|
render() {
|
|
93
|
-
return this.config ?
|
|
95
|
+
return this.config ? s`
|
|
94
96
|
<!-- Mobile Header -->
|
|
95
97
|
<div class="mobile-header" part="mobile-header" ?hidden="${!this.state.startsWith("mobile")}">
|
|
96
98
|
${this.renderLogo()}
|
|
@@ -98,6 +100,7 @@ var g = class extends i {
|
|
|
98
100
|
${this.config.title}
|
|
99
101
|
</span>
|
|
100
102
|
<u-button class="toggler" variant="ghost"
|
|
103
|
+
aria-label=${a(this.locale || void 0).toggleMobileMenu}
|
|
101
104
|
@click=${this.handleToggleButtonClick}>
|
|
102
105
|
<u-icon
|
|
103
106
|
lib="bootstrap"
|
|
@@ -115,6 +118,7 @@ var g = class extends i {
|
|
|
115
118
|
${this.config.title}
|
|
116
119
|
</span>
|
|
117
120
|
<u-button class="toggler" variant="ghost"
|
|
121
|
+
aria-label=${a(this.locale || void 0).toggleSidebar}
|
|
118
122
|
@click=${this.handleToggleButtonClick}>
|
|
119
123
|
<u-icon
|
|
120
124
|
lib="bootstrap"
|
|
@@ -124,13 +128,14 @@ var g = class extends i {
|
|
|
124
128
|
</div>
|
|
125
129
|
|
|
126
130
|
<!-- Sidebar Navigation Menu -->
|
|
127
|
-
<nav class="sidebar-main" part="sidebar-main" scrollable
|
|
128
|
-
|
|
131
|
+
<nav class="sidebar-main" part="sidebar-main" scrollable
|
|
132
|
+
aria-label=${this.config.mainAriaLabel ?? c}>
|
|
133
|
+
${m(t(this.config.main ?? [], this.config.hasPermission), (e, t) => t, (e) => this.renderItem(e))}
|
|
129
134
|
</nav>
|
|
130
135
|
|
|
131
136
|
<!-- Sidebar Footer -->
|
|
132
137
|
<div class="sidebar-footer" part="sidebar-footer">
|
|
133
|
-
${
|
|
138
|
+
${m(t(this.config.footer ?? [], this.config.hasPermission), (e, t) => t, (e) => this.renderItem(e))}
|
|
134
139
|
</div>
|
|
135
140
|
</aside>
|
|
136
141
|
|
|
@@ -145,16 +150,17 @@ var g = class extends i {
|
|
|
145
150
|
<div class="backdrop" ?hidden="${this.state !== "modal"}"
|
|
146
151
|
@click="${this.handleBackdropClick}"
|
|
147
152
|
></div>
|
|
148
|
-
` :
|
|
153
|
+
` : c;
|
|
149
154
|
}
|
|
150
155
|
renderItem(e) {
|
|
151
|
-
if (!e) return
|
|
156
|
+
if (!e) return c;
|
|
152
157
|
if (e.type === "html") {
|
|
153
158
|
let t = e.render(this.state);
|
|
154
|
-
return typeof t == "string" ?
|
|
159
|
+
return typeof t == "string" ? p(t) : s`${t}`;
|
|
155
160
|
}
|
|
156
|
-
if (e.type === "button") return
|
|
161
|
+
if (e.type === "button") return s`
|
|
157
162
|
<u-sidebar-button
|
|
163
|
+
id=${h(e.id)}
|
|
158
164
|
?compact=${this.state === "slim"}
|
|
159
165
|
.icon="${e.icon}"
|
|
160
166
|
.lib="${e.lib}"
|
|
@@ -165,7 +171,7 @@ var g = class extends i {
|
|
|
165
171
|
`;
|
|
166
172
|
if (e.type === "link") {
|
|
167
173
|
let t = this.isMatchedLink(e.pattern || e.href);
|
|
168
|
-
return
|
|
174
|
+
return s`
|
|
169
175
|
<u-sidebar-link
|
|
170
176
|
?compact=${this.state === "slim"}
|
|
171
177
|
?selected=${t}
|
|
@@ -180,18 +186,18 @@ var g = class extends i {
|
|
|
180
186
|
></u-sidebar-link>
|
|
181
187
|
`;
|
|
182
188
|
}
|
|
183
|
-
if (e.type === "section") return
|
|
189
|
+
if (e.type === "section") return s`
|
|
184
190
|
<u-sidebar-section
|
|
185
191
|
?compact=${this.state === "slim"}
|
|
186
192
|
.mainTitle="${e.title}"
|
|
187
193
|
.subTitle="${e.subTitle}"
|
|
188
194
|
.styles="${e.styles}">
|
|
189
|
-
${
|
|
195
|
+
${m(e.items, (e, t) => t, (e) => this.renderItem(e))}
|
|
190
196
|
</u-sidebar-section>
|
|
191
197
|
`;
|
|
192
198
|
if (e.type === "group") {
|
|
193
199
|
let t = e.items.some((e) => this.isMatchedLink(e.pattern || e.href));
|
|
194
|
-
return
|
|
200
|
+
return s`
|
|
195
201
|
<u-sidebar-group
|
|
196
202
|
?compact=${this.state === "slim"}
|
|
197
203
|
?selected=${t}
|
|
@@ -200,15 +206,15 @@ var g = class extends i {
|
|
|
200
206
|
.lib="${e.lib}"
|
|
201
207
|
.label="${e.label}"
|
|
202
208
|
.styles="${e.styles}">
|
|
203
|
-
${
|
|
209
|
+
${m(e.items, (e, t) => t, (e) => this.renderItem(e))}
|
|
204
210
|
</u-sidebar-group>
|
|
205
211
|
`;
|
|
206
212
|
}
|
|
207
|
-
return
|
|
213
|
+
return c;
|
|
208
214
|
}
|
|
209
215
|
renderLogo() {
|
|
210
216
|
let e = this.config?.logo;
|
|
211
|
-
if (!e || typeof e == "string") return
|
|
217
|
+
if (!e || typeof e == "string") return s`
|
|
212
218
|
<u-icon class="logo"
|
|
213
219
|
.name="${e}"
|
|
214
220
|
@click=${this.handleBrandLogoClick()}
|
|
@@ -216,13 +222,13 @@ var g = class extends i {
|
|
|
216
222
|
`;
|
|
217
223
|
if (typeof e == "function") {
|
|
218
224
|
let t = e(this.state);
|
|
219
|
-
return
|
|
225
|
+
return s`
|
|
220
226
|
<span class="logo" @click=${this.handleBrandLogoClick()}>
|
|
221
|
-
${typeof t == "string" ?
|
|
227
|
+
${typeof t == "string" ? p(t) : t}
|
|
222
228
|
</span>
|
|
223
229
|
`;
|
|
224
230
|
}
|
|
225
|
-
return
|
|
231
|
+
return s`
|
|
226
232
|
<img class="logo"
|
|
227
233
|
src="${e.src}"
|
|
228
234
|
alt="${e.alt ?? ""}"
|
|
@@ -231,9 +237,9 @@ var g = class extends i {
|
|
|
231
237
|
`;
|
|
232
238
|
}
|
|
233
239
|
};
|
|
234
|
-
r([
|
|
240
|
+
r([u({
|
|
235
241
|
type: String,
|
|
236
242
|
reflect: !0
|
|
237
|
-
}), n("design:type", Object)],
|
|
243
|
+
}), n("design:type", Object)], v.prototype, "state", void 0), r([u({ type: Object }), n("design:type", Object)], v.prototype, "config", void 0), r([u({ type: String }), n("design:type", Object)], v.prototype, "locale", void 0), r([d("u-progress-bar"), n("design:type", g === void 0 ? Object : g)], v.prototype, "progressBarEl", void 0), r([f(), n("design:type", Object)], v.prototype, "context", void 0), v = r([l("u-sidebar-layout")], v);
|
|
238
244
|
//#endregion
|
|
239
|
-
export {
|
|
245
|
+
export { v as SidebarLayout };
|
|
@@ -42,6 +42,13 @@ export interface SidebarLayoutConfig {
|
|
|
42
42
|
main?: SidebarItem[];
|
|
43
43
|
/** 하단(footer)에 고정해서 렌더할 항목들 */
|
|
44
44
|
footer?: SidebarItem[];
|
|
45
|
+
/**
|
|
46
|
+
* 메인 내비게이션(`<nav class="sidebar-main">`)의 접근 가능한 이름. 지정하면
|
|
47
|
+
* `aria-label`로 반영돼 스크린리더가 랜드마크를 "주 메뉴" 같은 이름으로 발표한다.
|
|
48
|
+
* `title`은 사이드바 헤더에 표시되는 브랜드 텍스트일 뿐 이 `<nav>`와 연결되지 않는다 —
|
|
49
|
+
* 별개 값이다. 미지정 시 종전과 동일하게 랜드마크 이름이 없다(breaking 아님).
|
|
50
|
+
*/
|
|
51
|
+
mainAriaLabel?: string;
|
|
45
52
|
/**
|
|
46
53
|
* 메뉴 항목 권한 필터 판정. 지정하면 `requirePermission`/`requireAnyPermission` 를 만족하지
|
|
47
54
|
* 않는 항목을 숨기고, 항목이 모두 걸러진 section/group 은 통째로 숨긴다.
|
package/dist/react.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { default as React } from 'react';
|
|
|
2
2
|
import { EventName } from '@lit/react';
|
|
3
3
|
import { SidebarLayout as SidebarLayoutElement } from './layouts/SidebarLayout.js';
|
|
4
4
|
import { Wizard as WizardElement, WizardStepChangeDetail } from './components/Wizard.js';
|
|
5
|
+
export { ScreenObserver } from './internals/ScreenObserver.js';
|
|
6
|
+
export type { ScreenSize, ScreenObserverConfig, ScreenResizeEvent } from './internals/ScreenObserver.js';
|
|
5
7
|
/**
|
|
6
8
|
* React wrapper for `<u-sidebar-layout>`. `config` is an `@property({ type: Object })` —
|
|
7
9
|
* a raw custom element handles that correctly under React 19 (property assignment) but not
|
package/dist/react.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import n from "
|
|
4
|
-
import
|
|
1
|
+
import { ScreenObserver as e } from "./internals/ScreenObserver.js";
|
|
2
|
+
import { Wizard as t } from "./components/Wizard.js";
|
|
3
|
+
import { SidebarLayout as n } from "./layouts/SidebarLayout.js";
|
|
4
|
+
import r from "react";
|
|
5
|
+
import { createComponent as i } from "@lit/react";
|
|
5
6
|
//#region src/react.ts
|
|
6
|
-
var
|
|
7
|
-
react:
|
|
7
|
+
var a = i({
|
|
8
|
+
react: r,
|
|
8
9
|
tagName: "u-sidebar-layout",
|
|
9
|
-
elementClass:
|
|
10
|
+
elementClass: n,
|
|
10
11
|
events: {}
|
|
11
|
-
}),
|
|
12
|
-
react:
|
|
12
|
+
}), o = i({
|
|
13
|
+
react: r,
|
|
13
14
|
tagName: "u-wizard",
|
|
14
|
-
elementClass:
|
|
15
|
+
elementClass: t,
|
|
15
16
|
events: { onStepChange: "step-change" }
|
|
16
17
|
});
|
|
17
18
|
//#endregion
|
|
18
|
-
export {
|
|
19
|
+
export { e as ScreenObserver, a as SidebarLayout, o as Wizard };
|
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@ and those are different states of the business. So the component owns the rule.
|
|
|
39
39
|
| `size` | `'default'\|'lg'` | `'default'` | ✓ | `'lg'` renders the value at the `title` type-scale step — for dashboard KPI tiles composed inside `u-info-section` |
|
|
40
40
|
| `trend` | `'up'\|'down'\|'flat'` | — | | Trend direction; renders a trend indicator when set, alongside `trendLabel`; pair with trendLabel for an accessible name — trend alone conveys direction by color only |
|
|
41
41
|
| `trendLabel` | `string` | — | | Trend copy, e.g. `"+12% vs last month"` — wording is the consumer's responsibility |
|
|
42
|
-
| `tone` | `'positive'\|'negative'\|'neutral'` | — | | Explicit tone override; resolves from `trend` when unset (`up→positive`, `down→negative`, `flat`/unset→`neutral`) but always wins over inference |
|
|
42
|
+
| `tone` | `'positive'\|'negative'\|'neutral'` | — | | Explicit tone override; resolves from `trend` when unset (`up→positive`, `down→negative`, `flat`/unset→`neutral`) but always wins over inference. Colors the value text itself, independent of `trend` — a static figure (e.g. a balance due) can be toned `negative` with no trend arrow |
|
|
43
43
|
|
|
44
44
|
⚠ `numeric` earns its keep in **tables**, where columns of figures are compared by eye. On a
|
|
45
45
|
lone field it just pushes the value away from its label.
|