@iyulab/router 0.15.1 → 0.15.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 +14 -0
- package/README.md +9 -1
- package/dist/index.d.ts +619 -9
- package/dist/index.js +1 -1
- package/dist/react.d.ts +170 -9
- package/dist/react.js +1 -1
- package/dist/{share-Cwn-vX3y.js → share-DxyaaBox.js} +11 -1
- package/package.json +3 -2
- package/skills/iyulab-router/references/components.md +9 -1
- package/dist/Router.d.ts +0 -41
- package/dist/components/UErrorPage.d.ts +0 -30
- package/dist/components/ULink.d.ts +0 -93
- package/dist/components/UOutlet.d.ts +0 -47
- package/dist/internals/RouteTracker.d.ts +0 -22
- package/dist/internals/crypto-helpers.d.ts +0 -8
- package/dist/internals/element-helpers.d.ts +0 -36
- package/dist/internals/route-helpers.d.ts +0 -21
- package/dist/internals/url-helpers.d.ts +0 -38
- package/dist/types/NavigateOptions.d.ts +0 -25
- package/dist/types/RouteConfig.d.ts +0 -151
- package/dist/types/RouteContext.d.ts +0 -85
- package/dist/types/RouteError.d.ts +0 -52
- package/dist/types/RouteEvent.d.ts +0 -54
- package/dist/types/RouterConfig.d.ts +0 -52
package/dist/react.d.ts
CHANGED
|
@@ -1,11 +1,172 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { CSSResult } from 'lit';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
import { PropertyValues } from 'lit';
|
|
4
|
+
import { ReactWebComponent } from '@lit/react';
|
|
5
|
+
import { TemplateResult } from 'lit-html';
|
|
6
|
+
|
|
7
|
+
/** 렌더링 옵션 */
|
|
8
|
+
declare interface RenderOption {
|
|
9
|
+
/** 교차 렌더링 방지 ID — 어느 라우트의 콘텐츠인가 */
|
|
10
|
+
id?: string;
|
|
11
|
+
/**
|
|
12
|
+
* 라우트의 식별 키(`RouteConfig.key` 의 결과). 같은 라우트 + 같은 키면 기존 콘텐츠를
|
|
13
|
+
* 유지한 채 제자리 갱신하고, 바뀌면 내리고 새로 마운트한다.
|
|
14
|
+
*/
|
|
15
|
+
key?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `u-link` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ULink: ReactWebComponent<ULink_2, {}>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* - 클라이언트 라우팅을 지원하는 링크 엘리먼트입니다.
|
|
25
|
+
* - 내부 링크는 클라이언트 라우팅을 수행하고, 외부 링크는 브라우저 기본 네비게이션을 사용합니다.
|
|
26
|
+
* - Ctrl/Meta/Shift/Alt, 중클릭/우클릭 등은 브라우저 기본 동작(새 탭, 컨텍스트 메뉴 등)을 그대로 유지합니다.
|
|
27
|
+
*/
|
|
28
|
+
declare class ULink_2 extends LitElement {
|
|
29
|
+
/** 외부 링크 여부 */
|
|
30
|
+
private isExternal;
|
|
31
|
+
/**
|
|
32
|
+
* 링크 대상 target 속성
|
|
33
|
+
*
|
|
34
|
+
* - `_self`: 현재 창에서 링크 열기 (기본값)
|
|
35
|
+
* - `_blank`: 새 탭/창에서 링크 열기
|
|
36
|
+
* - `_parent`: 부모 프레임에서 링크 열기
|
|
37
|
+
* - `_top`: 최상위 프레임에서 링크 열기
|
|
38
|
+
*/
|
|
39
|
+
target?: string;
|
|
40
|
+
/**
|
|
41
|
+
* 링크 관계 rel 속성
|
|
42
|
+
*
|
|
43
|
+
* - `noopener`: target이 _blank인 경우 보안 강화 (window.opener 차단)
|
|
44
|
+
* - `noreferrer`: target이 _blank인 경우 보안 강화 + Referer 헤더 제거
|
|
45
|
+
* - `external`: 외부 링크임을 명시 (SEO/접근성에 도움)
|
|
46
|
+
* - `nofollow`: 검색 엔진이 링크를 따라가지 않도록 지시 (SEO에 영향)
|
|
47
|
+
* - 그 외 rel 값도 그대로 전달됩니다.
|
|
48
|
+
*/
|
|
49
|
+
rel?: string;
|
|
50
|
+
/**
|
|
51
|
+
* 링크 대상 URL, 다음 사항에 따라 SPA 라우팅 또는 브라우저 네비게이션이 결정됩니다.
|
|
52
|
+
*
|
|
53
|
+
* - 속성을 정의하지 않으면 설정에서 지정한 `basepath`로 SPA 라우팅합니다.
|
|
54
|
+
* - http(s)로 시작하면 외부 링크로 간주하고 브라우저 네비게이션을 사용합니다.
|
|
55
|
+
* - 절대경로(/...)의 경우 `basepath`로 시작하면 SPA 라우팅합니다, 이외 브라우저 네비게이션을 사용합니다.
|
|
56
|
+
* - 상대경로는 (basepath + 상대경로)로 결합하여 SPA 라우팅합니다.
|
|
57
|
+
* - ?로 시작하면 현재 경로에 쿼리스트링을 추가하여 SPA 라우팅합니다.
|
|
58
|
+
* - #으로 시작하면 브라우저 기본 동작을 사용합니다.
|
|
59
|
+
*/
|
|
60
|
+
href?: string;
|
|
61
|
+
/**
|
|
62
|
+
* 이 링크를 라우터가 처리할지, 브라우저의 문서 이동에 맡길지.
|
|
63
|
+
*
|
|
64
|
+
* - `router`(기본): 종전 동작 그대로 — 같은 오리진이면 SPA 이동, 아니면 브라우저에 맡긴다.
|
|
65
|
+
* - `document`: 라우터가 **가로채지 않는다.** 같은 오리진이지만 SPA 라우트가 아닌 경로
|
|
66
|
+
* (정적 문서 사이트, 서버 렌더 페이지, 파일 다운로드 엔드포인트, 인증 리다이렉트)를 가리킬 때 쓴다.
|
|
67
|
+
*
|
|
68
|
+
* ⚠**「외부 오리진」이 아니라 「다른 문서」다.** 종전에는 이 구분이 **오리진 비교 하나**로만
|
|
69
|
+
* 결정돼서, 같은 오리진의 비-SPA 경로를 가리킬 수단이 없었다 — 라우터가 클릭을 가로채고
|
|
70
|
+
* 등록되지 않은 라우트이므로 화면이 not-found 로 떨어졌다. 빠져나갈 길이 셋뿐이었고
|
|
71
|
+
* (다른 오리진 · `target="_blank"` · `#` 프래그먼트) 셋 다 요구와 다르다:
|
|
72
|
+
* 같은 오리진이어야 하고(쿠키·세션·역방향 프록시), **같은 탭**이어야 하며, 다른 문서다.
|
|
73
|
+
*
|
|
74
|
+
* ```html
|
|
75
|
+
* <u-link href="/help/" navigate="document">Help</u-link>
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* ⚠**자동 판정을 넓히지 않는다.** 「등록된 라우트와 대조해 미등록이면 문서 이동」도 가능하지만
|
|
79
|
+
* 라우트가 늦게 등록되면 판정이 **시점에 의존**하게 된다. 명시 선언이 예측 가능하다.
|
|
80
|
+
*/
|
|
81
|
+
navigate?: "router" | "document";
|
|
82
|
+
connectedCallback(): void;
|
|
83
|
+
disconnectedCallback(): void;
|
|
84
|
+
/**
|
|
85
|
+
* 호스트에 세팅된 `aria-current`/`aria-label`은 실제 접근 가능한(포커스 대상)
|
|
86
|
+
* 엘리먼트가 아니라 — 그 안쪽 shadow DOM 의 네이티브 `<a>`다. 섀도우 경계를
|
|
87
|
+
* 넘지 않으므로 접근성 트리에 자동 반영되지 않는다(실측 — 속성은
|
|
88
|
+
* 붙어 있는데 접근성 트리의 `aria-current`는 계속 비어 있음). `render()`가 이
|
|
89
|
+
* 값을 읽어 내부 `<a>`에 직접 옮긴다.
|
|
90
|
+
*
|
|
91
|
+
* 둘 다 Lit 리액티브 프로퍼티로 선언돼 있지 않아 `observedAttributes`에 없다 —
|
|
92
|
+
* 그 목록에 없는 속성은 `attributeChangedCallback` 자체가 호출되지 않는다
|
|
93
|
+
* (커스텀 엘리먼트 표준 동작). 초기 렌더는 되지만 연결 후 동적 변경은 반영되지
|
|
94
|
+
* 않았다 — 목록에 명시적으로 추가해야 한다.
|
|
95
|
+
*/
|
|
96
|
+
static get observedAttributes(): string[];
|
|
97
|
+
attributeChangedCallback(name: string, old: string | null, value: string | null): void;
|
|
98
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
99
|
+
render(): TemplateResult<1>;
|
|
100
|
+
/** a 태그에 주입할 href 값을 계산합니다. */
|
|
101
|
+
private compute;
|
|
102
|
+
/**
|
|
103
|
+
* 클릭 가로채기 핸들러
|
|
104
|
+
* - 좌클릭(0) + 보조키 없음(ctrl/meta/shift/alt 없음) + target이 _self일 때만 SPA 라우팅 고려
|
|
105
|
+
* - 그 외(중클릭/우클릭/보조키/target=_blank 등)는 브라우저 기본 동작 유지
|
|
106
|
+
*/
|
|
107
|
+
private handleClick;
|
|
108
|
+
/** 클라이언트 라우팅을 위해 popstate 이벤트를 발생시킵니다. */
|
|
109
|
+
private dispatchPopstate;
|
|
110
|
+
/** basepath를 state에서 꺼내는 헬퍼 */
|
|
111
|
+
private getBasepath;
|
|
112
|
+
static styles: CSSResult;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* `u-outlet` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
117
|
+
*/
|
|
118
|
+
export declare const UOutlet: ReactWebComponent<UOutlet_2, {}>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* LitElement 또는 React 컴포넌트를 렌더링해주는 웹컴포넌트 입니다.
|
|
122
|
+
*/
|
|
123
|
+
declare class UOutlet_2 extends HTMLElement {
|
|
124
|
+
/** 교차 렌더링 방지 id */
|
|
125
|
+
private routeId?;
|
|
126
|
+
/** 마지막으로 렌더한 라우트의 식별 키 */
|
|
127
|
+
private routeKey?;
|
|
128
|
+
/** 마운트된 콘텐츠의 종류 */
|
|
129
|
+
private kind?;
|
|
130
|
+
/** 실제 렌더링 컨텐츠 */
|
|
131
|
+
private root?;
|
|
132
|
+
/** 진행 중인 render — 다음 render 는 이것이 끝난 뒤 판정한다 */
|
|
133
|
+
private pending?;
|
|
134
|
+
connectedCallback(): void;
|
|
135
|
+
/**
|
|
136
|
+
* 주어진 렌더링 옵션에 따라 컨텐츠를 렌더링합니다.
|
|
137
|
+
*
|
|
138
|
+
* 같은 라우트(`id`)에 같은 키(`key`)로 다시 불리면 **제자리 갱신**한다 — Lit 템플릿은
|
|
139
|
+
* 같은 파트에 다시 렌더(요소·상태 유지, 바인딩만 갱신), React 엘리먼트는 같은 root 에 다시
|
|
140
|
+
* 렌더(컴포넌트 상태 유지), `HTMLElement` 는 기존 인스턴스를 그대로 둔다. 매번 `reset()`
|
|
141
|
+
* 을 먼저 부르던 종전 동작이 «쿼리스트링만 바뀌어도 페이지가 재마운트되는» 원인이었다
|
|
142
|
+
* (Lit 의 `render` 도 React 의 `root.render` 도 같은 컨테이너에 다시 부르면 조정한다).
|
|
143
|
+
*/
|
|
144
|
+
render(value: unknown, options?: RenderOption): Promise<void>;
|
|
145
|
+
private mount;
|
|
146
|
+
/**
|
|
147
|
+
* 기존 DOM을 삭제하여, 초기 상태로 되돌립니다.
|
|
148
|
+
*/
|
|
149
|
+
reset(): void;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export { }
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
declare global {
|
|
156
|
+
interface HTMLElementTagNameMap {
|
|
157
|
+
'u-outlet': UOutlet;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
4
162
|
/**
|
|
5
|
-
*
|
|
163
|
+
* 전역 WindowEventMap에 라우터 이벤트 타입
|
|
6
164
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
165
|
+
declare global {
|
|
166
|
+
interface WindowEventMap {
|
|
167
|
+
'route-begin': RouteBeginEvent;
|
|
168
|
+
'route-progress': RouteProgressEvent;
|
|
169
|
+
'route-done': RouteDoneEvent;
|
|
170
|
+
'route-error': RouteErrorEvent;
|
|
171
|
+
}
|
|
172
|
+
}
|
package/dist/react.js
CHANGED
|
@@ -58,6 +58,16 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
|
|
58
58
|
* 🔴**소비자가 아웃렛을 «줄이려면» `height` 만으로는 부족하고 `min-height: 0` 이 함께 필요하다**
|
|
59
59
|
* — 0.14.0 대비 유일한 계약 추가이며 README·CHANGELOG·참조 문서에 적혀 있다.
|
|
60
60
|
*
|
|
61
|
+
* ## 가로 — 열 트랙은 아웃렛 폭에 묶는다 (0.15.2)
|
|
62
|
+
*
|
|
63
|
+
* 🔴**grid 는 세로만이 아니라 가로에도 격자 규칙을 들여온다.** 열 트랙을 선언하지 않으면 암묵적
|
|
64
|
+
* 열은 `auto` 이고, 격자 항목(라우트 화면)의 기본 `min-width: auto` 가 자손의 최소 내용 폭을
|
|
65
|
+
* 트랙까지 올려 보낸다 — 넓은 표가 `overflow-x: auto` 상자 안에 있어도 라우트 화면 전체가 표
|
|
66
|
+
* 폭만큼 늘어나 아웃렛을 넘친다(소비자 실측: 아웃렛 972 · 화면 1,945 · 툴바 끝 버튼이 뷰포트 밖).
|
|
67
|
+
* `block` 이던 시절(0.14.x)에는 없던 부작용이고, `display` 를 바꾼 우리 몫이다.
|
|
68
|
+
* ✅`minmax(0, 1fr)` — 최소 0 이라 내용이 트랙을 밀어 넓히지 못하고, `1fr` 이라 좁은 내용이어도
|
|
69
|
+
* 아웃렛 폭을 채운다(격자 항목의 `min-width: 0` 을 대신 줄 수는 없다 — 항목은 소비자의 요소다).
|
|
70
|
+
*
|
|
61
71
|
* ## 인쇄 매체 — `block` 으로 돌아간다 (0.15.1)
|
|
62
72
|
*
|
|
63
73
|
* 🔴**grid 는 자기 안에서 여백 접힘을 막는다.** 라우트 화면의 마지막 블록이 `margin-bottom` 을
|
|
@@ -70,7 +80,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
|
|
70
80
|
* `min-height: 100%` 도 0 으로 풀린다. ⇒ 인쇄에서 grid 는 **여백을 가두기만** 한다.
|
|
71
81
|
* ⚠같은 `:where()` 라 특이도 0 그대로다 — 소비자 규칙은 인쇄에서도 `!important` 없이 이긴다.
|
|
72
82
|
*/
|
|
73
|
-
var OUTLET_DISPLAY_CSS = [":where(u-outlet) { display: grid; min-height: 100%; }", "@media print { :where(u-outlet) { display: block; } }"].join("\n");
|
|
83
|
+
var OUTLET_DISPLAY_CSS = [":where(u-outlet) { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 100%; }", "@media print { :where(u-outlet) { display: block; } }"].join("\n");
|
|
74
84
|
/** 시트를 이미 채택한 트리 — 같은 트리에 두 번 넣지 않는다. */
|
|
75
85
|
var styledRoots = /* @__PURE__ */ new WeakSet();
|
|
76
86
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/router",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2",
|
|
4
4
|
"description": "A modern client-side router for web applications with support for Lit and React components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lit",
|
|
@@ -71,10 +71,11 @@
|
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@
|
|
74
|
+
"@microsoft/api-extractor": "^7.58.8",
|
|
75
75
|
"@types/node": "^26.1.1",
|
|
76
76
|
"@types/react": "^19.2.17",
|
|
77
77
|
"@types/react-dom": "^19.2.3",
|
|
78
|
+
"@vitest/browser-playwright": "^5.0.0",
|
|
78
79
|
"happy-dom": "^20.10.6",
|
|
79
80
|
"react": "^19.2.8",
|
|
80
81
|
"react-dom": "^19.2.8",
|
|
@@ -46,7 +46,7 @@ rules on whichever tree it is connected to (the document, or the shadow root if
|
|
|
46
46
|
one):
|
|
47
47
|
|
|
48
48
|
```css
|
|
49
|
-
:where(u-outlet) { display: grid; min-height: 100%; }
|
|
49
|
+
:where(u-outlet) { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 100%; }
|
|
50
50
|
@media print { :where(u-outlet) { display: block; } }
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -78,6 +78,13 @@ The rule deliberately omits `align-content`; it relies on the initial `normal`.
|
|
|
78
78
|
When the parent's own height is `auto`, `min-height: 100%` resolves to `auto` too, so ordinary
|
|
79
79
|
document flow is unaffected.
|
|
80
80
|
|
|
81
|
+
The column track is bound to the outlet's width with `minmax(0, 1fr)`. Without it the implicit
|
|
82
|
+
column is `auto`, and a grid item's default `min-width: auto` passes its content's minimum width up
|
|
83
|
+
to the track — so a wide table inside a screen widened the whole screen past the outlet, even when
|
|
84
|
+
the table sat in an `overflow-x: auto` box, and anything aligned to the screen's right edge (a
|
|
85
|
+
toolbar's last button) ended up off screen. With the track bound, the screen is exactly as wide as
|
|
86
|
+
the outlet, a narrow screen still fills it, and wide content scrolls inside its own box.
|
|
87
|
+
|
|
81
88
|
### Printing
|
|
82
89
|
|
|
83
90
|
In print media the outlet is a plain block box instead of a grid container. A grid container is
|
|
@@ -99,6 +106,7 @@ application writes wins, regardless of sheet order and without `!important`:
|
|
|
99
106
|
|
|
100
107
|
```css
|
|
101
108
|
u-outlet { display: flex; } /* wins */
|
|
109
|
+
u-outlet { grid-template-columns: auto; } /* restores the 0.15.1 column track */
|
|
102
110
|
u-outlet { display: contents; } /* remove the box entirely */
|
|
103
111
|
u-outlet { display: block; height: 100%; } /* restores the 0.14.0 behavior */
|
|
104
112
|
u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
|
package/dist/Router.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { RouteContext } from './types/RouteContext.js';
|
|
2
|
-
import { RouterConfig } from './types/RouterConfig.js';
|
|
3
|
-
import { RouteConfig } from './types/RouteConfig.js';
|
|
4
|
-
import { NavigateOptions } from './types/NavigateOptions.js';
|
|
5
|
-
/**
|
|
6
|
-
* `lit-element`, `react`를 지원하는 SPA 클라이언트 라우터 객체입니다.
|
|
7
|
-
*/
|
|
8
|
-
export declare class Router {
|
|
9
|
-
private readonly _rootElement;
|
|
10
|
-
private readonly _basepath;
|
|
11
|
-
private readonly _routes;
|
|
12
|
-
private readonly _fallback?;
|
|
13
|
-
private readonly _enter?;
|
|
14
|
-
private readonly _tracker;
|
|
15
|
-
/** 현재 라우팅 요청 ID */
|
|
16
|
-
private _requestID?;
|
|
17
|
-
/** 현재 라우팅 정보 */
|
|
18
|
-
private _context?;
|
|
19
|
-
constructor(config: RouterConfig);
|
|
20
|
-
/** 객체를 정리하고 이벤트 리스너를 제거합니다. */
|
|
21
|
-
destroy(): void;
|
|
22
|
-
/** 라우터의 기본 경로 반환 */
|
|
23
|
-
get basepath(): string;
|
|
24
|
-
/** 등록된 라우트 정보 반환 */
|
|
25
|
-
get routes(): RouteConfig[];
|
|
26
|
-
/** 현재 라우팅 정보 반환 */
|
|
27
|
-
get context(): RouteContext | undefined;
|
|
28
|
-
/**
|
|
29
|
-
* 지정한 경로의 클라이언트 라우팅을 수행합니다. 상대경로일 경우 basepath와 조합되어 이동합니다.
|
|
30
|
-
* @param href 이동할 경로
|
|
31
|
-
* @param options 네비게이션 옵션
|
|
32
|
-
* @param routes (internal) 호출자가 이미 계산한 라우트 매칭 결과가 있으면 재사용합니다.
|
|
33
|
-
* `handleRootElementClick`이 가로채기 여부 판단을 위해 미리 계산한 결과를 전달해
|
|
34
|
-
* 동일 pathname에 대한 getRoutes 중복 호출을 피하는 용도입니다. 외부에서 사용하지 마세요.
|
|
35
|
-
*/
|
|
36
|
-
go(href: string, options?: NavigateOptions, routes?: RouteConfig[]): Promise<undefined>;
|
|
37
|
-
/** 브라우저 히스토리 이벤트가 발생시 라우팅 처리 */
|
|
38
|
-
private handleWindowPopstate;
|
|
39
|
-
/** 클릭 이벤트에서 라우터로 처리할 앵커를 찾아 클라이언트 라우팅 수행 */
|
|
40
|
-
private handleRootElementClick;
|
|
41
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { LitElement, CSSResult } from 'lit';
|
|
2
|
-
import { RouteError } from '../types/RouteError.js';
|
|
3
|
-
import { TemplateResult } from 'lit-html';
|
|
4
|
-
/**
|
|
5
|
-
* 라우팅 중 발생한 에러 정보를 사용자에게 전달하기 위한 기본 컴포넌트 입니다.
|
|
6
|
-
*
|
|
7
|
-
* `Router`가 `fallback`을 지정하지 않았을 때 내부적으로 그리는 기본 화면이라
|
|
8
|
-
* `src/index.ts`에서 공개 export되지 않는다 — 직접 import해 쓰는 컴포넌트가
|
|
9
|
-
* 아니다. 다만 라우팅 실패 시 실제 DOM에 렌더되므로, 기본 화면의 색만 가볍게
|
|
10
|
-
* 맞추고 싶은 소비자를 위해 세 색상 훅을 남겨 둔다(전체 교체는 `fallback.render`).
|
|
11
|
-
*
|
|
12
|
-
* @cssprop --error-icon-color - 아이콘 색. 기본값 `#4a5568`(다크 `#a0aec0`)
|
|
13
|
-
* @cssprop --error-code-color - 에러 코드 텍스트 색. 기본값 `#1a202c`(다크 `#f7fafc`)
|
|
14
|
-
* @cssprop --error-message-color - 에러 메시지 텍스트 색. 기본값 `#718096`(다크 `#cbd5e0`)
|
|
15
|
-
*
|
|
16
|
-
* ⚠세 값은 아래 `static styles` 의 `:host` 에서 **구체적인 색으로 선언된다** — 지정하지
|
|
17
|
-
* 않으면 주변 색을 상속하는 것이 아니라 위 기본값이 적용된다. 리터럴이므로 이 페이지는
|
|
18
|
-
* 호스트 앱의 디자인 토큰을 따르지 않는다.
|
|
19
|
-
*/
|
|
20
|
-
export declare class UErrorPage extends LitElement {
|
|
21
|
-
constructor(error?: RouteError);
|
|
22
|
-
/** 표시할 에러 정보 */
|
|
23
|
-
error?: RouteError;
|
|
24
|
-
render(): TemplateResult<1>;
|
|
25
|
-
/** 기본 에러 정보 반환 */
|
|
26
|
-
private getDefaultError;
|
|
27
|
-
/** 에러 코드에 따른 기본 아이콘 반환 */
|
|
28
|
-
private getErrorIcon;
|
|
29
|
-
static styles: CSSResult;
|
|
30
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { LitElement, PropertyValues, CSSResult } from 'lit';
|
|
2
|
-
import { TemplateResult } from 'lit-html';
|
|
3
|
-
/**
|
|
4
|
-
* - 클라이언트 라우팅을 지원하는 링크 엘리먼트입니다.
|
|
5
|
-
* - 내부 링크는 클라이언트 라우팅을 수행하고, 외부 링크는 브라우저 기본 네비게이션을 사용합니다.
|
|
6
|
-
* - Ctrl/Meta/Shift/Alt, 중클릭/우클릭 등은 브라우저 기본 동작(새 탭, 컨텍스트 메뉴 등)을 그대로 유지합니다.
|
|
7
|
-
*/
|
|
8
|
-
export declare class ULink extends LitElement {
|
|
9
|
-
/** 외부 링크 여부 */
|
|
10
|
-
private isExternal;
|
|
11
|
-
/**
|
|
12
|
-
* 링크 대상 target 속성
|
|
13
|
-
*
|
|
14
|
-
* - `_self`: 현재 창에서 링크 열기 (기본값)
|
|
15
|
-
* - `_blank`: 새 탭/창에서 링크 열기
|
|
16
|
-
* - `_parent`: 부모 프레임에서 링크 열기
|
|
17
|
-
* - `_top`: 최상위 프레임에서 링크 열기
|
|
18
|
-
*/
|
|
19
|
-
target?: string;
|
|
20
|
-
/**
|
|
21
|
-
* 링크 관계 rel 속성
|
|
22
|
-
*
|
|
23
|
-
* - `noopener`: target이 _blank인 경우 보안 강화 (window.opener 차단)
|
|
24
|
-
* - `noreferrer`: target이 _blank인 경우 보안 강화 + Referer 헤더 제거
|
|
25
|
-
* - `external`: 외부 링크임을 명시 (SEO/접근성에 도움)
|
|
26
|
-
* - `nofollow`: 검색 엔진이 링크를 따라가지 않도록 지시 (SEO에 영향)
|
|
27
|
-
* - 그 외 rel 값도 그대로 전달됩니다.
|
|
28
|
-
*/
|
|
29
|
-
rel?: string;
|
|
30
|
-
/**
|
|
31
|
-
* 링크 대상 URL, 다음 사항에 따라 SPA 라우팅 또는 브라우저 네비게이션이 결정됩니다.
|
|
32
|
-
*
|
|
33
|
-
* - 속성을 정의하지 않으면 설정에서 지정한 `basepath`로 SPA 라우팅합니다.
|
|
34
|
-
* - http(s)로 시작하면 외부 링크로 간주하고 브라우저 네비게이션을 사용합니다.
|
|
35
|
-
* - 절대경로(/...)의 경우 `basepath`로 시작하면 SPA 라우팅합니다, 이외 브라우저 네비게이션을 사용합니다.
|
|
36
|
-
* - 상대경로는 (basepath + 상대경로)로 결합하여 SPA 라우팅합니다.
|
|
37
|
-
* - ?로 시작하면 현재 경로에 쿼리스트링을 추가하여 SPA 라우팅합니다.
|
|
38
|
-
* - #으로 시작하면 브라우저 기본 동작을 사용합니다.
|
|
39
|
-
*/
|
|
40
|
-
href?: string;
|
|
41
|
-
/**
|
|
42
|
-
* 이 링크를 라우터가 처리할지, 브라우저의 문서 이동에 맡길지.
|
|
43
|
-
*
|
|
44
|
-
* - `router`(기본): 종전 동작 그대로 — 같은 오리진이면 SPA 이동, 아니면 브라우저에 맡긴다.
|
|
45
|
-
* - `document`: 라우터가 **가로채지 않는다.** 같은 오리진이지만 SPA 라우트가 아닌 경로
|
|
46
|
-
* (정적 문서 사이트, 서버 렌더 페이지, 파일 다운로드 엔드포인트, 인증 리다이렉트)를 가리킬 때 쓴다.
|
|
47
|
-
*
|
|
48
|
-
* ⚠**「외부 오리진」이 아니라 「다른 문서」다.** 종전에는 이 구분이 **오리진 비교 하나**로만
|
|
49
|
-
* 결정돼서, 같은 오리진의 비-SPA 경로를 가리킬 수단이 없었다 — 라우터가 클릭을 가로채고
|
|
50
|
-
* 등록되지 않은 라우트이므로 화면이 not-found 로 떨어졌다. 빠져나갈 길이 셋뿐이었고
|
|
51
|
-
* (다른 오리진 · `target="_blank"` · `#` 프래그먼트) 셋 다 요구와 다르다:
|
|
52
|
-
* 같은 오리진이어야 하고(쿠키·세션·역방향 프록시), **같은 탭**이어야 하며, 다른 문서다.
|
|
53
|
-
*
|
|
54
|
-
* ```html
|
|
55
|
-
* <u-link href="/help/" navigate="document">Help</u-link>
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* ⚠**자동 판정을 넓히지 않는다.** 「등록된 라우트와 대조해 미등록이면 문서 이동」도 가능하지만
|
|
59
|
-
* 라우트가 늦게 등록되면 판정이 **시점에 의존**하게 된다. 명시 선언이 예측 가능하다.
|
|
60
|
-
*/
|
|
61
|
-
navigate?: "router" | "document";
|
|
62
|
-
connectedCallback(): void;
|
|
63
|
-
disconnectedCallback(): void;
|
|
64
|
-
/**
|
|
65
|
-
* 호스트에 세팅된 `aria-current`/`aria-label`은 실제 접근 가능한(포커스 대상)
|
|
66
|
-
* 엘리먼트가 아니라 — 그 안쪽 shadow DOM 의 네이티브 `<a>`다. 섀도우 경계를
|
|
67
|
-
* 넘지 않으므로 접근성 트리에 자동 반영되지 않는다(실측 — 속성은
|
|
68
|
-
* 붙어 있는데 접근성 트리의 `aria-current`는 계속 비어 있음). `render()`가 이
|
|
69
|
-
* 값을 읽어 내부 `<a>`에 직접 옮긴다.
|
|
70
|
-
*
|
|
71
|
-
* 둘 다 Lit 리액티브 프로퍼티로 선언돼 있지 않아 `observedAttributes`에 없다 —
|
|
72
|
-
* 그 목록에 없는 속성은 `attributeChangedCallback` 자체가 호출되지 않는다
|
|
73
|
-
* (커스텀 엘리먼트 표준 동작). 초기 렌더는 되지만 연결 후 동적 변경은 반영되지
|
|
74
|
-
* 않았다 — 목록에 명시적으로 추가해야 한다.
|
|
75
|
-
*/
|
|
76
|
-
static get observedAttributes(): string[];
|
|
77
|
-
attributeChangedCallback(name: string, old: string | null, value: string | null): void;
|
|
78
|
-
protected willUpdate(changedProperties: PropertyValues): void;
|
|
79
|
-
render(): TemplateResult<1>;
|
|
80
|
-
/** a 태그에 주입할 href 값을 계산합니다. */
|
|
81
|
-
private compute;
|
|
82
|
-
/**
|
|
83
|
-
* 클릭 가로채기 핸들러
|
|
84
|
-
* - 좌클릭(0) + 보조키 없음(ctrl/meta/shift/alt 없음) + target이 _self일 때만 SPA 라우팅 고려
|
|
85
|
-
* - 그 외(중클릭/우클릭/보조키/target=_blank 등)는 브라우저 기본 동작 유지
|
|
86
|
-
*/
|
|
87
|
-
private handleClick;
|
|
88
|
-
/** 클라이언트 라우팅을 위해 popstate 이벤트를 발생시킵니다. */
|
|
89
|
-
private dispatchPopstate;
|
|
90
|
-
/** basepath를 state에서 꺼내는 헬퍼 */
|
|
91
|
-
private getBasepath;
|
|
92
|
-
static styles: CSSResult;
|
|
93
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/** 렌더링 옵션 */
|
|
2
|
-
interface RenderOption {
|
|
3
|
-
/** 교차 렌더링 방지 ID — 어느 라우트의 콘텐츠인가 */
|
|
4
|
-
id?: string;
|
|
5
|
-
/**
|
|
6
|
-
* 라우트의 식별 키(`RouteConfig.key` 의 결과). 같은 라우트 + 같은 키면 기존 콘텐츠를
|
|
7
|
-
* 유지한 채 제자리 갱신하고, 바뀌면 내리고 새로 마운트한다.
|
|
8
|
-
*/
|
|
9
|
-
key?: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* LitElement 또는 React 컴포넌트를 렌더링해주는 웹컴포넌트 입니다.
|
|
13
|
-
*/
|
|
14
|
-
declare class UOutlet extends HTMLElement {
|
|
15
|
-
/** 교차 렌더링 방지 id */
|
|
16
|
-
private routeId?;
|
|
17
|
-
/** 마지막으로 렌더한 라우트의 식별 키 */
|
|
18
|
-
private routeKey?;
|
|
19
|
-
/** 마운트된 콘텐츠의 종류 */
|
|
20
|
-
private kind?;
|
|
21
|
-
/** 실제 렌더링 컨텐츠 */
|
|
22
|
-
private root?;
|
|
23
|
-
/** 진행 중인 render — 다음 render 는 이것이 끝난 뒤 판정한다 */
|
|
24
|
-
private pending?;
|
|
25
|
-
connectedCallback(): void;
|
|
26
|
-
/**
|
|
27
|
-
* 주어진 렌더링 옵션에 따라 컨텐츠를 렌더링합니다.
|
|
28
|
-
*
|
|
29
|
-
* 같은 라우트(`id`)에 같은 키(`key`)로 다시 불리면 **제자리 갱신**한다 — Lit 템플릿은
|
|
30
|
-
* 같은 파트에 다시 렌더(요소·상태 유지, 바인딩만 갱신), React 엘리먼트는 같은 root 에 다시
|
|
31
|
-
* 렌더(컴포넌트 상태 유지), `HTMLElement` 는 기존 인스턴스를 그대로 둔다. 매번 `reset()`
|
|
32
|
-
* 을 먼저 부르던 종전 동작이 «쿼리스트링만 바뀌어도 페이지가 재마운트되는» 원인이었다
|
|
33
|
-
* (Lit 의 `render` 도 React 의 `root.render` 도 같은 컨테이너에 다시 부르면 조정한다).
|
|
34
|
-
*/
|
|
35
|
-
render(value: unknown, options?: RenderOption): Promise<void>;
|
|
36
|
-
private mount;
|
|
37
|
-
/**
|
|
38
|
-
* 기존 DOM을 삭제하여, 초기 상태로 되돌립니다.
|
|
39
|
-
*/
|
|
40
|
-
reset(): void;
|
|
41
|
-
}
|
|
42
|
-
declare global {
|
|
43
|
-
interface HTMLElementTagNameMap {
|
|
44
|
-
'u-outlet': UOutlet;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export { UOutlet };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { RouteConfig } from '../types/RouteConfig.js';
|
|
2
|
-
/**
|
|
3
|
-
* 라우팅 체인 상태를 추적합니다.
|
|
4
|
-
* - 방문한 href를 기록하여 리다이렉트 사이클을 감지합니다.
|
|
5
|
-
* - 이미 실행된 route enter를 기록하여 중복 실행을 방지합니다.
|
|
6
|
-
*/
|
|
7
|
-
export declare class RouteTracker {
|
|
8
|
-
private readonly _history;
|
|
9
|
-
private readonly _processed;
|
|
10
|
-
/** 새 네비게이션 시작 시 상태를 초기화합니다. */
|
|
11
|
-
reset(): void;
|
|
12
|
-
/**
|
|
13
|
-
* href 방문을 기록하고 사이클 여부를 반환합니다.
|
|
14
|
-
* @returns 사이클이 감지되면 true
|
|
15
|
-
*/
|
|
16
|
-
visit(href: string): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* route enter를 아직 실행하지 않았다면 키를 등록하고 true를 반환합니다.
|
|
19
|
-
* 이미 실행된 route라면 false를 반환합니다 (중첩 라우트 redirect 체인에서 중복 방지).
|
|
20
|
-
*/
|
|
21
|
-
enter(route: RouteConfig): boolean;
|
|
22
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { UOutlet } from '../components/UOutlet';
|
|
2
|
-
/**
|
|
3
|
-
* `u-outlet` 엘리먼트를 찾아 반환합니다.
|
|
4
|
-
*
|
|
5
|
-
* @param element 검색을 시작할 HTMLElement
|
|
6
|
-
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
7
|
-
* @returns 찾은 UOutlet 엘리먼트 또는 undefined
|
|
8
|
-
*/
|
|
9
|
-
export declare function findOutlet(element: HTMLElement, skip?: boolean): UOutlet | undefined;
|
|
10
|
-
/**
|
|
11
|
-
* `u-outlet` 엘리먼트를 찾아 반환합니다. 없으면 에러를 던집니다.
|
|
12
|
-
*
|
|
13
|
-
* @param element 검색을 시작할 HTMLElement
|
|
14
|
-
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
15
|
-
*
|
|
16
|
-
* @returns 찾은 UOutlet 엘리먼트
|
|
17
|
-
* @throws OutletMissingError `u-outlet` 엘리먼트를 찾지 못한 경우
|
|
18
|
-
*/
|
|
19
|
-
export declare function findOutletOrThrow(element: HTMLElement, skip?: boolean): UOutlet;
|
|
20
|
-
/**
|
|
21
|
-
* 주어진 엘리먼트 내에서 `u-outlet`이 준비될 때까지 대기합니다.
|
|
22
|
-
*
|
|
23
|
-
* @param element 대기할 엘리먼트
|
|
24
|
-
* @param timeout 타임아웃 시간(밀리초, 기본값: 10_000ms)
|
|
25
|
-
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
26
|
-
*
|
|
27
|
-
* @returns 준비된 `u-outlet` 엘리먼트
|
|
28
|
-
*/
|
|
29
|
-
export declare function waitOutlet(element: HTMLElement, timeout?: number, skip?: boolean): Promise<UOutlet>;
|
|
30
|
-
/**
|
|
31
|
-
* 이벤트에서 composedPath()/closest를 사용하여 A 태그를 찾아 반환합니다.
|
|
32
|
-
*
|
|
33
|
-
* @param event 이벤트 객체
|
|
34
|
-
* @returns 찾은 A 태그 엘리먼트 또는 null
|
|
35
|
-
*/
|
|
36
|
-
export declare function findAnchorFrom(event: Event): HTMLAnchorElement | null;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { RouteConfig } from '../types/RouteConfig';
|
|
2
|
-
/**
|
|
3
|
-
* 라우트들을 다음 사항에 따라 재귀적으로 재설정합니다.
|
|
4
|
-
* - 각 라우트에 고유 `id`를 랜덤하게 부여합니다.
|
|
5
|
-
* - `path`를 URLPattern 객체로 변환합니다.
|
|
6
|
-
* - 자식 라우트가 있으면 재귀적으로 재설정합니다.
|
|
7
|
-
*
|
|
8
|
-
* @param routes 설정할 라우트 배열
|
|
9
|
-
* @param basepath 기준이 되는 basepath 문자열
|
|
10
|
-
* @returns 재설정된 라우트 배열
|
|
11
|
-
*/
|
|
12
|
-
export declare function setRoutes(routes: RouteConfig[], basepath: string): RouteConfig[];
|
|
13
|
-
/**
|
|
14
|
-
* URLPattern을 사용하여 경로와 일치하는 라우트들을 자식 라우트까지 포함하여 반환합니다.
|
|
15
|
-
* 반환된 배열은 상위 라우트부터 하위 라우트 순서로 정렬됩니다.
|
|
16
|
-
*
|
|
17
|
-
* @param routes 검사할 라우트 배열
|
|
18
|
-
* @param pathname 검사할 경로 이름
|
|
19
|
-
* @returns 일치하는 라우트 배열
|
|
20
|
-
*/
|
|
21
|
-
export declare function getRoutes(routes: RouteConfig[], pathname: string): RouteConfig[];
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { RouteContext } from '../types/RouteContext';
|
|
2
|
-
/**
|
|
3
|
-
* 주어진 URL이 외부 링크인지 확인합니다.
|
|
4
|
-
*
|
|
5
|
-
* @param url 확인할 URL 문자열
|
|
6
|
-
* @return 외부 링크인 경우 true, 내부 링크인 경우 false
|
|
7
|
-
*/
|
|
8
|
-
export declare function isExternalUrl(url: string): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* URL 문자열을 파싱하여 RouteContext 객체로 반환합니다.
|
|
11
|
-
* - http(s)로 시작하는 절대 URL은 외부 링크로 간주됩니다.
|
|
12
|
-
* - 절대경로(/...)는 그대로 사용됩니다.
|
|
13
|
-
* - 상대경로는 basepath를 기준으로 절대경로로 변환됩니다.
|
|
14
|
-
* - 쿼리스트링(?)로 시작하는 쿼리는 현재 경로와 추가됩니다.
|
|
15
|
-
* - 해시(#)로 시작하는 해시는 현재 경로와 추가됩니다.
|
|
16
|
-
*
|
|
17
|
-
* @param url 파싱할 URL 문자열
|
|
18
|
-
* @param basepath 기준이 되는 basepath 문자열
|
|
19
|
-
* @returns 파싱된 RouteContext 객체
|
|
20
|
-
*/
|
|
21
|
-
export declare function parseUrl(url: string, basepath: string): RouteContext;
|
|
22
|
-
/**
|
|
23
|
-
* pathname 경로를 조합하여 절대경로를 반환합니다.
|
|
24
|
-
*
|
|
25
|
-
* @param paths 조합할 경로 문자열들
|
|
26
|
-
* @returns 조합된 절대경로 문자열
|
|
27
|
-
*/
|
|
28
|
-
export declare function absolutePath(...paths: string[]): string;
|
|
29
|
-
/**
|
|
30
|
-
* basepath가 동적 패턴일 경우(RouteConfig에서 basepath가 :id 등으로 정의된 경우),
|
|
31
|
-
* 현재 경로에서 해당되는 패턴의 basepath를 추출하여 반환합니다.
|
|
32
|
-
*
|
|
33
|
-
* @param basepath 동적 패턴이 포함된 basepath 문자열
|
|
34
|
-
* @return 현재 경로에 매칭되는 basepath 문자열
|
|
35
|
-
* @example
|
|
36
|
-
* catchBasePath('/app/:id') => '/app/123'
|
|
37
|
-
*/
|
|
38
|
-
export declare function catchBasepath(basepath: string): string;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* go() 메서드에 전달할 네비게이션 옵션
|
|
3
|
-
*/
|
|
4
|
-
export interface NavigateOptions {
|
|
5
|
-
/**
|
|
6
|
-
* 리다이렉트로 인한 네비게이션 여부.
|
|
7
|
-
* - `true`이면 히스토리에 새 항목을 추가하지 않고 현재 항목을 교체합니다(replaceState).
|
|
8
|
-
* - 뒤로가기 버튼이 리다이렉트 경유지를 건너뛰게 됩니다.
|
|
9
|
-
* - 리다이렉트 사이클 감지에 사용됩니다.
|
|
10
|
-
* @default false
|
|
11
|
-
*/
|
|
12
|
-
isRedirect?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* 히스토리에 새 항목을 추가하지 않고 현재 항목을 교체합니다(replaceState).
|
|
15
|
-
* - `isRedirect`와 달리 리다이렉트 체인 추적에는 영향을 주지 않습니다.
|
|
16
|
-
* @default false
|
|
17
|
-
*/
|
|
18
|
-
replace?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* pushState / replaceState 호출 시 함께 저장할 커스텀 상태 객체.
|
|
21
|
-
* - `history.state`로 다시 읽을 수 있습니다.
|
|
22
|
-
* @example { from: '/login', referrer: 'email-link' }
|
|
23
|
-
*/
|
|
24
|
-
state?: Record<string, unknown>;
|
|
25
|
-
}
|