@furystack/shades 11.1.0 → 12.0.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/CHANGELOG.md +312 -0
- package/README.md +13 -13
- package/esm/component-factory.spec.js +13 -5
- package/esm/component-factory.spec.js.map +1 -1
- package/esm/components/index.d.ts +4 -1
- package/esm/components/index.d.ts.map +1 -1
- package/esm/components/index.js +4 -1
- package/esm/components/index.js.map +1 -1
- package/esm/components/lazy-load.d.ts +2 -4
- package/esm/components/lazy-load.d.ts.map +1 -1
- package/esm/components/lazy-load.js +40 -24
- package/esm/components/lazy-load.js.map +1 -1
- package/esm/components/lazy-load.spec.js +57 -50
- package/esm/components/lazy-load.spec.js.map +1 -1
- package/esm/components/link-to-route.d.ts +2 -0
- package/esm/components/link-to-route.d.ts.map +1 -1
- package/esm/components/link-to-route.js +3 -2
- package/esm/components/link-to-route.js.map +1 -1
- package/esm/components/link-to-route.spec.js +13 -9
- package/esm/components/link-to-route.spec.js.map +1 -1
- package/esm/components/nested-route-link.d.ts +62 -0
- package/esm/components/nested-route-link.d.ts.map +1 -0
- package/esm/components/nested-route-link.js +66 -0
- package/esm/components/nested-route-link.js.map +1 -0
- package/esm/components/nested-route-link.spec.d.ts +2 -0
- package/esm/components/nested-route-link.spec.d.ts.map +1 -0
- package/esm/components/nested-route-link.spec.js +179 -0
- package/esm/components/nested-route-link.spec.js.map +1 -0
- package/esm/components/nested-route-types.d.ts +37 -0
- package/esm/components/nested-route-types.d.ts.map +1 -0
- package/esm/components/nested-route-types.js +2 -0
- package/esm/components/nested-route-types.js.map +1 -0
- package/esm/components/nested-router.d.ts +103 -0
- package/esm/components/nested-router.d.ts.map +1 -0
- package/esm/components/nested-router.js +183 -0
- package/esm/components/nested-router.js.map +1 -0
- package/esm/components/nested-router.spec.d.ts +2 -0
- package/esm/components/nested-router.spec.d.ts.map +1 -0
- package/esm/components/nested-router.spec.js +737 -0
- package/esm/components/nested-router.spec.js.map +1 -0
- package/esm/components/route-link.d.ts +4 -0
- package/esm/components/route-link.d.ts.map +1 -1
- package/esm/components/route-link.js +5 -5
- package/esm/components/route-link.js.map +1 -1
- package/esm/components/route-link.spec.js +16 -12
- package/esm/components/route-link.spec.js.map +1 -1
- package/esm/components/router.d.ts +20 -2
- package/esm/components/router.d.ts.map +1 -1
- package/esm/components/router.js +12 -7
- package/esm/components/router.js.map +1 -1
- package/esm/components/router.spec.js +141 -74
- package/esm/components/router.spec.js.map +1 -1
- package/esm/initialize.d.ts +11 -0
- package/esm/initialize.d.ts.map +1 -1
- package/esm/initialize.js +5 -0
- package/esm/initialize.js.map +1 -1
- package/esm/jsx.d.ts +83 -2
- package/esm/jsx.d.ts.map +1 -1
- package/esm/models/children-list.d.ts +5 -1
- package/esm/models/children-list.d.ts.map +1 -1
- package/esm/models/partial-element.d.ts +12 -2
- package/esm/models/partial-element.d.ts.map +1 -1
- package/esm/models/render-options.d.ts +89 -3
- package/esm/models/render-options.d.ts.map +1 -1
- package/esm/models/selection-state.d.ts +4 -0
- package/esm/models/selection-state.d.ts.map +1 -1
- package/esm/services/location-service.d.ts +11 -0
- package/esm/services/location-service.d.ts.map +1 -1
- package/esm/services/location-service.js +11 -0
- package/esm/services/location-service.js.map +1 -1
- package/esm/services/resource-manager.d.ts +24 -0
- package/esm/services/resource-manager.d.ts.map +1 -1
- package/esm/services/resource-manager.js +36 -1
- package/esm/services/resource-manager.js.map +1 -1
- package/esm/services/resource-manager.spec.js +102 -0
- package/esm/services/resource-manager.spec.js.map +1 -1
- package/esm/services/screen-service.d.ts +81 -4
- package/esm/services/screen-service.d.ts.map +1 -1
- package/esm/services/screen-service.js +75 -4
- package/esm/services/screen-service.js.map +1 -1
- package/esm/services/screen-service.spec.js +91 -7
- package/esm/services/screen-service.spec.js.map +1 -1
- package/esm/shade-component.d.ts +17 -4
- package/esm/shade-component.d.ts.map +1 -1
- package/esm/shade-component.js +67 -5
- package/esm/shade-component.js.map +1 -1
- package/esm/shade-host-props-ref.integration.spec.d.ts +2 -0
- package/esm/shade-host-props-ref.integration.spec.d.ts.map +1 -0
- package/esm/shade-host-props-ref.integration.spec.js +381 -0
- package/esm/shade-host-props-ref.integration.spec.js.map +1 -0
- package/esm/shade-resources.integration.spec.js +208 -39
- package/esm/shade-resources.integration.spec.js.map +1 -1
- package/esm/shade.d.ts +20 -17
- package/esm/shade.d.ts.map +1 -1
- package/esm/shade.js +172 -33
- package/esm/shade.js.map +1 -1
- package/esm/shade.spec.js +31 -30
- package/esm/shade.spec.js.map +1 -1
- package/esm/shades.integration.spec.js +135 -72
- package/esm/shades.integration.spec.js.map +1 -1
- package/esm/style-manager.d.ts +2 -2
- package/esm/style-manager.js +2 -2
- package/esm/svg-types.d.ts +389 -0
- package/esm/svg-types.d.ts.map +1 -0
- package/esm/svg-types.js +9 -0
- package/esm/svg-types.js.map +1 -0
- package/esm/svg.d.ts +15 -0
- package/esm/svg.d.ts.map +1 -0
- package/esm/svg.js +76 -0
- package/esm/svg.js.map +1 -0
- package/esm/svg.spec.d.ts +2 -0
- package/esm/svg.spec.d.ts.map +1 -0
- package/esm/svg.spec.js +80 -0
- package/esm/svg.spec.js.map +1 -0
- package/esm/vnode.d.ts +103 -0
- package/esm/vnode.d.ts.map +1 -0
- package/esm/vnode.integration.spec.d.ts +2 -0
- package/esm/vnode.integration.spec.d.ts.map +1 -0
- package/esm/vnode.integration.spec.js +494 -0
- package/esm/vnode.integration.spec.js.map +1 -0
- package/esm/vnode.js +453 -0
- package/esm/vnode.js.map +1 -0
- package/esm/vnode.spec.d.ts +2 -0
- package/esm/vnode.spec.d.ts.map +1 -0
- package/esm/vnode.spec.js +473 -0
- package/esm/vnode.spec.js.map +1 -0
- package/package.json +8 -9
- package/src/component-factory.spec.tsx +18 -5
- package/src/components/index.ts +4 -1
- package/src/components/lazy-load.spec.tsx +82 -75
- package/src/components/lazy-load.tsx +49 -27
- package/src/components/link-to-route.spec.tsx +25 -21
- package/src/components/link-to-route.tsx +4 -2
- package/src/components/nested-route-link.spec.tsx +303 -0
- package/src/components/nested-route-link.tsx +100 -0
- package/src/components/nested-route-types.ts +42 -0
- package/src/components/nested-router.spec.tsx +918 -0
- package/src/components/nested-router.tsx +260 -0
- package/src/components/route-link.spec.tsx +22 -18
- package/src/components/route-link.tsx +6 -5
- package/src/components/router.spec.tsx +196 -108
- package/src/components/router.tsx +21 -8
- package/src/initialize.ts +12 -0
- package/src/jsx.ts +129 -2
- package/src/models/children-list.ts +7 -1
- package/src/models/partial-element.ts +13 -2
- package/src/models/render-options.ts +90 -3
- package/src/models/selection-state.ts +4 -0
- package/src/services/location-service.tsx +11 -0
- package/src/services/resource-manager.spec.ts +128 -0
- package/src/services/resource-manager.ts +36 -1
- package/src/services/screen-service.spec.ts +109 -7
- package/src/services/screen-service.ts +81 -4
- package/src/shade-component.ts +72 -6
- package/src/shade-host-props-ref.integration.spec.tsx +460 -0
- package/src/shade-resources.integration.spec.tsx +276 -52
- package/src/shade.spec.tsx +40 -39
- package/src/shade.ts +186 -58
- package/src/shades.integration.spec.tsx +154 -80
- package/src/style-manager.ts +2 -2
- package/src/svg-types.ts +437 -0
- package/src/svg.spec.ts +89 -0
- package/src/svg.ts +78 -0
- package/src/vnode.integration.spec.tsx +657 -0
- package/src/vnode.spec.ts +579 -0
- package/src/vnode.ts +508 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { compileRoute } from '../compile-route.js'
|
|
2
|
+
import type { ChildrenList } from '../models/children-list.js'
|
|
3
|
+
import type { PartialElement } from '../models/partial-element.js'
|
|
4
|
+
import { LocationService } from '../services/location-service.js'
|
|
5
|
+
import { createComponent } from '../shade-component.js'
|
|
6
|
+
import { Shade } from '../shade.js'
|
|
7
|
+
import type { ExtractRouteParams, ExtractRoutePaths } from './nested-route-types.js'
|
|
8
|
+
import type { NestedRoute } from './nested-router.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Props for the NestedRouteLink component.
|
|
12
|
+
* Combines SPA navigation from RouteLink with parameter compilation from LinkToRoute.
|
|
13
|
+
*/
|
|
14
|
+
export type NestedRouteLinkProps = {
|
|
15
|
+
href: string
|
|
16
|
+
params?: Record<string, string>
|
|
17
|
+
} & PartialElement<Omit<HTMLAnchorElement, 'onclick' | 'href'>>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Props for a type-safe nested route link.
|
|
21
|
+
* When the path contains parameters (e.g. `:id`), the `params` prop becomes required.
|
|
22
|
+
* @typeParam TPath - A specific route path string
|
|
23
|
+
*/
|
|
24
|
+
export type TypedNestedRouteLinkProps<TPath extends string> = {
|
|
25
|
+
href: TPath
|
|
26
|
+
} & (string extends keyof ExtractRouteParams<TPath>
|
|
27
|
+
? { params?: Record<string, string> }
|
|
28
|
+
: { params: ExtractRouteParams<TPath> }) &
|
|
29
|
+
PartialElement<Omit<HTMLAnchorElement, 'onclick' | 'href'>>
|
|
30
|
+
|
|
31
|
+
const _NestedRouteLink = Shade<NestedRouteLinkProps>({
|
|
32
|
+
shadowDomName: 'nested-route-link',
|
|
33
|
+
elementBase: HTMLAnchorElement,
|
|
34
|
+
elementBaseName: 'a',
|
|
35
|
+
css: {
|
|
36
|
+
color: 'inherit',
|
|
37
|
+
textDecoration: 'inherit',
|
|
38
|
+
},
|
|
39
|
+
render: ({ children, props, injector, useHostProps }) => {
|
|
40
|
+
const { href, params } = props
|
|
41
|
+
const resolvedUrl = params ? compileRoute(href, params) : href
|
|
42
|
+
|
|
43
|
+
useHostProps({
|
|
44
|
+
href: resolvedUrl,
|
|
45
|
+
onclick: (ev: MouseEvent) => {
|
|
46
|
+
ev.preventDefault()
|
|
47
|
+
history.pushState('', props.title || '', resolvedUrl)
|
|
48
|
+
injector.getInstance(LocationService).updateState()
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
return <>{children}</>
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A link component for NestedRouter that supports SPA navigation with
|
|
57
|
+
* type-safe route parameter compilation.
|
|
58
|
+
*
|
|
59
|
+
* Intercepts click events to use `history.pushState` for client-side navigation,
|
|
60
|
+
* and compiles parameterized routes (e.g. `/users/:id`) when `params` is provided.
|
|
61
|
+
*
|
|
62
|
+
* Route parameters are automatically inferred from the `href` pattern:
|
|
63
|
+
* - `href="/buttons"` — `params` is optional
|
|
64
|
+
* - `href="/users/:id"` — `params: { id: string }` is required
|
|
65
|
+
*
|
|
66
|
+
* For additional URL validation against a route tree, use {@link createNestedRouteLink}.
|
|
67
|
+
*/
|
|
68
|
+
export const NestedRouteLink = _NestedRouteLink as unknown as <TPath extends string = string>(
|
|
69
|
+
props: TypedNestedRouteLinkProps<TPath>,
|
|
70
|
+
children?: ChildrenList,
|
|
71
|
+
) => JSX.Element
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Creates a type-safe wrapper around NestedRouteLink constrained to a specific route tree.
|
|
75
|
+
* The returned component has the same runtime behavior but narrows `href` to only accept
|
|
76
|
+
* valid route paths, and requires `params` when the route has parameters.
|
|
77
|
+
*
|
|
78
|
+
* @typeParam TRoutes - The route tree type (use `typeof yourRoutes`)
|
|
79
|
+
* @returns A narrowed NestedRouteLink component
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const AppLink = createNestedRouteLink<typeof appRoutes>()
|
|
84
|
+
*
|
|
85
|
+
* // Type-safe: only valid paths accepted
|
|
86
|
+
* <AppLink href="/buttons">Buttons</AppLink>
|
|
87
|
+
*
|
|
88
|
+
* // TypeScript error: invalid path
|
|
89
|
+
* <AppLink href="/nonexistent">Error!</AppLink>
|
|
90
|
+
*
|
|
91
|
+
* // Params required for parameterized routes
|
|
92
|
+
* <AppLink href="/users/:id" params={{ id: '123' }}>User</AppLink>
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export const createNestedRouteLink = <TRoutes extends Record<string, NestedRoute<unknown>>>() => {
|
|
96
|
+
return _NestedRouteLink as unknown as <TPath extends ExtractRoutePaths<TRoutes>>(
|
|
97
|
+
props: TypedNestedRouteLinkProps<TPath>,
|
|
98
|
+
children?: ChildrenList,
|
|
99
|
+
) => JSX.Element
|
|
100
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { NestedRoute } from './nested-router.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Concatenates parent and child route paths, handling the '/' root specially
|
|
5
|
+
* to avoid double slashes.
|
|
6
|
+
* @typeParam Parent - The parent route path
|
|
7
|
+
* @typeParam Child - The child route path
|
|
8
|
+
*/
|
|
9
|
+
export type ConcatPaths<Parent extends string, Child extends string> = Parent extends '/' ? Child : `${Parent}${Child}`
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Recursively extracts all valid full URL paths from a nested route tree.
|
|
13
|
+
* @typeParam T - A record of route patterns to NestedRoute definitions
|
|
14
|
+
*/
|
|
15
|
+
export type ExtractRoutePaths<T extends Record<string, NestedRoute<unknown>>> = {
|
|
16
|
+
[K in keyof T & string]:
|
|
17
|
+
| K
|
|
18
|
+
| (T[K] extends { children: infer C extends Record<string, NestedRoute<unknown>> }
|
|
19
|
+
? ConcatPaths<K, ExtractRoutePaths<C> & string>
|
|
20
|
+
: never)
|
|
21
|
+
}[keyof T & string]
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extracts route parameter names from a URL pattern and creates a record type
|
|
25
|
+
* mapping each parameter name to `string`.
|
|
26
|
+
* Returns `Record<string, never>` when no parameters are present.
|
|
27
|
+
* @typeParam T - A URL pattern string potentially containing `:param` segments
|
|
28
|
+
*/
|
|
29
|
+
export type ExtractRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}`
|
|
30
|
+
? { [K in Param | keyof ExtractRouteParams<`/${Rest}`>]: string }
|
|
31
|
+
: T extends `${string}:${infer Param}`
|
|
32
|
+
? { [K in Param]: string }
|
|
33
|
+
: Record<string, never>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A recursive type for validating URL constant objects against a set of valid paths.
|
|
37
|
+
* Leaf values must be valid route paths, and intermediate values can be nested UrlTree objects.
|
|
38
|
+
* @typeParam TPaths - Union of valid route path strings
|
|
39
|
+
*/
|
|
40
|
+
export type UrlTree<TPaths extends string> = {
|
|
41
|
+
[key: string]: TPaths | UrlTree<TPaths>
|
|
42
|
+
}
|