@iyulab/router 0.6.1 → 0.7.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.
@@ -1,89 +1,54 @@
1
- import { LitElement, html, render, css } from "lit";
2
- import { customElement, property } from "lit/decorators.js";
1
+ import { render, css, LitElement, html } from "lit";
3
2
  import { createRoot } from "react-dom/client";
4
- var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
5
- var __decorateClass$1 = (decorators, target, key, kind) => {
6
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
7
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
8
- if (decorator = decorators[i])
9
- result = decorator(result) || result;
10
- return result;
11
- };
12
- let UOutlet = class extends LitElement {
13
- /** 외부 스타일을 적용하기 위해 라이트 돔을사용 합니다. */
14
- createRenderRoot() {
15
- return this;
16
- }
17
- /** 컴포넌트가 DOM에 연결될 때 초기화 작업 수행 */
18
- connectedCallback() {
19
- super.connectedCallback();
20
- this.dispatchEvent(new CustomEvent("outlet-load", {
21
- bubbles: true,
22
- composed: true
23
- }));
24
- }
25
- render() {
26
- return html`${this.container}`;
27
- }
3
+ import { property, customElement } from "lit/decorators.js";
4
+ import { ifDefined } from "lit/directives/if-defined.js";
5
+ class UOutlet extends HTMLElement {
28
6
  /**
29
- * render 함수의 결과를 렌더링합니다.
30
- * - HTMLElement, ReactElement, TemplateResult를 모두 처리할 수 있습니다.
7
+ * 주어진 렌더링 옵션에 따라 컨텐츠를 렌더링합니다.
31
8
  */
32
- async renderContent({ id, content, force }) {
33
- if (this.routeId === id && force === false && this.container) {
34
- return this.container;
35
- }
9
+ render({ id, value, force }) {
10
+ if (this.routeId === id && force === false) return;
36
11
  this.routeId = id;
37
- this.clear();
38
- if (!this.container) {
39
- throw new Error("Outlet container is not initialized.");
40
- }
41
- if (typeof content !== "object") {
12
+ this.reset();
13
+ if (typeof value !== "object") {
42
14
  throw new Error("Content is not a valid renderable object.");
43
15
  }
44
- if (content instanceof HTMLElement) {
45
- this.container.appendChild(content);
46
- } else if ("_$litType$" in content) {
47
- this.content = render(content, this.container);
48
- } else if ("$$typeof" in content) {
49
- this.content = createRoot(this.container);
50
- this.content.render(content);
16
+ if (value instanceof HTMLElement) {
17
+ this.replaceChildren(value);
18
+ this.root = void 0;
19
+ } else if ("_$litType$" in value) {
20
+ this.root = render(value, this);
21
+ } else if ("$$typeof" in value) {
22
+ this.root = createRoot(this);
23
+ this.root.render(value);
51
24
  } else {
52
25
  throw new Error("not supported content type for Outlet rendering.");
53
26
  }
54
- this.requestUpdate();
55
- await this.updateComplete;
56
- return this.container;
57
27
  }
58
28
  /**
59
- * 기존 DOM을 라이프 사이클에 맞게 제거합니다.
29
+ * 기존 DOM을 삭제하여, 초기 상태로 되돌립니다.
60
30
  */
61
- clear() {
62
- if (this.content) {
63
- if ("unmount" in this.content) {
64
- this.content.unmount();
65
- }
66
- if ("setConnected" in this.content) {
67
- this.content.setConnected(false);
68
- }
69
- this.content = void 0;
31
+ reset() {
32
+ if (this.root && "_$litPart$" in this) {
33
+ delete this._$litPart$;
34
+ }
35
+ if (this.root && "unmount" in this.root) {
36
+ this.root.unmount();
70
37
  }
71
- this.container = document.createElement("div");
72
- this.container.style.display = "contents";
38
+ this.root = void 0;
39
+ this.innerHTML = "";
73
40
  }
74
- };
75
- UOutlet = __decorateClass$1([
76
- customElement("u-outlet")
77
- ], UOutlet);
41
+ }
42
+ customElements.define("u-outlet", UOutlet);
78
43
  function isExternalUrl(url) {
79
44
  if (!url) return false;
80
- const s = url.trim();
81
- if (/^(?:mailto:|tel:|javascript:)/i.test(s)) return true;
82
- if (s.startsWith("//")) return true;
45
+ url = url.trim();
46
+ if (/^(?:mailto:|tel:|javascript:)/i.test(url)) return true;
47
+ if (url.startsWith("//")) return true;
83
48
  try {
84
49
  const base = typeof window !== "undefined" ? window.location.origin : "http://localhost";
85
- const parsed = new URL(s, base);
86
- if (/^(?:ftp:|ftps:|data:|ws:|wss:)/i.test(parsed.protocol)) return true;
50
+ const parsed = new URL(url, base);
51
+ if (/^(?:ftp:|ftps:|ws:|wss:)/i.test(parsed.protocol)) return true;
87
52
  return parsed.origin !== new URL(base).origin;
88
53
  } catch {
89
54
  return false;
@@ -91,7 +56,7 @@ function isExternalUrl(url) {
91
56
  }
92
57
  function parseUrl(url, basepath) {
93
58
  let urlObj;
94
- basepath = catchBasePath(basepath);
59
+ basepath = catchBasepath(basepath);
95
60
  if (url.startsWith("http")) {
96
61
  urlObj = new URL(url);
97
62
  } else if (url.startsWith("/")) {
@@ -113,7 +78,8 @@ function parseUrl(url, basepath) {
113
78
  hash: urlObj.hash,
114
79
  params: {},
115
80
  progress: () => {
116
- }
81
+ },
82
+ meta: {}
117
83
  };
118
84
  }
119
85
  function absolutePath(...paths) {
@@ -121,7 +87,7 @@ function absolutePath(...paths) {
121
87
  if (paths.length === 0) return "/";
122
88
  return "/" + paths.join("/");
123
89
  }
124
- function catchBasePath(basepath) {
90
+ function catchBasepath(basepath) {
125
91
  if (basepath === "/") return basepath;
126
92
  let pattern = new URLPattern({ pathname: basepath + "/*" });
127
93
  let match = pattern.exec({ pathname: window.location.pathname });
@@ -151,12 +117,11 @@ let ULink = class extends LitElement {
151
117
  constructor() {
152
118
  super(...arguments);
153
119
  this.isExternal = false;
154
- this.handleAnchorClick = (event) => {
120
+ this.handleClick = (event) => {
155
121
  if (event.defaultPrevented) return;
156
122
  if (event.button !== 0) return;
157
123
  if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
158
- const target = (this.target ?? "").trim();
159
- if (target && target.toLowerCase() !== "_self") return;
124
+ if (this.target && this.target.toLowerCase() !== "_self") return;
160
125
  const basepath = this.getBasepath();
161
126
  if (!this.href) {
162
127
  event.preventDefault();
@@ -183,6 +148,14 @@ let ULink = class extends LitElement {
183
148
  this.dispatchPopstate(basepath, url);
184
149
  };
185
150
  }
151
+ connectedCallback() {
152
+ super.connectedCallback();
153
+ this.addEventListener("click", this.handleClick);
154
+ }
155
+ disconnectedCallback() {
156
+ this.removeEventListener("click", this.handleClick);
157
+ super.disconnectedCallback();
158
+ }
186
159
  willUpdate(changedProperties) {
187
160
  super.willUpdate(changedProperties);
188
161
  if (changedProperties.has("href")) {
@@ -191,27 +164,18 @@ let ULink = class extends LitElement {
191
164
  }
192
165
  render() {
193
166
  return html`
194
- <a
195
- target=${this.target ?? "_self"}
196
- href=${this.computeHref(this.href)}
197
- @click=${this.handleAnchorClick}>
167
+ <a target=${ifDefined(this.target)} href=${this.compute(this.href)}>
198
168
  <slot></slot>
199
169
  </a>
200
170
  `;
201
171
  }
202
- /** basepath를 state에서 꺼내는 헬퍼 */
203
- getBasepath() {
204
- return window.history.state?.basepath || "";
205
- }
206
172
  /** a 태그에 주입할 href 값을 계산합니다. */
207
- computeHref(href) {
173
+ compute(href) {
208
174
  const basepath = this.getBasepath();
209
- if (!href) {
210
- return window.location.origin + basepath;
211
- }
175
+ if (!href) return window.location.origin + basepath;
212
176
  if (this.isExternal) return href;
213
- if (href.startsWith("#") || href.startsWith("?")) return href;
214
177
  if (href.startsWith("/")) return href;
178
+ if (href.startsWith("#") || href.startsWith("?")) return href;
215
179
  return absolutePath(basepath, href);
216
180
  }
217
181
  /** 클라이언트 라우팅을 위해 popstate 이벤트를 발생시킵니다. */
@@ -219,15 +183,17 @@ let ULink = class extends LitElement {
219
183
  window.history.pushState({ basepath }, "", url);
220
184
  window.dispatchEvent(new PopStateEvent("popstate"));
221
185
  }
186
+ /** basepath를 state에서 꺼내는 헬퍼 */
187
+ getBasepath() {
188
+ return window.history.state?.basepath || "";
189
+ }
222
190
  };
223
191
  ULink.styles = css`
224
192
  :host {
225
- display: inline-flex;
226
193
  cursor: pointer;
227
194
  }
228
195
 
229
196
  a {
230
- display: contents;
231
197
  text-decoration: none;
232
198
 
233
199
  font-size: inherit;
package/package.json CHANGED
@@ -1,56 +1,56 @@
1
- {
2
- "name": "@iyulab/router",
3
- "version": "0.6.1",
4
- "description": "A modern client-side router for web applications with support for Lit and React components",
5
- "keywords": [
6
- "lit",
7
- "react",
8
- "router",
9
- "routing",
10
- "spa",
11
- "navigation",
12
- "client-side"
13
- ],
14
- "license": "MIT",
15
- "author": "iyulab",
16
- "repository": {
17
- "type": "git",
18
- "url": "https://github.com/iyulab/node-router.git"
19
- },
20
- "files": [
21
- "dist",
22
- "package.json",
23
- "README.md",
24
- "LICENSE"
25
- ],
26
- "type": "module",
27
- "types": "dist/index.d.ts",
28
- "exports": {
29
- ".": {
30
- "types": "./dist/index.d.ts",
31
- "import": "./dist/index.js"
32
- },
33
- "./react": {
34
- "types": "./dist/react.d.ts",
35
- "import": "./dist/react.js"
36
- }
37
- },
38
- "scripts": {
39
- "test": "vite",
40
- "build": "vite build"
41
- },
42
- "dependencies": {
43
- "lit": "^3.3.2",
44
- "react": "^19.2.3",
45
- "react-dom": "^19.2.3"
46
- },
47
- "devDependencies": {
48
- "@lit/react": "^1.0.8",
49
- "@types/node": "^25.0.9",
50
- "@types/react": "^19.2.8",
51
- "@types/react-dom": "^19.2.3",
52
- "typescript": "^5.9.3",
53
- "vite": "^7.3.1",
54
- "vite-plugin-dts": "^4.5.4"
55
- }
56
- }
1
+ {
2
+ "name": "@iyulab/router",
3
+ "version": "0.7.0",
4
+ "description": "A modern client-side router for web applications with support for Lit and React components",
5
+ "keywords": [
6
+ "lit",
7
+ "react",
8
+ "router",
9
+ "routing",
10
+ "spa",
11
+ "navigation",
12
+ "client-side"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "iyulab",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/iyulab/node-router.git"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "package.json",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "type": "module",
27
+ "types": "dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./src/index.d.ts",
31
+ "import": "./src/index.js"
32
+ },
33
+ "./react": {
34
+ "types": "./dist/react.d.ts",
35
+ "import": "./dist/react.js"
36
+ }
37
+ },
38
+ "scripts": {
39
+ "test": "vite",
40
+ "build": "vite build"
41
+ },
42
+ "dependencies": {
43
+ "@lit/react": "^1.0.8",
44
+ "lit": "^3.3.2",
45
+ "react": "^19.2.3",
46
+ "react-dom": "^19.2.3"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^25.0.9",
50
+ "@types/react": "^19.2.9",
51
+ "@types/react-dom": "^19.2.3",
52
+ "typescript": "^5.9.3",
53
+ "vite": "^7.3.1",
54
+ "vite-plugin-dts": "^4.5.4"
55
+ }
56
+ }