@iyulab/router 0.5.3 โ 0.6.1
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/README.md +42 -56
- package/dist/index.d.ts +63 -73
- package/dist/index.js +104 -345
- package/dist/react.d.ts +89 -0
- package/dist/react.js +44 -0
- package/dist/share-SPj-xl6y.js +255 -0
- package/package.json +13 -8
package/README.md
CHANGED
|
@@ -6,13 +6,9 @@ A modern, lightweight client-side router for web applications with support for b
|
|
|
6
6
|
|
|
7
7
|
- ๐ **Modern URLPattern-based routing** - Uses native URLPattern API for powerful path matching
|
|
8
8
|
- ๐ง **Unified Framework Support** - Works with both Lit and React components using render functions
|
|
9
|
-
- ๐ฑ **Client-
|
|
9
|
+
- ๐ฑ **Client-Side Navigation** - History API integration with browser back/forward support
|
|
10
10
|
- ๐ฏ **Nested Routing** - Support for deeply nested route hierarchies with index and path routes
|
|
11
|
-
- ๐ **Smart Link Component** - Automatic external link detection and handling
|
|
12
11
|
- ๐ **Route Events** - Track navigation progress with route-begin, route-done, and route-error events
|
|
13
|
-
- ๐จ **Flexible Outlet System** - Unified rendering with renderContent method
|
|
14
|
-
- ๐ **Global Route Access** - Access current route information anywhere via `window.route`
|
|
15
|
-
- ๐ **Force Re-rendering** - Control component re-rendering on route changes
|
|
16
12
|
- โ ๏ธ **Enhanced Error Handling** - Built-in ErrorPage component with improved styling
|
|
17
13
|
|
|
18
14
|
## Installation
|
|
@@ -30,43 +26,18 @@ import { Router } from '@iyulab/router';
|
|
|
30
26
|
import { html } from 'lit';
|
|
31
27
|
|
|
32
28
|
const router = new Router({
|
|
33
|
-
|
|
34
|
-
basepath: '/app',
|
|
29
|
+
basepath: '/',
|
|
35
30
|
routes: [
|
|
36
31
|
{
|
|
37
32
|
index: true,
|
|
38
33
|
render: () => html`<home-page></home-page>`
|
|
39
34
|
},
|
|
40
35
|
{
|
|
41
|
-
path: '/user/:id',
|
|
36
|
+
path: '/user/:id', // URLPattern route
|
|
42
37
|
render: (routeInfo) => html`<user-page .userId=${routeInfo.params.id}></user-page>`
|
|
43
38
|
}
|
|
44
|
-
]
|
|
39
|
+
],
|
|
45
40
|
});
|
|
46
|
-
|
|
47
|
-
// Start routing
|
|
48
|
-
router.go(window.location.href);
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Nested Routes
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
const routes = [
|
|
55
|
-
{
|
|
56
|
-
path: '/dashboard',
|
|
57
|
-
render: () => html`<dashboard-layout><u-outlet></u-outlet></dashboard-layout>`,
|
|
58
|
-
children: [
|
|
59
|
-
{
|
|
60
|
-
index: true, // Matches /dashboard exactly
|
|
61
|
-
render: () => html`<dashboard-home></dashboard-home>`
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
path: 'settings',
|
|
65
|
-
render: () => html`<dashboard-settings></dashboard-settings>`
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
];
|
|
70
41
|
```
|
|
71
42
|
|
|
72
43
|
### Mixed Framework Support
|
|
@@ -78,12 +49,16 @@ const routes = [
|
|
|
78
49
|
// Lit component
|
|
79
50
|
{
|
|
80
51
|
path: '/lit-page',
|
|
81
|
-
render: (routeInfo) =>
|
|
52
|
+
render: (routeInfo) => {
|
|
53
|
+
return html`<my-lit-component .routeInfo=${routeInfo}></my-lit-component>`
|
|
54
|
+
}
|
|
82
55
|
},
|
|
83
56
|
// React component
|
|
84
57
|
{
|
|
85
58
|
path: '/react-page',
|
|
86
|
-
render: (routeInfo) =>
|
|
59
|
+
render: (routeInfo) => {
|
|
60
|
+
return ( <MyComponent></MyComponent> )
|
|
61
|
+
}
|
|
87
62
|
},
|
|
88
63
|
// HTML element
|
|
89
64
|
{
|
|
@@ -97,14 +72,39 @@ const routes = [
|
|
|
97
72
|
];
|
|
98
73
|
```
|
|
99
74
|
|
|
75
|
+
### Nested Routes
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { RouteConfig } from '@iyulab/router';
|
|
79
|
+
|
|
80
|
+
const routes: RouteConfig[] = [
|
|
81
|
+
{
|
|
82
|
+
path: '/dashboard',
|
|
83
|
+
render: () => html`<dashboard-layout><u-outlet></u-outlet></dashboard-layout>`,
|
|
84
|
+
children: [
|
|
85
|
+
{
|
|
86
|
+
index: true, // Matches '/dashboard'
|
|
87
|
+
render: () => html`<dashboard-home></dashboard-home>`
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
path: 'settings', // Matches '/dashboard/settings'
|
|
91
|
+
render: () => html`<dashboard-settings></dashboard-settings>`
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
```
|
|
97
|
+
|
|
100
98
|
## Usage Examples
|
|
101
99
|
|
|
102
|
-
### Using with Lit
|
|
100
|
+
### Using with Lit Elements
|
|
103
101
|
|
|
104
102
|
```typescript
|
|
105
103
|
import { LitElement, html } from 'lit';
|
|
106
104
|
import { customElement } from 'lit/decorators.js';
|
|
107
105
|
|
|
106
|
+
import "@iyulab/router";
|
|
107
|
+
|
|
108
108
|
@customElement('app-root')
|
|
109
109
|
export class AppRoot extends LitElement {
|
|
110
110
|
render() {
|
|
@@ -126,38 +126,24 @@ export class AppRoot extends LitElement {
|
|
|
126
126
|
|
|
127
127
|
```tsx
|
|
128
128
|
import React from 'react';
|
|
129
|
-
import {
|
|
129
|
+
import { UOutlet, ULink } from '@iyulab/router/react';
|
|
130
130
|
|
|
131
131
|
export function AppRoot() {
|
|
132
132
|
return (
|
|
133
133
|
<div>
|
|
134
134
|
<nav>
|
|
135
|
-
<
|
|
136
|
-
<
|
|
137
|
-
<
|
|
135
|
+
<ULink href="/">Home</ULink>
|
|
136
|
+
<ULink href="/about">About</ULink>
|
|
137
|
+
<ULink href="/user/123">User Profile</ULink>
|
|
138
138
|
</nav>
|
|
139
139
|
<main>
|
|
140
|
-
<
|
|
140
|
+
<UOutlet />
|
|
141
141
|
</main>
|
|
142
142
|
</div>
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
## Browser Support
|
|
148
|
-
|
|
149
|
-
- **URLPattern API**: Required for routing functionality
|
|
150
|
-
- **Modern browsers**: Chrome 95+, Firefox 106+, Safari 16.4+
|
|
151
|
-
- **Polyfill**: Consider using [urlpattern-polyfill](https://www.npmjs.com/package/urlpattern-polyfill) for older browsers
|
|
152
|
-
|
|
153
|
-
## Contributing
|
|
154
|
-
|
|
155
|
-
1. Fork the repository
|
|
156
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
157
|
-
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
158
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
159
|
-
5. Open a Pull Request
|
|
160
|
-
|
|
161
147
|
## License
|
|
162
148
|
|
|
163
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
|
149
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CSSResult } from 'lit';
|
|
2
2
|
import { LitElement } from 'lit';
|
|
3
|
+
import { PropertyValues } from 'lit';
|
|
3
4
|
import { ReactElement } from 'react';
|
|
4
|
-
import { ReactWebComponent } from '@lit/react';
|
|
5
5
|
import { TemplateResult } from 'lit';
|
|
6
6
|
import { TemplateResult as TemplateResult_2 } from 'lit-html';
|
|
7
7
|
|
|
@@ -119,47 +119,6 @@ declare interface IndexRouteConfig extends BaseRouteConfig {
|
|
|
119
119
|
index: true;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
/**
|
|
123
|
-
* - ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ง์ํ๋ ๋งํฌ ์๋ฆฌ๋จผํธ์
๋๋ค.
|
|
124
|
-
* - ๋ด๋ถ ๋งํฌ๋ ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํํ๊ณ , ์ธ๋ถ ๋งํฌ๋ ์๋ก์ด ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
|
|
125
|
-
* - ๋ง์ฐ์ค ์ค๊ฐ ๋ฒํผ ํด๋ฆญ ๋๋ Ctrl ํค๋ฅผ ๋๋ฅด๋ฉด ์๋ก์ด ํญ์์ ์ฝ๋๋ค.
|
|
126
|
-
*/
|
|
127
|
-
export declare class Link extends LitElement {
|
|
128
|
-
/** ์ธ๋ถ ๋งํฌ ์ฌ๋ถ */
|
|
129
|
-
private isExternal;
|
|
130
|
-
/** a ํ๊ทธ์ href ์์ฑ ๋ฐ ์๋ก์ด ํ์ด์ง๋ก ์ด๋ํ ๋ ์ฌ์ฉ๋ ๋งํฌ์
๋๋ค. */
|
|
131
|
-
anchorHref: string;
|
|
132
|
-
/**
|
|
133
|
-
* - ์์ฑ์ ์ ์ํ์ง ์์ผ๋ฉด basepath๋ก ์ด๋ํฉ๋๋ค.
|
|
134
|
-
* - http ๋ก ์์ํ๋ฉด ์๋ก์ด ํ์ด์ง๋ฅผ ๋ก๋ํฉ๋๋ค.
|
|
135
|
-
* - ์ ๋๊ฒฝ๋ก์ผ ๊ฒฝ์ฐ basepath๋ก ์์ํ๋ฉด ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ก์ด ํ์ด์ง๋ฅผ ๋ก๋ํฉ๋๋ค.
|
|
136
|
-
* - ์๋๊ฒฝ๋ก๋ก ์์ํ๋ฉด (ํ์ฌ์ basepath + ์๋๊ฒฝ๋ก)๋ก ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ํฉ๋๋ค.
|
|
137
|
-
* - ?๋ก ์์ํ๋ฉด ํ์ฌ ๊ฒฝ๋ก์ ์ฟผ๋ฆฌ์คํธ๋ง์ ์ถ๊ฐํ๊ณ , ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ํฉ๋๋ค.
|
|
138
|
-
* - #์ผ๋ก ์์ํ๋ฉด ํ์ฌ ๊ฒฝ๋ก์ ํด์๋ฅผ ์ถ๊ฐํ๊ณ , hashchange ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค.
|
|
139
|
-
*/
|
|
140
|
-
href?: string;
|
|
141
|
-
connectedCallback(): void;
|
|
142
|
-
disconnectedCallback(): void;
|
|
143
|
-
protected updated(changedProperties: any): Promise<void>;
|
|
144
|
-
render(): TemplateResult_2<1>;
|
|
145
|
-
/**
|
|
146
|
-
* ๋งํฌ ์๋ฆฌ๋จผํธ์ ๋ง์ฐ์ค ์ด๋ฒคํธ ํธ๋ค๋ฌ
|
|
147
|
-
* - ์๋ก์ด ํญ์์ ์ด๊ธฐ: ๋ง์ฐ์ค ์ค๊ฐ ๋ฒํผ ๋๋ Ctrl ํค๋ฅผ ๋๋ฆ
๋๋ค.
|
|
148
|
-
* - ์๋ก์ด ํ์ด์ง๋ก ์ด๋: http๋ก ์์ํ๊ฑฐ๋ ์ ๋๊ฒฝ๋ก์ผ ๊ฒฝ์ฐ ์๋ก์ด ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
|
|
149
|
-
* - ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
: ์๋๊ฒฝ๋ก๋ก ์์ํ๋ฉด ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ํฉ๋๋ค.
|
|
150
|
-
*/
|
|
151
|
-
private handleMouseDown;
|
|
152
|
-
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด popstate ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
153
|
-
private dispatchPopstate;
|
|
154
|
-
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด hashchange ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
155
|
-
private dispatchHashchange;
|
|
156
|
-
/** ๊ธฐ๋ณธ a ํ๊ทธ์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ง์ต๋๋ค. */
|
|
157
|
-
private preventClickEvent;
|
|
158
|
-
/** a ํ๊ทธ์ ์ฃผ์
ํ href ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. */
|
|
159
|
-
private getAnchorHref;
|
|
160
|
-
static styles: CSSResult;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
122
|
declare interface NonIndexRouteConfig extends BaseRouteConfig {
|
|
164
123
|
/**
|
|
165
124
|
* ์ธ๋ฑ์ค ๋ผ์ฐํธ๊ฐ ์๋์ ๋ํ๋
๋๋ค.
|
|
@@ -179,28 +138,6 @@ export declare class NotFoundError extends RouteError {
|
|
|
179
138
|
constructor(path: string, original?: Error | any);
|
|
180
139
|
}
|
|
181
140
|
|
|
182
|
-
/**
|
|
183
|
-
* ๋ผ์ฐํธ ์์๋ ์ปดํฌ๋ํธ
|
|
184
|
-
* ๋ผ์ฐํธ ์ค์ ์ ๋ฐ๋ผ LitElement ๋๋ React ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
185
|
-
*/
|
|
186
|
-
export declare class Outlet extends LitElement {
|
|
187
|
-
private routeId?;
|
|
188
|
-
private container?;
|
|
189
|
-
private content?;
|
|
190
|
-
/** ์๋์ฐ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ์ง์ ๋ ๋๋งํฉ๋๋ค. */
|
|
191
|
-
protected createRenderRoot(): this;
|
|
192
|
-
render(): TemplateResult<1>;
|
|
193
|
-
/**
|
|
194
|
-
* render ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
195
|
-
* - HTMLElement, ReactElement, TemplateResult๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
196
|
-
*/
|
|
197
|
-
renderContent({ id, content, force }: RenderOption): Promise<HTMLDivElement>;
|
|
198
|
-
/**
|
|
199
|
-
* ๊ธฐ์กด DOM์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ง๊ฒ ์ ๊ฑฐํฉ๋๋ค.
|
|
200
|
-
*/
|
|
201
|
-
clear(): void;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
141
|
/**
|
|
205
142
|
* u-outlet ์์๋ฅผ ์ฐพ์ ์ ์์ ๋ ๋ฐ์ํ๋ ์๋ฌ
|
|
206
143
|
*/
|
|
@@ -360,7 +297,7 @@ export declare class RouteProgressEvent extends RouteEvent {
|
|
|
360
297
|
}
|
|
361
298
|
|
|
362
299
|
/**
|
|
363
|
-
* `lit-element
|
|
300
|
+
* `lit-element`, `react`๋ฅผ ์ง์ํ๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํฐ
|
|
364
301
|
*/
|
|
365
302
|
export declare class Router {
|
|
366
303
|
private readonly _rootElement;
|
|
@@ -388,7 +325,7 @@ export declare class Router {
|
|
|
388
325
|
/** ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ ์ด๋ฒคํธ๊ฐ ๋ฐ์์ ๋ผ์ฐํ
์ฒ๋ฆฌ */
|
|
389
326
|
private handleWindowPopstate;
|
|
390
327
|
/** ํด๋ฆญ ์ด๋ฒคํธ์์ ๋ผ์ฐํฐ๋ก ์ฒ๋ฆฌํ ์ต์ปค๋ฅผ ์ฐพ์ ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ํ */
|
|
391
|
-
private
|
|
328
|
+
private handleDocumentClick;
|
|
392
329
|
}
|
|
393
330
|
|
|
394
331
|
/**
|
|
@@ -429,9 +366,67 @@ export declare interface RouterConfig {
|
|
|
429
366
|
initialLoad?: boolean;
|
|
430
367
|
}
|
|
431
368
|
|
|
432
|
-
|
|
369
|
+
/**
|
|
370
|
+
* - ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ง์ํ๋ ๋งํฌ ์๋ฆฌ๋จผํธ์
๋๋ค.
|
|
371
|
+
* - ๋ด๋ถ ๋งํฌ๋ ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํํ๊ณ , ์ธ๋ถ ๋งํฌ๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋ค๋น๊ฒ์ด์
์ ์ฌ์ฉํฉ๋๋ค.
|
|
372
|
+
* - Ctrl/Meta/Shift/Alt, ์คํด๋ฆญ/์ฐํด๋ฆญ ๋ฑ์ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์(์ ํญ, ์ปจํ
์คํธ ๋ฉ๋ด ๋ฑ)์ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค.
|
|
373
|
+
*/
|
|
374
|
+
export declare class ULink extends LitElement {
|
|
375
|
+
/** ์ธ๋ถ ๋งํฌ ์ฌ๋ถ */
|
|
376
|
+
private isExternal;
|
|
377
|
+
/**
|
|
378
|
+
* a ํ๊ทธ target์ ์ง์ํ๊ณ ์ถ์ผ๋ฉด ์ด์ด๋๋๊ฒ ์ข์ต๋๋ค.
|
|
379
|
+
* - _blank ๋ฑ์ ์ฐ๋ฉด ๋ฌด์กฐ๊ฑด ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์์ ๋ฐ๋ฅด๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.
|
|
380
|
+
*/
|
|
381
|
+
target?: string;
|
|
382
|
+
/**
|
|
383
|
+
* - ์์ฑ์ ์ ์ํ์ง ์์ผ๋ฉด basepath๋ก ์ด๋ํฉ๋๋ค.
|
|
384
|
+
* - http(s)๋ก ์์ํ๋ฉด ์ธ๋ถ ๋งํฌ๋ก ๊ฐ์ฃผํ๊ณ ๋ธ๋ผ์ฐ์ ๋ค๋น๊ฒ์ด์
์ ์ฌ์ฉํฉ๋๋ค.
|
|
385
|
+
* - ์ ๋๊ฒฝ๋ก(/...)์ผ ๊ฒฝ์ฐ basepath๋ก ์์ํ๋ฉด SPA ๋ผ์ฐํ
๋์์ด ๋ ์ ์์ต๋๋ค.
|
|
386
|
+
* - ์๋๊ฒฝ๋ก๋ (basepath + ์๋๊ฒฝ๋ก)๋ก SPA ๋ผ์ฐํ
๋์์ด ๋ ์ ์์ต๋๋ค.
|
|
387
|
+
* - ?๋ก ์์ํ๋ฉด ํ์ฌ pathname์ ์ฟผ๋ฆฌ์คํธ๋ง์ ๋ถ์ฌ SPA ๋ผ์ฐํ
ํฉ๋๋ค.
|
|
388
|
+
* - #์ผ๋ก ์์ํ๋ฉด ํ์ฌ URL์ ํด์๋ง ๋ฐ๊พธ๊ณ (๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ) ๋์ํฉ๋๋ค.
|
|
389
|
+
*/
|
|
390
|
+
href?: string;
|
|
391
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
392
|
+
render(): TemplateResult_2<1>;
|
|
393
|
+
/** basepath๋ฅผ state์์ ๊บผ๋ด๋ ํฌํผ */
|
|
394
|
+
private getBasepath;
|
|
395
|
+
/** a ํ๊ทธ์ ์ฃผ์
ํ href ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. */
|
|
396
|
+
private computeHref;
|
|
397
|
+
/**
|
|
398
|
+
* ํด๋ฆญ ๊ฐ๋ก์ฑ๊ธฐ ๊ท์น
|
|
399
|
+
* - ์ขํด๋ฆญ(0) + ๋ณด์กฐํค ์์(ctrl/meta/shift/alt ์์) + target์ด _self์ผ ๋๋ง SPA ๋ผ์ฐํ
๊ณ ๋ ค
|
|
400
|
+
* - ๊ทธ ์ธ(์คํด๋ฆญ/์ฐํด๋ฆญ/๋ณด์กฐํค/target=_blank ๋ฑ)๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์ ์ ์ง
|
|
401
|
+
*/
|
|
402
|
+
private handleAnchorClick;
|
|
403
|
+
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด popstate ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
404
|
+
private dispatchPopstate;
|
|
405
|
+
static styles: CSSResult;
|
|
406
|
+
}
|
|
433
407
|
|
|
434
|
-
|
|
408
|
+
/**
|
|
409
|
+
* ๋ผ์ฐํธ ์ค์ ์ ๋ฐ๋ผ LitElement ๋๋ React ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
410
|
+
*/
|
|
411
|
+
export declare class UOutlet extends LitElement {
|
|
412
|
+
private routeId?;
|
|
413
|
+
private container?;
|
|
414
|
+
private content?;
|
|
415
|
+
/** ์ธ๋ถ ์คํ์ผ์ ์ ์ฉํ๊ธฐ ์ํด ๋ผ์ดํธ ๋์์ฌ์ฉ ํฉ๋๋ค. */
|
|
416
|
+
protected createRenderRoot(): this;
|
|
417
|
+
/** ์ปดํฌ๋ํธ๊ฐ DOM์ ์ฐ๊ฒฐ๋ ๋ ์ด๊ธฐํ ์์
์ํ */
|
|
418
|
+
connectedCallback(): void;
|
|
419
|
+
render(): TemplateResult<1>;
|
|
420
|
+
/**
|
|
421
|
+
* render ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
422
|
+
* - HTMLElement, ReactElement, TemplateResult๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
423
|
+
*/
|
|
424
|
+
renderContent({ id, content, force }: RenderOption): Promise<HTMLDivElement>;
|
|
425
|
+
/**
|
|
426
|
+
* ๊ธฐ์กด DOM์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ง๊ฒ ์ ๊ฑฐํฉ๋๋ค.
|
|
427
|
+
*/
|
|
428
|
+
clear(): void;
|
|
429
|
+
}
|
|
435
430
|
|
|
436
431
|
export { }
|
|
437
432
|
|
|
@@ -442,9 +437,4 @@ declare global {
|
|
|
442
437
|
'route-done': RouteDoneEvent;
|
|
443
438
|
'route-error': RouteErrorEvent;
|
|
444
439
|
}
|
|
445
|
-
|
|
446
|
-
interface HTMLElementTagNameMap {
|
|
447
|
-
'u-link': Link;
|
|
448
|
-
'u-outlet': Outlet;
|
|
449
|
-
}
|
|
450
440
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,269 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { a as absolutePath, i as isExternalUrl, p as parseUrl } from "./share-SPj-xl6y.js";
|
|
2
|
+
import { b, U } from "./share-SPj-xl6y.js";
|
|
3
|
+
import { css, LitElement, html } from "lit";
|
|
4
|
+
import { property, customElement } from "lit/decorators.js";
|
|
5
5
|
import { unsafeHTML } from "lit-html/directives/unsafe-html.js";
|
|
6
|
-
const e = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), n = /* @__PURE__ */ new WeakMap(), t = (e2, t2, o2, l, a) => {
|
|
7
|
-
const s = a?.[t2];
|
|
8
|
-
void 0 === s ? (e2[t2] = o2, null == o2 && t2 in HTMLElement.prototype && e2.removeAttribute(t2)) : o2 !== l && ((e3, t3, o3) => {
|
|
9
|
-
let l2 = n.get(e3);
|
|
10
|
-
void 0 === l2 && n.set(e3, l2 = /* @__PURE__ */ new Map());
|
|
11
|
-
let a2 = l2.get(t3);
|
|
12
|
-
void 0 !== o3 ? void 0 === a2 ? (l2.set(t3, a2 = { handleEvent: o3 }), e3.addEventListener(t3, a2)) : a2.handleEvent = o3 : void 0 !== a2 && (l2.delete(t3), e3.removeEventListener(t3, a2));
|
|
13
|
-
})(e2, s, o2);
|
|
14
|
-
}, o = ({ react: n2, tagName: o2, elementClass: l, events: a, displayName: s }) => {
|
|
15
|
-
const c = new Set(Object.keys(a ?? {})), r = n2.forwardRef(((s2, r2) => {
|
|
16
|
-
const i = n2.useRef(/* @__PURE__ */ new Map()), d = n2.useRef(null), f = {}, u = {};
|
|
17
|
-
for (const [n3, t2] of Object.entries(s2)) e.has(n3) ? f["className" === n3 ? "class" : n3] = t2 : c.has(n3) || n3 in l.prototype ? u[n3] = t2 : f[n3] = t2;
|
|
18
|
-
return n2.useLayoutEffect((() => {
|
|
19
|
-
if (null === d.current) return;
|
|
20
|
-
const e2 = /* @__PURE__ */ new Map();
|
|
21
|
-
for (const n3 in u) t(d.current, n3, s2[n3], i.current.get(n3), a), i.current.delete(n3), e2.set(n3, s2[n3]);
|
|
22
|
-
for (const [e3, n3] of i.current) t(d.current, e3, void 0, n3, a);
|
|
23
|
-
i.current = e2;
|
|
24
|
-
})), n2.useLayoutEffect((() => {
|
|
25
|
-
d.current?.removeAttribute("defer-hydration");
|
|
26
|
-
}), []), f.suppressHydrationWarning = true, n2.createElement(o2, { ...f, ref: n2.useCallback(((e2) => {
|
|
27
|
-
d.current = e2, "function" == typeof r2 ? r2(e2) : null !== r2 && (r2.current = e2);
|
|
28
|
-
}), [r2]) });
|
|
29
|
-
}));
|
|
30
|
-
return r.displayName = s ?? l.name, r;
|
|
31
|
-
};
|
|
32
|
-
function isExternalUrl(url) {
|
|
33
|
-
if (!url) return false;
|
|
34
|
-
const s = url.trim();
|
|
35
|
-
if (/^(?:mailto:|tel:|javascript:)/i.test(s)) return true;
|
|
36
|
-
if (s.startsWith("//")) return true;
|
|
37
|
-
try {
|
|
38
|
-
const base = typeof window !== "undefined" ? window.location.origin : "http://localhost";
|
|
39
|
-
const parsed = new URL(s, base);
|
|
40
|
-
if (/^(?:ftp:|ftps:|data:|ws:|wss:)/i.test(parsed.protocol)) return true;
|
|
41
|
-
return parsed.origin !== new URL(base).origin;
|
|
42
|
-
} catch {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function parseUrl(url, basepath) {
|
|
47
|
-
let urlObj;
|
|
48
|
-
basepath = catchBasePath(basepath);
|
|
49
|
-
if (url.startsWith("http")) {
|
|
50
|
-
urlObj = new URL(url);
|
|
51
|
-
} else if (url.startsWith("/")) {
|
|
52
|
-
urlObj = new URL(url, window.location.origin);
|
|
53
|
-
} else if (url.startsWith("?")) {
|
|
54
|
-
urlObj = new URL(window.location.pathname + url, window.location.origin);
|
|
55
|
-
} else if (url.startsWith("#")) {
|
|
56
|
-
urlObj = new URL(window.location.pathname + window.location.search + url, window.location.origin);
|
|
57
|
-
} else {
|
|
58
|
-
urlObj = new URL(absolutePath(basepath, url), window.location.origin);
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
href: urlObj.href,
|
|
62
|
-
origin: urlObj.origin,
|
|
63
|
-
basepath,
|
|
64
|
-
path: urlObj.href.replace(urlObj.origin, ""),
|
|
65
|
-
pathname: urlObj.pathname,
|
|
66
|
-
query: new URLSearchParams(urlObj.search),
|
|
67
|
-
hash: urlObj.hash,
|
|
68
|
-
params: {},
|
|
69
|
-
progress: () => {
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function absolutePath(...paths) {
|
|
74
|
-
paths = paths.map((p) => p.replace(/^\/|\/$/g, "")).filter((p) => p.length > 0);
|
|
75
|
-
if (paths.length === 0) return "/";
|
|
76
|
-
return "/" + paths.join("/");
|
|
77
|
-
}
|
|
78
|
-
function catchBasePath(basepath) {
|
|
79
|
-
if (basepath === "/") return basepath;
|
|
80
|
-
let pattern = new URLPattern({ pathname: basepath + "/*" });
|
|
81
|
-
let match = pattern.exec({ pathname: window.location.pathname });
|
|
82
|
-
if (match) {
|
|
83
|
-
const rawPath = match.pathname.input;
|
|
84
|
-
const restPath = match.pathname.groups?.["0"];
|
|
85
|
-
return restPath ? rawPath.replace("/" + restPath, "") : rawPath.slice(0, -1);
|
|
86
|
-
}
|
|
87
|
-
pattern = new URLPattern({ pathname: `${basepath}{/}?` });
|
|
88
|
-
match = pattern.exec({ pathname: window.location.pathname });
|
|
89
|
-
if (match) {
|
|
90
|
-
return match.pathname.input;
|
|
91
|
-
}
|
|
92
|
-
return basepath;
|
|
93
|
-
}
|
|
94
|
-
var __defProp$1 = Object.defineProperty;
|
|
95
|
-
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
96
|
-
var result = void 0;
|
|
97
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
98
|
-
if (decorator = decorators[i])
|
|
99
|
-
result = decorator(target, key, result) || result;
|
|
100
|
-
if (result) __defProp$1(target, key, result);
|
|
101
|
-
return result;
|
|
102
|
-
};
|
|
103
|
-
const _Link = class _Link extends LitElement {
|
|
104
|
-
constructor() {
|
|
105
|
-
super(...arguments);
|
|
106
|
-
this.isExternal = false;
|
|
107
|
-
this.anchorHref = "#";
|
|
108
|
-
this.handleMouseDown = (event) => {
|
|
109
|
-
const isNonNavigationClick = event.button === 2 || event.metaKey || event.shiftKey || event.altKey;
|
|
110
|
-
if (event.defaultPrevented || isNonNavigationClick) return;
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
event.stopPropagation();
|
|
113
|
-
const basepath = window.history.state?.basepath || "";
|
|
114
|
-
if (event.button === 1 || event.ctrlKey) {
|
|
115
|
-
window.open(this.anchorHref, "_blank");
|
|
116
|
-
} else if (!this.href) {
|
|
117
|
-
this.dispatchPopstate(basepath, basepath);
|
|
118
|
-
} else if (this.isExternal || this.href.startsWith("/") && !this.href.startsWith(basepath)) {
|
|
119
|
-
window.location.href = this.href;
|
|
120
|
-
} else if (this.href.startsWith("#")) {
|
|
121
|
-
const url = window.location.pathname + window.location.search + this.href;
|
|
122
|
-
this.dispatchHashchange(basepath, url);
|
|
123
|
-
} else if (this.href.startsWith("?")) {
|
|
124
|
-
const url = window.location.pathname + this.href;
|
|
125
|
-
this.dispatchPopstate(basepath, url);
|
|
126
|
-
} else {
|
|
127
|
-
const url = absolutePath(basepath, this.href);
|
|
128
|
-
this.dispatchPopstate(basepath, url);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
this.preventClickEvent = (event) => {
|
|
132
|
-
event.preventDefault();
|
|
133
|
-
event.stopPropagation();
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
connectedCallback() {
|
|
137
|
-
super.connectedCallback();
|
|
138
|
-
this.addEventListener("mousedown", this.handleMouseDown);
|
|
139
|
-
}
|
|
140
|
-
disconnectedCallback() {
|
|
141
|
-
this.removeEventListener("mousedown", this.handleMouseDown);
|
|
142
|
-
super.disconnectedCallback();
|
|
143
|
-
}
|
|
144
|
-
async updated(changedProperties) {
|
|
145
|
-
super.updated(changedProperties);
|
|
146
|
-
await this.updateComplete;
|
|
147
|
-
if (changedProperties.has("href")) {
|
|
148
|
-
this.isExternal = isExternalUrl(this.href || "");
|
|
149
|
-
this.anchorHref = this.getAnchorHref(this.href);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
render() {
|
|
153
|
-
return html`
|
|
154
|
-
<a href=${this.anchorHref} @click=${this.preventClickEvent}>
|
|
155
|
-
<slot></slot>
|
|
156
|
-
</a>
|
|
157
|
-
`;
|
|
158
|
-
}
|
|
159
|
-
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด popstate ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
160
|
-
dispatchPopstate(basepath, url) {
|
|
161
|
-
window.history.pushState({ basepath }, "", url);
|
|
162
|
-
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
163
|
-
}
|
|
164
|
-
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด hashchange ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
165
|
-
dispatchHashchange(basepath, url) {
|
|
166
|
-
window.history.pushState({ basepath }, "", url);
|
|
167
|
-
window.dispatchEvent(new HashChangeEvent("hashchange"));
|
|
168
|
-
}
|
|
169
|
-
/** a ํ๊ทธ์ ์ฃผ์
ํ href ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. */
|
|
170
|
-
getAnchorHref(href) {
|
|
171
|
-
const basepath = window.history.state?.basepath || "";
|
|
172
|
-
if (!href) {
|
|
173
|
-
return window.location.origin + basepath;
|
|
174
|
-
}
|
|
175
|
-
if (this.isExternal || href.startsWith("/") || href.startsWith("#") || href.startsWith("?")) {
|
|
176
|
-
return href;
|
|
177
|
-
}
|
|
178
|
-
return absolutePath(basepath, href);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
_Link.styles = css`
|
|
182
|
-
:host {
|
|
183
|
-
display: inline-flex;
|
|
184
|
-
cursor: pointer;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
a {
|
|
188
|
-
display: contents;
|
|
189
|
-
text-decoration: none;
|
|
190
|
-
color: inherit;
|
|
191
|
-
}
|
|
192
|
-
`;
|
|
193
|
-
let Link = _Link;
|
|
194
|
-
__decorateClass$1([
|
|
195
|
-
state()
|
|
196
|
-
], Link.prototype, "anchorHref");
|
|
197
|
-
__decorateClass$1([
|
|
198
|
-
property({ type: String })
|
|
199
|
-
], Link.prototype, "href");
|
|
200
|
-
class Outlet extends LitElement {
|
|
201
|
-
/** ์๋์ฐ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ์ง์ ๋ ๋๋งํฉ๋๋ค. */
|
|
202
|
-
createRenderRoot() {
|
|
203
|
-
return this;
|
|
204
|
-
}
|
|
205
|
-
render() {
|
|
206
|
-
return html`${this.container}`;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* render ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
210
|
-
* - HTMLElement, ReactElement, TemplateResult๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
211
|
-
*/
|
|
212
|
-
async renderContent({ id, content, force }) {
|
|
213
|
-
if (this.routeId === id && force === false && this.container) {
|
|
214
|
-
return this.container;
|
|
215
|
-
}
|
|
216
|
-
this.routeId = id;
|
|
217
|
-
this.clear();
|
|
218
|
-
if (!this.container) {
|
|
219
|
-
throw new Error("Outlet container is not initialized.");
|
|
220
|
-
}
|
|
221
|
-
if (typeof content !== "object") {
|
|
222
|
-
throw new Error("Content is not a valid renderable object.");
|
|
223
|
-
}
|
|
224
|
-
if (content instanceof HTMLElement) {
|
|
225
|
-
this.container.appendChild(content);
|
|
226
|
-
} else if ("_$litType$" in content) {
|
|
227
|
-
this.content = render(content, this.container);
|
|
228
|
-
} else if ("$$typeof" in content) {
|
|
229
|
-
this.content = createRoot(this.container);
|
|
230
|
-
this.content.render(content);
|
|
231
|
-
} else {
|
|
232
|
-
throw new Error("not supported content type for Outlet rendering.");
|
|
233
|
-
}
|
|
234
|
-
this.requestUpdate();
|
|
235
|
-
await this.updateComplete;
|
|
236
|
-
return this.container;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* ๊ธฐ์กด DOM์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ง๊ฒ ์ ๊ฑฐํฉ๋๋ค.
|
|
240
|
-
*/
|
|
241
|
-
clear() {
|
|
242
|
-
if (this.content) {
|
|
243
|
-
if ("unmount" in this.content) {
|
|
244
|
-
this.content.unmount();
|
|
245
|
-
}
|
|
246
|
-
if ("setConnected" in this.content) {
|
|
247
|
-
this.content.setConnected(false);
|
|
248
|
-
}
|
|
249
|
-
this.content = void 0;
|
|
250
|
-
}
|
|
251
|
-
this.container = document.createElement("div");
|
|
252
|
-
this.container.style.display = "contents";
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
customElements.define("u-link", Link);
|
|
256
|
-
customElements.define("u-outlet", Outlet);
|
|
257
|
-
const ULink = o({
|
|
258
|
-
react: React,
|
|
259
|
-
tagName: "u-link",
|
|
260
|
-
elementClass: Link
|
|
261
|
-
});
|
|
262
|
-
const UOutlet = o({
|
|
263
|
-
react: React,
|
|
264
|
-
tagName: "u-outlet",
|
|
265
|
-
elementClass: Outlet
|
|
266
|
-
});
|
|
267
6
|
class RouteError extends Error {
|
|
268
7
|
constructor(code, message, original) {
|
|
269
8
|
super(message);
|
|
@@ -335,100 +74,51 @@ class RouteErrorEvent extends RouteEvent {
|
|
|
335
74
|
this.error = error;
|
|
336
75
|
}
|
|
337
76
|
}
|
|
338
|
-
const ban = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
77
|
+
const ban = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M15 8a6.97 6.97 0 0 0-1.71-4.584l-9.874 9.875A7 7 0 0 0 15 8M2.71 12.584l9.874-9.875a7 7 0 0 0-9.874 9.874ZM16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"/>\n</svg>';
|
|
339
78
|
const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
340
79
|
__proto__: null,
|
|
341
80
|
default: ban
|
|
342
81
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
343
|
-
const boxSeam = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
82
|
+
const boxSeam = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M8.186 1.113a.5.5 0 0 0-.372 0L1.846 3.5l2.404.961L10.404 2zm3.564 1.426L5.596 5 8 5.961 14.154 3.5zm3.25 1.7-6.5 2.6v7.922l6.5-2.6V4.24zM7.5 14.762V6.838L1 4.239v7.923zM7.443.184a1.5 1.5 0 0 1 1.114 0l7.129 2.852A.5.5 0 0 1 16 3.5v8.662a1 1 0 0 1-.629.928l-7.185 2.874a.5.5 0 0 1-.372 0L.63 13.09a1 1 0 0 1-.63-.928V3.5a.5.5 0 0 1 .314-.464z"/>\n</svg>';
|
|
344
83
|
const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
345
84
|
__proto__: null,
|
|
346
85
|
default: boxSeam
|
|
347
86
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
348
|
-
const exclamationTriangle = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
87
|
+
const exclamationTriangle = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.15.15 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.2.2 0 0 1-.054.06.1.1 0 0 1-.066.017H1.146a.1.1 0 0 1-.066-.017.2.2 0 0 1-.054-.06.18.18 0 0 1 .002-.183L7.884 2.073a.15.15 0 0 1 .054-.057m1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767z"/>\n <path d="M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z"/>\n</svg>';
|
|
349
88
|
const __vite_glob_0_2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
350
89
|
__proto__: null,
|
|
351
90
|
default: exclamationTriangle
|
|
352
91
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
353
|
-
const palette = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
92
|
+
const palette = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M8 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3m4 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M5.5 7a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m.5 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3"/>\n <path d="M16 8c0 3.15-1.866 2.585-3.567 2.07C11.42 9.763 10.465 9.473 10 10c-.603.683-.475 1.819-.351 2.92C9.826 14.495 9.996 16 8 16a8 8 0 1 1 8-8m-8 7c.611 0 .654-.171.655-.176.078-.146.124-.464.07-1.119-.014-.168-.037-.37-.061-.591-.052-.464-.112-1.005-.118-1.462-.01-.707.083-1.61.704-2.314.369-.417.845-.578 1.272-.618.404-.038.812.026 1.16.104.343.077.702.186 1.025.284l.028.008c.346.105.658.199.953.266.653.148.904.083.991.024C14.717 9.38 15 9.161 15 8a7 7 0 1 0-7 7"/>\n</svg>';
|
|
354
93
|
const __vite_glob_0_3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
355
94
|
__proto__: null,
|
|
356
95
|
default: palette
|
|
357
96
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
358
|
-
const personLock = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
97
|
+
const personLock = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0M8 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4m0 5.996V14H3s-1 0-1-1 1-4 6-4q.845.002 1.544.107a4.5 4.5 0 0 0-.803.918A11 11 0 0 0 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664zM9 13a1 1 0 0 1 1-1v-1a2 2 0 1 1 4 0v1a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1zm3-3a1 1 0 0 0-1 1v1h2v-1a1 1 0 0 0-1-1"/>\n</svg>';
|
|
359
98
|
const __vite_glob_0_4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
360
99
|
__proto__: null,
|
|
361
100
|
default: personLock
|
|
362
101
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
363
|
-
const search = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
102
|
+
const search = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>\n</svg>';
|
|
364
103
|
const __vite_glob_0_5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
365
104
|
__proto__: null,
|
|
366
105
|
default: search
|
|
367
106
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
368
|
-
const stopwatch = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
107
|
+
const stopwatch = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M8.5 5.6a.5.5 0 1 0-1 0v2.9h-3a.5.5 0 0 0 0 1H8a.5.5 0 0 0 .5-.5z"/>\n <path d="M6.5 1A.5.5 0 0 1 7 .5h2a.5.5 0 0 1 0 1v.57c1.36.196 2.594.78 3.584 1.64l.012-.013.354-.354-.354-.353a.5.5 0 0 1 .707-.708l1.414 1.415a.5.5 0 1 1-.707.707l-.353-.354-.354.354-.013.012A7 7 0 1 1 7 2.071V1.5a.5.5 0 0 1-.5-.5M8 3a6 6 0 1 0 .001 12A6 6 0 0 0 8 3"/>\n</svg>';
|
|
369
108
|
const __vite_glob_0_6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
370
109
|
__proto__: null,
|
|
371
110
|
default: stopwatch
|
|
372
111
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
373
|
-
const wifiOff = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
112
|
+
const wifiOff = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M10.706 3.294A12.6 12.6 0 0 0 8 3C5.259 3 2.723 3.882.663 5.379a.485.485 0 0 0-.048.736.52.52 0 0 0 .668.05A11.45 11.45 0 0 1 8 4q.946 0 1.852.148zM8 6c-1.905 0-3.68.56-5.166 1.526a.48.48 0 0 0-.063.745.525.525 0 0 0 .652.065 8.45 8.45 0 0 1 3.51-1.27zm2.596 1.404.785-.785q.947.362 1.785.907a.482.482 0 0 1 .063.745.525.525 0 0 1-.652.065 8.5 8.5 0 0 0-1.98-.932zM8 10l.933-.933a6.5 6.5 0 0 1 2.013.637c.285.145.326.524.1.75l-.015.015a.53.53 0 0 1-.611.09A5.5 5.5 0 0 0 8 10m4.905-4.905.747-.747q.886.451 1.685 1.03a.485.485 0 0 1 .047.737.52.52 0 0 1-.668.05 11.5 11.5 0 0 0-1.811-1.07M9.02 11.78c.238.14.236.464.04.66l-.707.706a.5.5 0 0 1-.707 0l-.707-.707c-.195-.195-.197-.518.04-.66A2 2 0 0 1 8 11.5c.374 0 .723.102 1.021.28zm4.355-9.905a.53.53 0 0 1 .75.75l-10.75 10.75a.53.53 0 0 1-.75-.75z"/>\n</svg>';
|
|
374
113
|
const __vite_glob_0_7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
375
114
|
__proto__: null,
|
|
376
115
|
default: wifiOff
|
|
377
116
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
378
|
-
const wrenchAdjustable = '<svg xmlns="http://www.w3.org/2000/svg"
|
|
117
|
+
const wrenchAdjustable = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\n <path d="M16 4.5a4.5 4.5 0 0 1-1.703 3.526L13 5l2.959-1.11q.04.3.041.61"/>\n <path d="M11.5 9c.653 0 1.273-.139 1.833-.39L12 5.5 11 3l3.826-1.53A4.5 4.5 0 0 0 7.29 6.092l-6.116 5.096a2.583 2.583 0 1 0 3.638 3.638L9.908 8.71A4.5 4.5 0 0 0 11.5 9m-1.292-4.361-.596.893.809-.27a.25.25 0 0 1 .287.377l-.596.893.809-.27.158.475-1.5.5a.25.25 0 0 1-.287-.376l.596-.893-.809.27a.25.25 0 0 1-.287-.377l.596-.893-.809.27-.158-.475 1.5-.5a.25.25 0 0 1 .287.376M3 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2"/>\n</svg>';
|
|
379
118
|
const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
380
119
|
__proto__: null,
|
|
381
120
|
default: wrenchAdjustable
|
|
382
121
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
383
|
-
const styles = css`
|
|
384
|
-
:host {
|
|
385
|
-
display: flex;
|
|
386
|
-
flex-direction: column;
|
|
387
|
-
justify-content: center;
|
|
388
|
-
align-items: center;
|
|
389
|
-
min-height: 100vh;
|
|
390
|
-
width: 100%;
|
|
391
|
-
text-align: center;
|
|
392
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
393
|
-
overflow: auto;
|
|
394
|
-
user-select: none;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.icon {
|
|
398
|
-
display: contents;
|
|
399
|
-
font-size: 6rem;
|
|
400
|
-
color: var(--route-error-color, #4a5568);
|
|
401
|
-
opacity: 0.85;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
.code {
|
|
405
|
-
font-size: 2rem;
|
|
406
|
-
font-weight: 700;
|
|
407
|
-
margin: 1rem 0;
|
|
408
|
-
color: var(--route-error-code-color, #1a202c);
|
|
409
|
-
letter-spacing: -0.5px;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
.message {
|
|
413
|
-
font-size: 1rem;
|
|
414
|
-
color: var(--route-error-message-color, #718096);
|
|
415
|
-
max-width: 600px;
|
|
416
|
-
line-height: 1.6;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
@media (prefers-color-scheme: dark) {
|
|
420
|
-
.icon {
|
|
421
|
-
color: var(--route-error-dark-color, #a0aec0);
|
|
422
|
-
opacity: 0.9;
|
|
423
|
-
}
|
|
424
|
-
.code {
|
|
425
|
-
color: var(--route-error-dark-code-color, #f7fafc);
|
|
426
|
-
}
|
|
427
|
-
.message {
|
|
428
|
-
color: var(--route-error-dark-message-color, #cbd5e0);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
`;
|
|
432
122
|
var __defProp = Object.defineProperty;
|
|
433
123
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
434
124
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -454,7 +144,7 @@ const icons = Object.entries(/* @__PURE__ */ Object.assign({
|
|
|
454
144
|
acc[name] = content.default;
|
|
455
145
|
return acc;
|
|
456
146
|
}, {});
|
|
457
|
-
let
|
|
147
|
+
let UErrorPage = class extends LitElement {
|
|
458
148
|
render() {
|
|
459
149
|
const error = this.error || this.getDefaultError();
|
|
460
150
|
const icon = this.getErrorIcon(error.code);
|
|
@@ -496,13 +186,73 @@ let ErrorPage = class extends LitElement {
|
|
|
496
186
|
}
|
|
497
187
|
}
|
|
498
188
|
};
|
|
499
|
-
|
|
189
|
+
UErrorPage.styles = css`
|
|
190
|
+
:host {
|
|
191
|
+
--route-icon-color: #4a5568;
|
|
192
|
+
--route-code-color: #1a202c;
|
|
193
|
+
--route-message-color: #718096;
|
|
194
|
+
}
|
|
195
|
+
:host-context([theme="dark"]) {
|
|
196
|
+
--route-icon-color: #a0aec0;
|
|
197
|
+
--route-code-color: #f7fafc;
|
|
198
|
+
--route-message-color: #cbd5e0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@media (prefers-color-scheme: dark) {
|
|
202
|
+
:host {
|
|
203
|
+
--route-icon-color: #a0aec0;
|
|
204
|
+
--route-code-color: #f7fafc;
|
|
205
|
+
--route-message-color: #cbd5e0;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
:host {
|
|
210
|
+
display: flex;
|
|
211
|
+
flex-direction: column;
|
|
212
|
+
justify-content: center;
|
|
213
|
+
align-items: center;
|
|
214
|
+
min-height: 100vh;
|
|
215
|
+
width: 100%;
|
|
216
|
+
text-align: center;
|
|
217
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
218
|
+
overflow: auto;
|
|
219
|
+
user-select: none;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.icon {
|
|
223
|
+
display: contents;
|
|
224
|
+
font-size: 6rem;
|
|
225
|
+
color: var(--route-icon-color);
|
|
226
|
+
opacity: 0.85;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
svg {
|
|
230
|
+
width: 1em;
|
|
231
|
+
height: 1em;
|
|
232
|
+
fill: currentColor;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.code {
|
|
236
|
+
font-size: 2rem;
|
|
237
|
+
font-weight: 700;
|
|
238
|
+
margin: 1rem 0;
|
|
239
|
+
color: var(--route-code-color);
|
|
240
|
+
letter-spacing: -0.5px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.message {
|
|
244
|
+
font-size: 1rem;
|
|
245
|
+
color: var(--route-message-color);
|
|
246
|
+
max-width: 600px;
|
|
247
|
+
line-height: 1.6;
|
|
248
|
+
}
|
|
249
|
+
`;
|
|
500
250
|
__decorateClass([
|
|
501
251
|
property({ type: Object })
|
|
502
|
-
],
|
|
503
|
-
|
|
252
|
+
], UErrorPage.prototype, "error", 2);
|
|
253
|
+
UErrorPage = __decorateClass([
|
|
504
254
|
customElement("u-error-page")
|
|
505
|
-
],
|
|
255
|
+
], UErrorPage);
|
|
506
256
|
function getRandomID() {
|
|
507
257
|
return window.isSecureContext ? window.crypto.randomUUID() : window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16);
|
|
508
258
|
}
|
|
@@ -532,15 +282,24 @@ function findOutletOrThrow(element) {
|
|
|
532
282
|
}
|
|
533
283
|
return outlet;
|
|
534
284
|
}
|
|
535
|
-
function
|
|
536
|
-
const
|
|
285
|
+
async function waitOutlet(element, timeout = 1e4) {
|
|
286
|
+
const start = performance.now();
|
|
287
|
+
while (performance.now() - start < timeout) {
|
|
288
|
+
const outlet = findOutlet(element);
|
|
289
|
+
if (outlet) return outlet;
|
|
290
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
291
|
+
}
|
|
292
|
+
throw new Error("Timed out waiting for u-outlet.");
|
|
293
|
+
}
|
|
294
|
+
function findAnchorFrom(event) {
|
|
295
|
+
const targets = event.composedPath() || [];
|
|
537
296
|
if (targets && targets.length) {
|
|
538
297
|
for (const node of targets) {
|
|
539
298
|
if (!(node instanceof Element)) continue;
|
|
540
299
|
if (node.tagName === "A") return node;
|
|
541
300
|
}
|
|
542
301
|
}
|
|
543
|
-
const tgt =
|
|
302
|
+
const tgt = event.target;
|
|
544
303
|
if (!tgt) return null;
|
|
545
304
|
const anchor = tgt.closest("a");
|
|
546
305
|
return anchor;
|
|
@@ -600,11 +359,11 @@ class Router {
|
|
|
600
359
|
const href = window.location.href;
|
|
601
360
|
await this.go(href);
|
|
602
361
|
};
|
|
603
|
-
this.
|
|
362
|
+
this.handleDocumentClick = (e) => {
|
|
604
363
|
try {
|
|
605
|
-
if (
|
|
606
|
-
if (
|
|
607
|
-
const anchor =
|
|
364
|
+
if (e.defaultPrevented) return;
|
|
365
|
+
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey) return;
|
|
366
|
+
const anchor = findAnchorFrom(e);
|
|
608
367
|
if (!anchor) return;
|
|
609
368
|
const href = anchor.getAttribute("href") || anchor.href;
|
|
610
369
|
if (!href) return;
|
|
@@ -612,7 +371,7 @@ class Router {
|
|
|
612
371
|
if (anchor.hasAttribute("download")) return;
|
|
613
372
|
if (anchor.getAttribute("rel") === "external") return;
|
|
614
373
|
if (anchor.target && anchor.target !== "") return;
|
|
615
|
-
|
|
374
|
+
e.preventDefault();
|
|
616
375
|
void this.go(anchor.href);
|
|
617
376
|
} catch {
|
|
618
377
|
}
|
|
@@ -624,17 +383,19 @@ class Router {
|
|
|
624
383
|
window.removeEventListener("popstate", this.handleWindowPopstate);
|
|
625
384
|
window.addEventListener("popstate", this.handleWindowPopstate);
|
|
626
385
|
if (config.useIntercept !== false) {
|
|
627
|
-
|
|
628
|
-
|
|
386
|
+
document.removeEventListener("click", this.handleDocumentClick);
|
|
387
|
+
document.addEventListener("click", this.handleDocumentClick);
|
|
629
388
|
}
|
|
630
389
|
if (config.initialLoad !== false) {
|
|
631
|
-
void this.
|
|
390
|
+
void waitOutlet(this._rootElement).then(() => {
|
|
391
|
+
this.go(window.location.href);
|
|
392
|
+
});
|
|
632
393
|
}
|
|
633
394
|
}
|
|
634
395
|
/** ๊ฐ์ฒด๋ฅผ ์ ๋ฆฌํ๊ณ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๊ฑฐํฉ๋๋ค. */
|
|
635
396
|
destroy() {
|
|
636
397
|
window.removeEventListener("popstate", this.handleWindowPopstate);
|
|
637
|
-
|
|
398
|
+
document.removeEventListener("click", this.handleDocumentClick);
|
|
638
399
|
this._requestID = void 0;
|
|
639
400
|
this._context = void 0;
|
|
640
401
|
}
|
|
@@ -721,7 +482,7 @@ class Router {
|
|
|
721
482
|
outlet.renderContent({ id: "#fallback", content: fallbackContent, force: true });
|
|
722
483
|
document.title = this._fallback.title || document.title;
|
|
723
484
|
} else {
|
|
724
|
-
const errorContent = new
|
|
485
|
+
const errorContent = new UErrorPage();
|
|
725
486
|
errorContent.error = error;
|
|
726
487
|
if (outlet) {
|
|
727
488
|
outlet.renderContent({ id: "#error", content: errorContent, force: true });
|
|
@@ -740,9 +501,7 @@ class Router {
|
|
|
740
501
|
export {
|
|
741
502
|
ContentLoadError,
|
|
742
503
|
ContentRenderError,
|
|
743
|
-
Link,
|
|
744
504
|
NotFoundError,
|
|
745
|
-
Outlet,
|
|
746
505
|
OutletMissingError,
|
|
747
506
|
RouteBeginEvent,
|
|
748
507
|
RouteDoneEvent,
|
|
@@ -750,6 +509,6 @@ export {
|
|
|
750
509
|
RouteErrorEvent,
|
|
751
510
|
RouteProgressEvent,
|
|
752
511
|
Router,
|
|
753
|
-
ULink,
|
|
754
|
-
UOutlet
|
|
512
|
+
b as ULink,
|
|
513
|
+
U as UOutlet
|
|
755
514
|
};
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { CSSResult } from 'lit';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
import { PropertyValues } from 'lit';
|
|
4
|
+
import { ReactElement } from 'react';
|
|
5
|
+
import { ReactWebComponent } from '@lit/react';
|
|
6
|
+
import { TemplateResult } from 'lit-html';
|
|
7
|
+
import { TemplateResult as TemplateResult_2 } from 'lit';
|
|
8
|
+
|
|
9
|
+
declare interface RenderOption {
|
|
10
|
+
id?: string;
|
|
11
|
+
force?: boolean;
|
|
12
|
+
content: RenderResult;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare type RenderResult = HTMLElement | ReactElement | TemplateResult_2<1> | false;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* `u-link` ์น ์ปดํฌ๋ํธ๋ฅผ React์์ ์ฌ์ฉํ ์ ์๋๋ก ๋ํํ ์ปดํฌ๋ํธ์
๋๋ค.
|
|
19
|
+
*/
|
|
20
|
+
export declare const ULink: ReactWebComponent<ULink_2, {}>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* - ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ง์ํ๋ ๋งํฌ ์๋ฆฌ๋จผํธ์
๋๋ค.
|
|
24
|
+
* - ๋ด๋ถ ๋งํฌ๋ ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํํ๊ณ , ์ธ๋ถ ๋งํฌ๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋ค๋น๊ฒ์ด์
์ ์ฌ์ฉํฉ๋๋ค.
|
|
25
|
+
* - Ctrl/Meta/Shift/Alt, ์คํด๋ฆญ/์ฐํด๋ฆญ ๋ฑ์ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์(์ ํญ, ์ปจํ
์คํธ ๋ฉ๋ด ๋ฑ)์ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค.
|
|
26
|
+
*/
|
|
27
|
+
declare class ULink_2 extends LitElement {
|
|
28
|
+
/** ์ธ๋ถ ๋งํฌ ์ฌ๋ถ */
|
|
29
|
+
private isExternal;
|
|
30
|
+
/**
|
|
31
|
+
* a ํ๊ทธ target์ ์ง์ํ๊ณ ์ถ์ผ๋ฉด ์ด์ด๋๋๊ฒ ์ข์ต๋๋ค.
|
|
32
|
+
* - _blank ๋ฑ์ ์ฐ๋ฉด ๋ฌด์กฐ๊ฑด ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์์ ๋ฐ๋ฅด๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.
|
|
33
|
+
*/
|
|
34
|
+
target?: string;
|
|
35
|
+
/**
|
|
36
|
+
* - ์์ฑ์ ์ ์ํ์ง ์์ผ๋ฉด basepath๋ก ์ด๋ํฉ๋๋ค.
|
|
37
|
+
* - http(s)๋ก ์์ํ๋ฉด ์ธ๋ถ ๋งํฌ๋ก ๊ฐ์ฃผํ๊ณ ๋ธ๋ผ์ฐ์ ๋ค๋น๊ฒ์ด์
์ ์ฌ์ฉํฉ๋๋ค.
|
|
38
|
+
* - ์ ๋๊ฒฝ๋ก(/...)์ผ ๊ฒฝ์ฐ basepath๋ก ์์ํ๋ฉด SPA ๋ผ์ฐํ
๋์์ด ๋ ์ ์์ต๋๋ค.
|
|
39
|
+
* - ์๋๊ฒฝ๋ก๋ (basepath + ์๋๊ฒฝ๋ก)๋ก SPA ๋ผ์ฐํ
๋์์ด ๋ ์ ์์ต๋๋ค.
|
|
40
|
+
* - ?๋ก ์์ํ๋ฉด ํ์ฌ pathname์ ์ฟผ๋ฆฌ์คํธ๋ง์ ๋ถ์ฌ SPA ๋ผ์ฐํ
ํฉ๋๋ค.
|
|
41
|
+
* - #์ผ๋ก ์์ํ๋ฉด ํ์ฌ URL์ ํด์๋ง ๋ฐ๊พธ๊ณ (๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ) ๋์ํฉ๋๋ค.
|
|
42
|
+
*/
|
|
43
|
+
href?: string;
|
|
44
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
45
|
+
render(): TemplateResult<1>;
|
|
46
|
+
/** basepath๋ฅผ state์์ ๊บผ๋ด๋ ํฌํผ */
|
|
47
|
+
private getBasepath;
|
|
48
|
+
/** a ํ๊ทธ์ ์ฃผ์
ํ href ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. */
|
|
49
|
+
private computeHref;
|
|
50
|
+
/**
|
|
51
|
+
* ํด๋ฆญ ๊ฐ๋ก์ฑ๊ธฐ ๊ท์น
|
|
52
|
+
* - ์ขํด๋ฆญ(0) + ๋ณด์กฐํค ์์(ctrl/meta/shift/alt ์์) + target์ด _self์ผ ๋๋ง SPA ๋ผ์ฐํ
๊ณ ๋ ค
|
|
53
|
+
* - ๊ทธ ์ธ(์คํด๋ฆญ/์ฐํด๋ฆญ/๋ณด์กฐํค/target=_blank ๋ฑ)๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋์ ์ ์ง
|
|
54
|
+
*/
|
|
55
|
+
private handleAnchorClick;
|
|
56
|
+
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด popstate ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
57
|
+
private dispatchPopstate;
|
|
58
|
+
static styles: CSSResult;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* `u-outlet` ์น ์ปดํฌ๋ํธ๋ฅผ React์์ ์ฌ์ฉํ ์ ์๋๋ก ๋ํํ ์ปดํฌ๋ํธ์
๋๋ค.
|
|
63
|
+
*/
|
|
64
|
+
export declare const UOutlet: ReactWebComponent<UOutlet_2, {}>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* ๋ผ์ฐํธ ์ค์ ์ ๋ฐ๋ผ LitElement ๋๋ React ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
68
|
+
*/
|
|
69
|
+
declare class UOutlet_2 extends LitElement {
|
|
70
|
+
private routeId?;
|
|
71
|
+
private container?;
|
|
72
|
+
private content?;
|
|
73
|
+
/** ์ธ๋ถ ์คํ์ผ์ ์ ์ฉํ๊ธฐ ์ํด ๋ผ์ดํธ ๋์์ฌ์ฉ ํฉ๋๋ค. */
|
|
74
|
+
protected createRenderRoot(): this;
|
|
75
|
+
/** ์ปดํฌ๋ํธ๊ฐ DOM์ ์ฐ๊ฒฐ๋ ๋ ์ด๊ธฐํ ์์
์ํ */
|
|
76
|
+
connectedCallback(): void;
|
|
77
|
+
render(): TemplateResult_2<1>;
|
|
78
|
+
/**
|
|
79
|
+
* render ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
80
|
+
* - HTMLElement, ReactElement, TemplateResult๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
81
|
+
*/
|
|
82
|
+
renderContent({ id, content, force }: RenderOption): Promise<HTMLDivElement>;
|
|
83
|
+
/**
|
|
84
|
+
* ๊ธฐ์กด DOM์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ง๊ฒ ์ ๊ฑฐํฉ๋๋ค.
|
|
85
|
+
*/
|
|
86
|
+
clear(): void;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { }
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { b as ULink$1, U as UOutlet$1 } from "./share-SPj-xl6y.js";
|
|
3
|
+
const e = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), n = /* @__PURE__ */ new WeakMap(), t = (e2, t2, o2, l, a) => {
|
|
4
|
+
const s = a?.[t2];
|
|
5
|
+
void 0 === s ? (e2[t2] = o2, null == o2 && t2 in HTMLElement.prototype && e2.removeAttribute(t2)) : o2 !== l && ((e3, t3, o3) => {
|
|
6
|
+
let l2 = n.get(e3);
|
|
7
|
+
void 0 === l2 && n.set(e3, l2 = /* @__PURE__ */ new Map());
|
|
8
|
+
let a2 = l2.get(t3);
|
|
9
|
+
void 0 !== o3 ? void 0 === a2 ? (l2.set(t3, a2 = { handleEvent: o3 }), e3.addEventListener(t3, a2)) : a2.handleEvent = o3 : void 0 !== a2 && (l2.delete(t3), e3.removeEventListener(t3, a2));
|
|
10
|
+
})(e2, s, o2);
|
|
11
|
+
}, o = ({ react: n2, tagName: o2, elementClass: l, events: a, displayName: s }) => {
|
|
12
|
+
const c = new Set(Object.keys(a ?? {})), r = n2.forwardRef(((s2, r2) => {
|
|
13
|
+
const i = n2.useRef(/* @__PURE__ */ new Map()), d = n2.useRef(null), f = {}, u = {};
|
|
14
|
+
for (const [n3, t2] of Object.entries(s2)) e.has(n3) ? f["className" === n3 ? "class" : n3] = t2 : c.has(n3) || n3 in l.prototype ? u[n3] = t2 : f[n3] = t2;
|
|
15
|
+
return n2.useLayoutEffect((() => {
|
|
16
|
+
if (null === d.current) return;
|
|
17
|
+
const e2 = /* @__PURE__ */ new Map();
|
|
18
|
+
for (const n3 in u) t(d.current, n3, s2[n3], i.current.get(n3), a), i.current.delete(n3), e2.set(n3, s2[n3]);
|
|
19
|
+
for (const [e3, n3] of i.current) t(d.current, e3, void 0, n3, a);
|
|
20
|
+
i.current = e2;
|
|
21
|
+
})), n2.useLayoutEffect((() => {
|
|
22
|
+
d.current?.removeAttribute("defer-hydration");
|
|
23
|
+
}), []), f.suppressHydrationWarning = true, n2.createElement(o2, { ...f, ref: n2.useCallback(((e2) => {
|
|
24
|
+
d.current = e2, "function" == typeof r2 ? r2(e2) : null !== r2 && (r2.current = e2);
|
|
25
|
+
}), [r2]) });
|
|
26
|
+
}));
|
|
27
|
+
return r.displayName = s ?? l.name, r;
|
|
28
|
+
};
|
|
29
|
+
const ULink = o({
|
|
30
|
+
react: React,
|
|
31
|
+
tagName: "u-link",
|
|
32
|
+
elementClass: ULink$1,
|
|
33
|
+
events: {}
|
|
34
|
+
});
|
|
35
|
+
const UOutlet = o({
|
|
36
|
+
react: React,
|
|
37
|
+
tagName: "u-outlet",
|
|
38
|
+
elementClass: UOutlet$1,
|
|
39
|
+
events: {}
|
|
40
|
+
});
|
|
41
|
+
export {
|
|
42
|
+
ULink,
|
|
43
|
+
UOutlet
|
|
44
|
+
};
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { LitElement, html, render, css } from "lit";
|
|
2
|
+
import { customElement, property } from "lit/decorators.js";
|
|
3
|
+
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
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* render ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
|
|
30
|
+
* - HTMLElement, ReactElement, TemplateResult๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
|
|
31
|
+
*/
|
|
32
|
+
async renderContent({ id, content, force }) {
|
|
33
|
+
if (this.routeId === id && force === false && this.container) {
|
|
34
|
+
return this.container;
|
|
35
|
+
}
|
|
36
|
+
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") {
|
|
42
|
+
throw new Error("Content is not a valid renderable object.");
|
|
43
|
+
}
|
|
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);
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error("not supported content type for Outlet rendering.");
|
|
53
|
+
}
|
|
54
|
+
this.requestUpdate();
|
|
55
|
+
await this.updateComplete;
|
|
56
|
+
return this.container;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* ๊ธฐ์กด DOM์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ง๊ฒ ์ ๊ฑฐํฉ๋๋ค.
|
|
60
|
+
*/
|
|
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;
|
|
70
|
+
}
|
|
71
|
+
this.container = document.createElement("div");
|
|
72
|
+
this.container.style.display = "contents";
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
UOutlet = __decorateClass$1([
|
|
76
|
+
customElement("u-outlet")
|
|
77
|
+
], UOutlet);
|
|
78
|
+
function isExternalUrl(url) {
|
|
79
|
+
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;
|
|
83
|
+
try {
|
|
84
|
+
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;
|
|
87
|
+
return parsed.origin !== new URL(base).origin;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function parseUrl(url, basepath) {
|
|
93
|
+
let urlObj;
|
|
94
|
+
basepath = catchBasePath(basepath);
|
|
95
|
+
if (url.startsWith("http")) {
|
|
96
|
+
urlObj = new URL(url);
|
|
97
|
+
} else if (url.startsWith("/")) {
|
|
98
|
+
urlObj = new URL(url, window.location.origin);
|
|
99
|
+
} else if (url.startsWith("?")) {
|
|
100
|
+
urlObj = new URL(window.location.pathname + url, window.location.origin);
|
|
101
|
+
} else if (url.startsWith("#")) {
|
|
102
|
+
urlObj = new URL(window.location.pathname + window.location.search + url, window.location.origin);
|
|
103
|
+
} else {
|
|
104
|
+
urlObj = new URL(absolutePath(basepath, url), window.location.origin);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
href: urlObj.href,
|
|
108
|
+
origin: urlObj.origin,
|
|
109
|
+
basepath,
|
|
110
|
+
path: urlObj.href.replace(urlObj.origin, ""),
|
|
111
|
+
pathname: urlObj.pathname,
|
|
112
|
+
query: new URLSearchParams(urlObj.search),
|
|
113
|
+
hash: urlObj.hash,
|
|
114
|
+
params: {},
|
|
115
|
+
progress: () => {
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function absolutePath(...paths) {
|
|
120
|
+
paths = paths.map((p) => p.replace(/^\/|\/$/g, "")).filter((p) => p.length > 0);
|
|
121
|
+
if (paths.length === 0) return "/";
|
|
122
|
+
return "/" + paths.join("/");
|
|
123
|
+
}
|
|
124
|
+
function catchBasePath(basepath) {
|
|
125
|
+
if (basepath === "/") return basepath;
|
|
126
|
+
let pattern = new URLPattern({ pathname: basepath + "/*" });
|
|
127
|
+
let match = pattern.exec({ pathname: window.location.pathname });
|
|
128
|
+
if (match) {
|
|
129
|
+
const rawPath = match.pathname.input;
|
|
130
|
+
const restPath = match.pathname.groups?.["0"];
|
|
131
|
+
return restPath ? rawPath.replace("/" + restPath, "") : rawPath.slice(0, -1);
|
|
132
|
+
}
|
|
133
|
+
pattern = new URLPattern({ pathname: `${basepath}{/}?` });
|
|
134
|
+
match = pattern.exec({ pathname: window.location.pathname });
|
|
135
|
+
if (match) {
|
|
136
|
+
return match.pathname.input;
|
|
137
|
+
}
|
|
138
|
+
return basepath;
|
|
139
|
+
}
|
|
140
|
+
var __defProp = Object.defineProperty;
|
|
141
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
142
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
143
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
144
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
145
|
+
if (decorator = decorators[i])
|
|
146
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
147
|
+
if (kind && result) __defProp(target, key, result);
|
|
148
|
+
return result;
|
|
149
|
+
};
|
|
150
|
+
let ULink = class extends LitElement {
|
|
151
|
+
constructor() {
|
|
152
|
+
super(...arguments);
|
|
153
|
+
this.isExternal = false;
|
|
154
|
+
this.handleAnchorClick = (event) => {
|
|
155
|
+
if (event.defaultPrevented) return;
|
|
156
|
+
if (event.button !== 0) return;
|
|
157
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
158
|
+
const target = (this.target ?? "").trim();
|
|
159
|
+
if (target && target.toLowerCase() !== "_self") return;
|
|
160
|
+
const basepath = this.getBasepath();
|
|
161
|
+
if (!this.href) {
|
|
162
|
+
event.preventDefault();
|
|
163
|
+
this.dispatchPopstate(basepath, basepath);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (this.isExternal) return;
|
|
167
|
+
if (this.href.startsWith("#")) return;
|
|
168
|
+
event.preventDefault();
|
|
169
|
+
if (this.href.startsWith("?")) {
|
|
170
|
+
const url2 = window.location.pathname + this.href;
|
|
171
|
+
this.dispatchPopstate(basepath, url2);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (this.href.startsWith("/")) {
|
|
175
|
+
if (!this.href.startsWith(basepath)) {
|
|
176
|
+
window.location.assign(this.href);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
this.dispatchPopstate(basepath, this.href);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const url = absolutePath(basepath, this.href);
|
|
183
|
+
this.dispatchPopstate(basepath, url);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
willUpdate(changedProperties) {
|
|
187
|
+
super.willUpdate(changedProperties);
|
|
188
|
+
if (changedProperties.has("href")) {
|
|
189
|
+
this.isExternal = isExternalUrl(this.href || "");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
render() {
|
|
193
|
+
return html`
|
|
194
|
+
<a
|
|
195
|
+
target=${this.target ?? "_self"}
|
|
196
|
+
href=${this.computeHref(this.href)}
|
|
197
|
+
@click=${this.handleAnchorClick}>
|
|
198
|
+
<slot></slot>
|
|
199
|
+
</a>
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
/** basepath๋ฅผ state์์ ๊บผ๋ด๋ ํฌํผ */
|
|
203
|
+
getBasepath() {
|
|
204
|
+
return window.history.state?.basepath || "";
|
|
205
|
+
}
|
|
206
|
+
/** a ํ๊ทธ์ ์ฃผ์
ํ href ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. */
|
|
207
|
+
computeHref(href) {
|
|
208
|
+
const basepath = this.getBasepath();
|
|
209
|
+
if (!href) {
|
|
210
|
+
return window.location.origin + basepath;
|
|
211
|
+
}
|
|
212
|
+
if (this.isExternal) return href;
|
|
213
|
+
if (href.startsWith("#") || href.startsWith("?")) return href;
|
|
214
|
+
if (href.startsWith("/")) return href;
|
|
215
|
+
return absolutePath(basepath, href);
|
|
216
|
+
}
|
|
217
|
+
/** ํด๋ผ์ด์ธํธ ๋ผ์ฐํ
์ ์ํด popstate ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค. */
|
|
218
|
+
dispatchPopstate(basepath, url) {
|
|
219
|
+
window.history.pushState({ basepath }, "", url);
|
|
220
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
ULink.styles = css`
|
|
224
|
+
:host {
|
|
225
|
+
display: inline-flex;
|
|
226
|
+
cursor: pointer;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
a {
|
|
230
|
+
display: contents;
|
|
231
|
+
text-decoration: none;
|
|
232
|
+
|
|
233
|
+
font-size: inherit;
|
|
234
|
+
font-weight: inherit;
|
|
235
|
+
font-family: inherit;
|
|
236
|
+
color: inherit;
|
|
237
|
+
cursor: inherit;
|
|
238
|
+
}
|
|
239
|
+
`;
|
|
240
|
+
__decorateClass([
|
|
241
|
+
property({ type: String })
|
|
242
|
+
], ULink.prototype, "target", 2);
|
|
243
|
+
__decorateClass([
|
|
244
|
+
property({ type: String })
|
|
245
|
+
], ULink.prototype, "href", 2);
|
|
246
|
+
ULink = __decorateClass([
|
|
247
|
+
customElement("u-link")
|
|
248
|
+
], ULink);
|
|
249
|
+
export {
|
|
250
|
+
UOutlet as U,
|
|
251
|
+
absolutePath as a,
|
|
252
|
+
ULink as b,
|
|
253
|
+
isExternalUrl as i,
|
|
254
|
+
parseUrl as p
|
|
255
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "A modern client-side router for web applications with support for Lit and React components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lit",
|
|
@@ -29,23 +29,28 @@
|
|
|
29
29
|
".": {
|
|
30
30
|
"types": "./dist/index.d.ts",
|
|
31
31
|
"import": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./react": {
|
|
34
|
+
"types": "./dist/react.d.ts",
|
|
35
|
+
"import": "./dist/react.js"
|
|
32
36
|
}
|
|
33
37
|
},
|
|
34
38
|
"scripts": {
|
|
39
|
+
"test": "vite",
|
|
35
40
|
"build": "vite build"
|
|
36
41
|
},
|
|
37
42
|
"dependencies": {
|
|
38
|
-
"lit": "^3.3.
|
|
39
|
-
"react": "^19.2.
|
|
40
|
-
"react-dom": "^19.2.
|
|
43
|
+
"lit": "^3.3.2",
|
|
44
|
+
"react": "^19.2.3",
|
|
45
|
+
"react-dom": "^19.2.3"
|
|
41
46
|
},
|
|
42
47
|
"devDependencies": {
|
|
43
48
|
"@lit/react": "^1.0.8",
|
|
44
|
-
"@types/node": "^
|
|
45
|
-
"@types/react": "^19.2.
|
|
49
|
+
"@types/node": "^25.0.9",
|
|
50
|
+
"@types/react": "^19.2.8",
|
|
46
51
|
"@types/react-dom": "^19.2.3",
|
|
47
52
|
"typescript": "^5.9.3",
|
|
48
|
-
"vite": "^7.
|
|
53
|
+
"vite": "^7.3.1",
|
|
49
54
|
"vite-plugin-dts": "^4.5.4"
|
|
50
55
|
}
|
|
51
|
-
}
|
|
56
|
+
}
|