@iyulab/modern-app 0.11.1 → 0.13.0
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 +59 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.142.0 → _@oxc-project_runtime@0.143.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.142.0 → _@oxc-project_runtime@0.143.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/InfoField.d.ts +18 -0
- package/dist/components/InfoField.js +13 -9
- package/dist/components/InfoSection.d.ts +1 -1
- package/dist/components/InfoSection.js +2 -2
- package/dist/components/PageHeader.js +2 -2
- package/dist/components/SidebarButton.js +2 -2
- package/dist/components/SidebarGroup.js +2 -2
- package/dist/components/SidebarLink.d.ts +23 -0
- package/dist/components/SidebarLink.js +8 -4
- package/dist/components/SidebarSection.js +2 -2
- package/dist/internals/StyledElement.js +9 -7
- package/dist/layouts/SidebarLayout.js +4 -2
- package/dist/layouts/filterSidebarItems.js +10 -8
- package/package.json +14 -3
- package/skills/modern-app/references/components/info-field.md +6 -0
- package/skills/modern-app/references/layout.md +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.13.0] - 2026-08-08
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`u-info-field` accepts `format` (`'number' | 'currency' | 'date'`) and `currency`.**
|
|
8
|
+
When set, the value renders through `@iyulab/components`' `formatNumber`/`formatCurrency`/
|
|
9
|
+
`formatDate` instead of a plain `String(value)`, and `format="number"`/`"currency"` implies
|
|
10
|
+
the existing `numeric` (right-aligned, tabular-nums) styling automatically. `currency` has
|
|
11
|
+
no default — omitting it while `format="currency"` degrades to plain number formatting
|
|
12
|
+
rather than throwing. Existing usage without `format` is unaffected.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`@iyulab/components` dependency floor raised to `^1.27.0`** (the feature above needs
|
|
17
|
+
`formatNumber`/`formatCurrency`/`formatDate`, added in that release).
|
|
18
|
+
|
|
19
|
+
## [0.12.0] - 2026-08-07
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`u-info-field` now accepts `value` as a plain HTML attribute**, not just a property binding.
|
|
24
|
+
`value` was declared `attribute: false`, so `<u-info-field value="42">` was silently ignored —
|
|
25
|
+
no error, no warning, the field just stayed blank. Property binding (`.value=${x}`) is
|
|
26
|
+
unaffected and still accepts any type (numbers, dates); the attribute converter only applies
|
|
27
|
+
when the value arrives as a string attribute.
|
|
28
|
+
|
|
29
|
+
- **Sidebar links can point outside the app.** `SidebarLinkConfig` accepted only `href` and could
|
|
30
|
+
not say whether that link was a SPA route. `SidebarLink` rendered a `<u-link>` without passing
|
|
31
|
+
`target` either, so even the one escape the lower layer offered was unreachable from config.
|
|
32
|
+
A same-origin help site placed in the menu had its click intercepted by the router and fell
|
|
33
|
+
through to not-found.
|
|
34
|
+
|
|
35
|
+
Real menus are not all SPA screens: a documentation site, a report endpoint, an admin console
|
|
36
|
+
and a legacy page sit in the same list. `navigate: 'document'` hands the click to the browser;
|
|
37
|
+
`target` is passed through for new-tab links.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
{ type: 'link', icon: 'help', label: 'Help', href: '/help/', navigate: 'document' }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The entry stays an anchor, which is the point — the alternative was a `type: 'button'` with an
|
|
44
|
+
imperative navigation, which loses middle-click and Ctrl+click, address copying, the link role
|
|
45
|
+
for screen readers, and `pattern`-based highlighting, and cannot sit inside a section or group.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **`@iyulab/router` requirement raised to `^0.11.0`.** The sidebar `navigate: 'document'` support
|
|
50
|
+
above needs `<u-link navigate="document">`, added in that release; `^0.10.2` does not resolve to
|
|
51
|
+
it (a 0.x range's minor segment behaves like a major boundary under semver).
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- **`sideEffects` omitted the source-resolved entry barrel.** The allowlist covered the component
|
|
56
|
+
and layout modules but not the barrel that `exports["."]` resolves to. The published artifacts
|
|
57
|
+
were unaffected — the shipped allowlist already covered them — but a consumer resolving this
|
|
58
|
+
package from source (a workspace sibling) could have the barrel elided, dropping the element
|
|
59
|
+
registrations it pulls in. The failure is silent: no error, and unregistered custom elements
|
|
60
|
+
render nothing. The source-form entry points are now declared alongside the artifact ones.
|
|
61
|
+
|
|
3
62
|
## [0.11.1] - 2026-08-04
|
|
4
63
|
|
|
5
64
|
### Fixed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.143.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.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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,6 @@
|
|
|
1
1
|
import { StyledElement } from '../internals/StyledElement.js';
|
|
2
2
|
type ElementParts = 'host' | 'label' | 'value';
|
|
3
|
+
export type InfoFieldFormat = 'number' | 'currency' | 'date';
|
|
3
4
|
/** 값이 "아직 없음"인가 — `0` 과 `false` 는 **값이다**. */
|
|
4
5
|
export declare function isBlank(v: unknown): boolean;
|
|
5
6
|
/**
|
|
@@ -16,6 +17,7 @@ export declare function isBlank(v: unknown): boolean;
|
|
|
16
17
|
* ```html
|
|
17
18
|
* <u-info-field label="부수" .value=${order.quantity} numeric></u-info-field>
|
|
18
19
|
* <u-info-field label="거래처">동서인쇄</u-info-field> <!-- 슬롯이 value 를 이긴다 -->
|
|
20
|
+
* <u-info-field label="합계" format="currency" currency="KRW" .value=${order.total}></u-info-field>
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
23
|
export declare class InfoField extends StyledElement<ElementParts> {
|
|
@@ -25,6 +27,10 @@ export declare class InfoField extends StyledElement<ElementParts> {
|
|
|
25
27
|
/**
|
|
26
28
|
* 값. `null`/`undefined`/빈 문자열이면 `blank` 문구로 대체된다.
|
|
27
29
|
* ⚠`0`·`false` 는 **대체되지 않는다** — 값이기 때문이다.
|
|
30
|
+
* 속성(`value="…"`)과 프로퍼티(`.value=`) 둘 다 받는다 — HTML 속성은 항상 문자열이라
|
|
31
|
+
* `type: String` 변환기가 붙어도 `.value=${order.quantity}` 같은 비-문자열 프로퍼티
|
|
32
|
+
* 바인딩은 그대로 통과한다(변환기는 속성 파싱에만 관여한다). 렌더는 `format` 이 없으면
|
|
33
|
+
* 항상 `String(value)`.
|
|
28
34
|
*/
|
|
29
35
|
value?: unknown;
|
|
30
36
|
/** "아직 없음"을 나타낼 문구. */
|
|
@@ -32,9 +38,21 @@ export declare class InfoField extends StyledElement<ElementParts> {
|
|
|
32
38
|
/**
|
|
33
39
|
* 숫자 값 — 우정렬 + 고정폭 숫자(`tabular-nums`).
|
|
34
40
|
* ★자릿수가 세로로 맞아야 크기 비교가 눈으로 된다. LOB 화면은 금액·수량이 절반이다.
|
|
41
|
+
* `format` 이 `'number'`/`'currency'` 면 이 정렬이 자동으로 함의된다 — 따로 켤 필요 없다.
|
|
35
42
|
*/
|
|
36
43
|
numeric: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Renders the value through `@iyulab/components`' `formatNumber`/`formatCurrency`/
|
|
46
|
+
* `formatDate`. When unset (default), falls back to plain `String(value)` as before.
|
|
47
|
+
*/
|
|
48
|
+
format?: InfoFieldFormat;
|
|
49
|
+
/**
|
|
50
|
+
* Currency code to use when `format="currency"` (e.g. `'KRW'`). **No default** — if
|
|
51
|
+
* omitted, degrades to plain number formatting without a currency symbol (does not throw).
|
|
52
|
+
*/
|
|
53
|
+
currency?: string;
|
|
37
54
|
private get hasSlotted();
|
|
55
|
+
private formatValue;
|
|
38
56
|
render(): import('lit-html').TemplateResult<1>;
|
|
39
57
|
}
|
|
40
58
|
declare global {
|
|
@@ -1,14 +1,15 @@
|
|
|
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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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";
|
|
6
6
|
import { customElement as a, property as o } from "lit/decorators.js";
|
|
7
|
+
import { formatCurrency as s, formatDate as c, formatNumber as l } from "@iyulab/components";
|
|
7
8
|
//#region src/components/InfoField.ts
|
|
8
|
-
function
|
|
9
|
+
function u(e) {
|
|
9
10
|
return e == null || typeof e == "string" && e.trim() === "";
|
|
10
11
|
}
|
|
11
|
-
var
|
|
12
|
+
var d = class extends n {
|
|
12
13
|
constructor(...e) {
|
|
13
14
|
super(...e), this.label = "", this.blank = "—", this.numeric = !1;
|
|
14
15
|
}
|
|
@@ -18,16 +19,19 @@ var c = class extends n {
|
|
|
18
19
|
get hasSlotted() {
|
|
19
20
|
return this.childNodes.length > 0 && [...this.childNodes].some((e) => e.nodeType !== Node.TEXT_NODE || (e.textContent ?? "").trim() !== "");
|
|
20
21
|
}
|
|
22
|
+
formatValue() {
|
|
23
|
+
return this.format === "currency" ? this.currency ? s(Number(this.value), this.currency) : l(Number(this.value)) : this.format === "number" ? l(Number(this.value)) : this.format === "date" ? c(this.value) : String(this.value);
|
|
24
|
+
}
|
|
21
25
|
render() {
|
|
22
|
-
let e = !this.hasSlotted &&
|
|
26
|
+
let e = !this.hasSlotted && u(this.value), t = this.numeric || this.format === "number" || this.format === "currency";
|
|
23
27
|
return i`
|
|
24
28
|
<div class="label" part="label">${this.label}</div>
|
|
25
|
-
<div class="value ${
|
|
26
|
-
${this.hasSlotted ? i`<slot></slot>` : e ? this.blank :
|
|
29
|
+
<div class="value ${t ? "numeric" : ""} ${e ? "blank" : ""}" part="value">
|
|
30
|
+
${this.hasSlotted ? i`<slot></slot>` : e ? this.blank : this.formatValue()}
|
|
27
31
|
</div>
|
|
28
32
|
`;
|
|
29
33
|
}
|
|
30
34
|
};
|
|
31
|
-
t([o({ type: String }), e("design:type", Object)],
|
|
35
|
+
t([o({ type: String }), e("design:type", Object)], d.prototype, "label", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "value", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "blank", void 0), t([o({ type: Boolean }), e("design:type", Object)], d.prototype, "numeric", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "format", void 0), t([o({ type: String }), e("design:type", String)], d.prototype, "currency", void 0), d = t([a("u-info-field")], d);
|
|
32
36
|
//#endregion
|
|
33
|
-
export {
|
|
37
|
+
export { d as InfoField, u as isBlank };
|
|
@@ -10,7 +10,7 @@ type ElementParts = 'host' | 'grid';
|
|
|
10
10
|
*
|
|
11
11
|
* ```html
|
|
12
12
|
* <u-info-section>
|
|
13
|
-
* <u-info-field label="파트" value
|
|
13
|
+
* <u-info-field label="파트" .value=${'일반'}></u-info-field>
|
|
14
14
|
* <u-info-field label="부수" .value=${0} numeric></u-info-field>
|
|
15
15
|
* </u-info-section>
|
|
16
16
|
* ```
|
|
@@ -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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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";
|
|
@@ -10,6 +10,25 @@ export interface SidebarLinkConfig extends SidebarPermissionGuard {
|
|
|
10
10
|
href: string;
|
|
11
11
|
pattern?: string | URLPattern;
|
|
12
12
|
styles?: StyleMap<ElementParts>;
|
|
13
|
+
/**
|
|
14
|
+
* 라우터가 가로채지 않고 브라우저의 문서 이동에 맡긴다 — 같은 오리진의 비-SPA 경로용.
|
|
15
|
+
*
|
|
16
|
+
* 실무 앱의 메뉴에는 SPA 화면만 서지 않는다: 도움말/문서 사이트, 리포트 출력 엔드포인트,
|
|
17
|
+
* 관리 콘솔, 레거시 페이지가 같은 목록에 선다. 종전에는 그것을 **표현할 수 없어서**
|
|
18
|
+
* 메뉴에 걸면 라우터가 클릭을 가로채 not-found 로 떨어졌다.
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* { type: 'link', label: '도움말', href: '/help/', navigate: 'document' }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
navigate?: 'router' | 'document';
|
|
25
|
+
/**
|
|
26
|
+
* 앵커 `target`. 새 탭으로 열 때 쓴다.
|
|
27
|
+
*
|
|
28
|
+
* ⚠**`navigate` 를 대신하지 못한다** — `_blank` 는 **새 탭을 강제**하므로 「같은 탭에서
|
|
29
|
+
* 다른 문서로」를 표현할 수 없다. 그것이 종전에 유일한 탈출구였고, 그래서 부족했다.
|
|
30
|
+
*/
|
|
31
|
+
target?: '_self' | '_blank';
|
|
13
32
|
}
|
|
14
33
|
/**
|
|
15
34
|
* SidebarLink 컴포넌트는 계층형 네비게이션 아이템을 표시합니다.
|
|
@@ -29,6 +48,10 @@ export declare class SidebarLink extends StyledElement<ElementParts> {
|
|
|
29
48
|
href?: string;
|
|
30
49
|
/** 네비게이션 패턴 매칭 */
|
|
31
50
|
pattern?: string | URLPattern;
|
|
51
|
+
/** 라우터가 가로채지 않고 브라우저 문서 이동에 맡긴다 (같은 오리진의 비-SPA 경로) */
|
|
52
|
+
navigate?: 'router' | 'document';
|
|
53
|
+
/** 앵커 target — 새 탭으로 열 때 */
|
|
54
|
+
target?: '_self' | '_blank';
|
|
32
55
|
render(): import('lit-html').TemplateResult<1>;
|
|
33
56
|
}
|
|
34
57
|
export {};
|
|
@@ -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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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";
|
|
@@ -16,7 +16,11 @@ var c = class extends n {
|
|
|
16
16
|
}
|
|
17
17
|
render() {
|
|
18
18
|
return a`
|
|
19
|
-
<u-link
|
|
19
|
+
<u-link
|
|
20
|
+
.href=${this.href || "#"}
|
|
21
|
+
.navigate=${this.navigate}
|
|
22
|
+
.target=${this.target}
|
|
23
|
+
>
|
|
20
24
|
<div class="container" part="base" ?compact=${this.compact}>
|
|
21
25
|
<u-icon part="icon"
|
|
22
26
|
.name=${this.icon}
|
|
@@ -33,6 +37,6 @@ var c = class extends n {
|
|
|
33
37
|
t([s({
|
|
34
38
|
type: Boolean,
|
|
35
39
|
reflect: !0
|
|
36
|
-
}), e("design:type", Object)], c.prototype, "selected", void 0), t([s({ type: Boolean }), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "href", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "pattern", void 0), c = t([o("u-sidebar-link")], c);
|
|
40
|
+
}), e("design:type", Object)], c.prototype, "selected", void 0), t([s({ type: Boolean }), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "href", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "pattern", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "navigate", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "target", void 0), c = t([o("u-sidebar-link")], c);
|
|
37
41
|
//#endregion
|
|
38
42
|
export { c 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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.143.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
|
|
@@ -12,11 +12,13 @@ var i = class extends r {
|
|
|
12
12
|
}
|
|
13
13
|
applyToParts(e) {
|
|
14
14
|
let t = Object.entries(e);
|
|
15
|
-
for (let [e, n] of t) if (n)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
for (let [e, n] of t) if (n) {
|
|
16
|
+
if (e === "host") this.assignToObject(this, n);
|
|
17
|
+
else {
|
|
18
|
+
let t = this.renderRoot?.querySelector(`[part="${String(e)}"]`);
|
|
19
|
+
if (!t) continue;
|
|
20
|
+
this.assignToObject(t, n);
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
assignToObject(e, t) {
|
|
@@ -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.
|
|
4
|
-
import r from "../_virtual/_@oxc-project_runtime@0.
|
|
3
|
+
import n from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.js";
|
|
4
|
+
import r from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
5
5
|
import { StyledElement as i } from "../internals/StyledElement.js";
|
|
6
6
|
import "../components/SidebarSection.js";
|
|
7
7
|
import "../components/SidebarLink.js";
|
|
@@ -172,6 +172,8 @@ var g = class extends i {
|
|
|
172
172
|
.label="${e.label}"
|
|
173
173
|
.href="${e.href}"
|
|
174
174
|
.pattern="${e.pattern}"
|
|
175
|
+
.navigate="${e.navigate}"
|
|
176
|
+
.target="${e.target}"
|
|
175
177
|
.styles="${e.styles}"
|
|
176
178
|
></u-sidebar-link>
|
|
177
179
|
`;
|
|
@@ -5,14 +5,16 @@ function e(e, t) {
|
|
|
5
5
|
function t(n, r) {
|
|
6
6
|
if (!r) return n;
|
|
7
7
|
let i = r, a = [];
|
|
8
|
-
for (let r of n) if (r && e(r, i))
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
for (let r of n) if (r && e(r, i)) {
|
|
9
|
+
if (r.type === "section" || r.type === "group") {
|
|
10
|
+
let e = t(r.items, i);
|
|
11
|
+
if (e.length === 0) continue;
|
|
12
|
+
a.push({
|
|
13
|
+
...r,
|
|
14
|
+
items: e
|
|
15
|
+
});
|
|
16
|
+
} else a.push(r);
|
|
17
|
+
}
|
|
16
18
|
return a;
|
|
17
19
|
}
|
|
18
20
|
//#endregion
|
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.
|
|
4
|
+
"version": "0.13.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iyulab",
|
|
7
7
|
"web-framework",
|
|
@@ -23,6 +23,17 @@
|
|
|
23
23
|
],
|
|
24
24
|
"type": "module",
|
|
25
25
|
"types": "dist/index.d.ts",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20"
|
|
28
|
+
},
|
|
29
|
+
"sideEffects": [
|
|
30
|
+
"./dist/components/*.js",
|
|
31
|
+
"./src/components/*.ts",
|
|
32
|
+
"./dist/index.js",
|
|
33
|
+
"./src/index.ts",
|
|
34
|
+
"./dist/layouts/*.js",
|
|
35
|
+
"./src/layouts/*.ts"
|
|
36
|
+
],
|
|
26
37
|
"exports": {
|
|
27
38
|
".": {
|
|
28
39
|
"types": "./dist/index.d.ts",
|
|
@@ -42,8 +53,8 @@
|
|
|
42
53
|
"typecheck": "tsc --noEmit"
|
|
43
54
|
},
|
|
44
55
|
"dependencies": {
|
|
45
|
-
"@iyulab/components": "^1.
|
|
46
|
-
"@iyulab/router": "^0.
|
|
56
|
+
"@iyulab/components": "^1.27.0",
|
|
57
|
+
"@iyulab/router": "^0.11.0",
|
|
47
58
|
"i18next": "^26.3.6",
|
|
48
59
|
"lit": "^3.3.3"
|
|
49
60
|
},
|
|
@@ -34,10 +34,16 @@ and those are different states of the business. So the component owns the rule.
|
|
|
34
34
|
| `value` | `unknown` | — | | Value; property only (`attribute: false`) |
|
|
35
35
|
| `blank` | `string` | `'—'` | | Placeholder for null/undefined/empty — **not** for `0` or `false` |
|
|
36
36
|
| `numeric` | `boolean` | `false` | | Right-align with tabular figures so digits line up vertically |
|
|
37
|
+
| `format` | `'number'\|'currency'\|'date'` | — | | Renders `value` through `@iyulab/components`' `formatNumber`/`formatCurrency`/`formatDate`; unset falls back to plain `String(value)` |
|
|
38
|
+
| `currency` | `string` | — | | Currency code for `format="currency"` (e.g. `'KRW'`); omitted degrades to plain number formatting, does not throw |
|
|
37
39
|
|
|
38
40
|
⚠ `numeric` earns its keep in **tables**, where columns of figures are compared by eye. On a
|
|
39
41
|
lone field it just pushes the value away from its label.
|
|
40
42
|
|
|
43
|
+
```html
|
|
44
|
+
<u-info-field label="Total" format="currency" currency="KRW" .value=${order.total}></u-info-field>
|
|
45
|
+
```
|
|
46
|
+
|
|
41
47
|
## CSS Parts
|
|
42
48
|
|
|
43
49
|
| Part | Description |
|
|
@@ -41,6 +41,10 @@ interface SidebarLinkConfig {
|
|
|
41
41
|
icon?: string;
|
|
42
42
|
/** Override the URL matching pattern. Accepts a string or URLPattern. */
|
|
43
43
|
pattern?: string | URLPattern;
|
|
44
|
+
/** Let the browser navigate instead of the router. For same-origin, non-SPA paths. */
|
|
45
|
+
navigate?: 'router' | 'document';
|
|
46
|
+
/** Anchor target. Use for opening in a new tab. */
|
|
47
|
+
target?: '_self' | '_blank';
|
|
44
48
|
styles?: StyleMap<'host' | 'base' | 'icon' | 'label'>;
|
|
45
49
|
}
|
|
46
50
|
```
|
|
@@ -51,6 +55,22 @@ Example:
|
|
|
51
55
|
{ type: 'link', icon: 'dashboard', label: 'Dashboard', href: '/' }
|
|
52
56
|
```
|
|
53
57
|
|
|
58
|
+
#### Linking outside the app
|
|
59
|
+
|
|
60
|
+
Not every entry in a real menu is a SPA screen. A help site, a report endpoint, an
|
|
61
|
+
admin console, a legacy page — these sit in the same list. Mark them so the router
|
|
62
|
+
leaves the click alone:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
{ type: 'link', icon: 'help', label: 'Help', href: '/help/', navigate: 'document' }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The entry stays an anchor, which is the point: middle-click and Ctrl+click still open
|
|
69
|
+
a tab, the address is copyable, screen readers announce a link, `pattern`-based
|
|
70
|
+
highlighting still works, and it can live inside a section or group. `target: '_blank'`
|
|
71
|
+
is available too, but it is not a substitute — it forces a new tab, so same-tab
|
|
72
|
+
navigation to another document needs `navigate`.
|
|
73
|
+
|
|
54
74
|
---
|
|
55
75
|
|
|
56
76
|
### `SidebarGroupConfig` — `type: 'group'`
|