@remix-run/ui 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -2
- package/dist/animation/animate-layout-mixin.d.ts +12 -0
- package/dist/animation/animate-layout-mixin.js +214 -0
- package/dist/animation/animate-layout-mixin.js.map +1 -0
- package/dist/animation/animate-mixins.d.ts +29 -0
- package/dist/animation/animate-mixins.js +235 -0
- package/dist/animation/animate-mixins.js.map +1 -0
- package/dist/animation/index.d.ts +6 -0
- package/dist/animation/index.js +5 -0
- package/dist/animation/index.js.map +1 -0
- package/dist/animation/spring.d.ts +75 -0
- package/dist/animation/spring.js +183 -0
- package/dist/animation/spring.js.map +1 -0
- package/dist/animation/tween.d.ts +70 -0
- package/dist/animation/tween.js +93 -0
- package/dist/animation/tween.js.map +1 -0
- package/dist/components/accordion/accordion.d.ts +92 -0
- package/dist/components/accordion/accordion.js +337 -0
- package/dist/components/accordion/accordion.js.map +1 -0
- package/dist/components/anchor/anchor.d.ts +13 -0
- package/dist/components/anchor/anchor.js +558 -0
- package/dist/components/anchor/anchor.js.map +1 -0
- package/dist/components/breadcrumbs/breadcrumbs.d.ts +11 -0
- package/dist/components/breadcrumbs/breadcrumbs.js +78 -0
- package/dist/components/breadcrumbs/breadcrumbs.js.map +1 -0
- package/dist/components/button/button.d.ts +23 -0
- package/dist/components/button/button.js +147 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/combobox/combobox.d.ts +101 -0
- package/dist/components/combobox/combobox.js +708 -0
- package/dist/components/combobox/combobox.js.map +1 -0
- package/dist/components/glyph/glyph.d.ts +14 -0
- package/dist/components/glyph/glyph.js +65 -0
- package/dist/components/glyph/glyph.js.map +1 -0
- package/dist/components/listbox/listbox.d.ts +67 -0
- package/dist/components/listbox/listbox.js +340 -0
- package/dist/components/listbox/listbox.js.map +1 -0
- package/dist/components/menu/hover-aim.d.ts +5 -0
- package/dist/components/menu/hover-aim.js +308 -0
- package/dist/components/menu/hover-aim.js.map +1 -0
- package/dist/components/menu/menu.d.ts +164 -0
- package/dist/components/menu/menu.js +1106 -0
- package/dist/components/menu/menu.js.map +1 -0
- package/dist/components/popover/popover.d.ts +35 -0
- package/dist/components/popover/popover.js +138 -0
- package/dist/components/popover/popover.js.map +1 -0
- package/dist/components/select/select.d.ts +67 -0
- package/dist/components/select/select.js +397 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/separator/separator.d.ts +2 -0
- package/dist/components/separator/separator.js +15 -0
- package/dist/components/separator/separator.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +78 -0
- package/dist/components/tabs/tabs.js +341 -0
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions/keydown/keydown.d.ts +1 -0
- package/dist/interactions/keydown/keydown.js +8 -0
- package/dist/interactions/keydown/keydown.js.map +1 -0
- package/dist/interactions/outside-click/outside-click-mixin.d.ts +2 -0
- package/dist/interactions/outside-click/outside-click-mixin.js +29 -0
- package/dist/interactions/outside-click/outside-click-mixin.js.map +1 -0
- package/dist/interactions/typeahead/typeahead-mixin.d.ts +8 -0
- package/dist/interactions/typeahead/typeahead-mixin.js +59 -0
- package/dist/interactions/typeahead/typeahead-mixin.js.map +1 -0
- package/dist/jsx-runtime.d.ts +2 -0
- package/dist/jsx-runtime.js +3 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/runtime/client-entries.d.ts +91 -0
- package/dist/runtime/client-entries.js +40 -0
- package/dist/runtime/client-entries.js.map +1 -0
- package/dist/runtime/component.d.ts +223 -0
- package/dist/runtime/component.js +152 -0
- package/dist/runtime/component.js.map +1 -0
- package/dist/runtime/create-element.d.ts +10 -0
- package/dist/runtime/create-element.js +29 -0
- package/dist/runtime/create-element.js.map +1 -0
- package/dist/runtime/diff-dom.d.ts +2 -0
- package/dist/runtime/diff-dom.js +364 -0
- package/dist/runtime/diff-dom.js.map +1 -0
- package/dist/runtime/diff-props.d.ts +9 -0
- package/dist/runtime/diff-props.js +195 -0
- package/dist/runtime/diff-props.js.map +1 -0
- package/dist/runtime/document-state.d.ts +11 -0
- package/dist/runtime/document-state.js +106 -0
- package/dist/runtime/document-state.js.map +1 -0
- package/dist/runtime/dom.d.ts +3189 -0
- package/dist/runtime/dom.js +2 -0
- package/dist/runtime/dom.js.map +1 -0
- package/dist/runtime/error-event.d.ts +20 -0
- package/dist/runtime/error-event.js +19 -0
- package/dist/runtime/error-event.js.map +1 -0
- package/dist/runtime/event-listeners.d.ts +50 -0
- package/dist/runtime/event-listeners.js +31 -0
- package/dist/runtime/event-listeners.js.map +1 -0
- package/dist/runtime/frame.d.ts +119 -0
- package/dist/runtime/frame.js +915 -0
- package/dist/runtime/frame.js.map +1 -0
- package/dist/runtime/invariant.d.ts +23 -0
- package/dist/runtime/invariant.js +33 -0
- package/dist/runtime/invariant.js.map +1 -0
- package/dist/runtime/jsx.d.ts +320 -0
- package/dist/runtime/jsx.js +31 -0
- package/dist/runtime/jsx.js.map +1 -0
- package/dist/runtime/mixins/attrs-mixin.d.ts +9 -0
- package/dist/runtime/mixins/attrs-mixin.js +23 -0
- package/dist/runtime/mixins/attrs-mixin.js.map +1 -0
- package/dist/runtime/mixins/link-mixin.d.ts +17 -0
- package/dist/runtime/mixins/link-mixin.js +101 -0
- package/dist/runtime/mixins/link-mixin.js.map +1 -0
- package/dist/runtime/mixins/mixin.d.ts +145 -0
- package/dist/runtime/mixins/mixin.js +570 -0
- package/dist/runtime/mixins/mixin.js.map +1 -0
- package/dist/runtime/mixins/on-mixin.d.ts +16 -0
- package/dist/runtime/mixins/on-mixin.js +49 -0
- package/dist/runtime/mixins/on-mixin.js.map +1 -0
- package/dist/runtime/mixins/ref-mixin.d.ts +9 -0
- package/dist/runtime/mixins/ref-mixin.js +21 -0
- package/dist/runtime/mixins/ref-mixin.js.map +1 -0
- package/dist/runtime/navigation.d.ts +22 -0
- package/dist/runtime/navigation.js +102 -0
- package/dist/runtime/navigation.js.map +1 -0
- package/dist/runtime/reconcile.d.ts +11 -0
- package/dist/runtime/reconcile.js +1240 -0
- package/dist/runtime/reconcile.js.map +1 -0
- package/dist/runtime/render.d.ts +54 -0
- package/dist/runtime/render.js +50 -0
- package/dist/runtime/render.js.map +1 -0
- package/dist/runtime/run.d.ts +45 -0
- package/dist/runtime/run.js +68 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +30 -0
- package/dist/runtime/scheduler.js +185 -0
- package/dist/runtime/scheduler.js.map +1 -0
- package/dist/runtime/svg-attributes.d.ts +5 -0
- package/dist/runtime/svg-attributes.js +124 -0
- package/dist/runtime/svg-attributes.js.map +1 -0
- package/dist/runtime/to-vnode.d.ts +3 -0
- package/dist/runtime/to-vnode.js +43 -0
- package/dist/runtime/to-vnode.js.map +1 -0
- package/dist/runtime/typed-event-target.d.ts +50 -0
- package/dist/runtime/typed-event-target.js +6 -0
- package/dist/runtime/typed-event-target.js.map +1 -0
- package/dist/runtime/vdom.d.ts +55 -0
- package/dist/runtime/vdom.js +198 -0
- package/dist/runtime/vdom.js.map +1 -0
- package/dist/runtime/vnode.d.ts +79 -0
- package/dist/runtime/vnode.js +38 -0
- package/dist/runtime/vnode.js.map +1 -0
- package/dist/server/stream.d.ts +57 -0
- package/dist/server/stream.js +1007 -0
- package/dist/server/stream.js.map +1 -0
- package/dist/style/css-mixin.d.ts +8 -0
- package/dist/style/css-mixin.js +54 -0
- package/dist/style/css-mixin.js.map +1 -0
- package/dist/style/index.d.ts +5 -0
- package/dist/style/index.js +4 -0
- package/dist/style/index.js.map +1 -0
- package/dist/style/style.d.ts +24 -0
- package/dist/style/style.js +269 -0
- package/dist/style/style.js.map +1 -0
- package/dist/style/stylesheet.d.ts +11 -0
- package/dist/style/stylesheet.js +174 -0
- package/dist/style/stylesheet.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.js +2 -0
- package/dist/test.js.map +1 -0
- package/dist/theme/contract.d.ts +259 -0
- package/dist/theme/contract.js +131 -0
- package/dist/theme/contract.js.map +1 -0
- package/dist/theme/glyph-contract.d.ts +13 -0
- package/dist/theme/glyph-contract.js +34 -0
- package/dist/theme/glyph-contract.js.map +1 -0
- package/dist/theme/presets/rmx-01/glyphs.d.ts +2 -0
- package/dist/theme/presets/rmx-01/glyphs.js +252 -0
- package/dist/theme/presets/rmx-01/glyphs.js.map +1 -0
- package/dist/theme/presets/rmx-01/index.d.ts +2 -0
- package/dist/theme/presets/rmx-01/index.js +119 -0
- package/dist/theme/presets/rmx-01/index.js.map +1 -0
- package/dist/theme/runtime.d.ts +2 -0
- package/dist/theme/runtime.js +81 -0
- package/dist/theme/runtime.js.map +1 -0
- package/dist/theme/theme.d.ts +6 -0
- package/dist/theme/theme.js +5 -0
- package/dist/theme/theme.js.map +1 -0
- package/dist/utils/flash-attribute.d.ts +1 -0
- package/dist/utils/flash-attribute.js +11 -0
- package/dist/utils/flash-attribute.js.map +1 -0
- package/dist/utils/scroll-lock.d.ts +3 -0
- package/dist/utils/scroll-lock.js +69 -0
- package/dist/utils/scroll-lock.js.map +1 -0
- package/dist/utils/wait-for-css-transition.d.ts +1 -0
- package/dist/utils/wait-for-css-transition.js +58 -0
- package/dist/utils/wait-for-css-transition.js.map +1 -0
- package/dist/utils/wait.d.ts +1 -0
- package/dist/utils/wait.js +6 -0
- package/dist/utils/wait.js.map +1 -0
- package/package.json +125 -5
- package/src/animation/animate-layout-mixin.ts +266 -0
- package/src/animation/animate-mixins.ts +292 -0
- package/src/animation/index.ts +6 -0
- package/src/animation/spring.ts +299 -0
- package/src/animation/tween.ts +134 -0
- package/src/components/accordion/accordion.tsx +565 -0
- package/src/components/anchor/anchor.ts +904 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +124 -0
- package/src/components/button/README.md +44 -0
- package/src/components/button/button.tsx +188 -0
- package/src/components/combobox/README.md +145 -0
- package/src/components/combobox/combobox.tsx +1014 -0
- package/src/components/glyph/glyph.tsx +110 -0
- package/src/components/listbox/listbox.ts +447 -0
- package/src/components/menu/hover-aim.ts +428 -0
- package/src/components/menu/menu.tsx +1547 -0
- package/src/components/popover/README.md +122 -0
- package/src/components/popover/popover.ts +201 -0
- package/src/components/select/select.tsx +585 -0
- package/src/components/separator/separator.ts +19 -0
- package/src/components/tabs/README.md +105 -0
- package/src/components/tabs/tabs.tsx +499 -0
- package/src/index.ts +72 -0
- package/src/interactions/keydown/keydown.ts +14 -0
- package/src/interactions/outside-click/outside-click-mixin.ts +55 -0
- package/src/interactions/typeahead/typeahead-mixin.ts +89 -0
- package/src/jsx-runtime.ts +2 -0
- package/src/runtime/client-entries.ts +137 -0
- package/src/runtime/component.ts +402 -0
- package/src/runtime/create-element.ts +38 -0
- package/src/runtime/diff-dom.ts +404 -0
- package/src/runtime/diff-props.ts +209 -0
- package/src/runtime/document-state.ts +130 -0
- package/src/runtime/dom.ts +3971 -0
- package/src/runtime/error-event.ts +26 -0
- package/src/runtime/event-listeners.ts +171 -0
- package/src/runtime/frame.ts +1211 -0
- package/src/runtime/invariant.ts +31 -0
- package/src/runtime/jsx.ts +398 -0
- package/src/runtime/mixins/attrs-mixin.ts +35 -0
- package/src/runtime/mixins/link-mixin.ts +131 -0
- package/src/runtime/mixins/mixin.ts +908 -0
- package/src/runtime/mixins/on-mixin.ts +89 -0
- package/src/runtime/mixins/ref-mixin.ts +32 -0
- package/src/runtime/navigation.ts +136 -0
- package/src/runtime/reconcile.ts +1722 -0
- package/src/runtime/render.ts +101 -0
- package/src/runtime/run.ts +100 -0
- package/src/runtime/scheduler.ts +262 -0
- package/src/runtime/svg-attributes.ts +133 -0
- package/src/runtime/to-vnode.ts +50 -0
- package/src/runtime/typed-event-target.ts +67 -0
- package/src/runtime/vdom.ts +295 -0
- package/src/runtime/vnode.ts +137 -0
- package/src/server/stream.ts +1342 -0
- package/src/style/css-mixin.ts +82 -0
- package/src/style/index.ts +10 -0
- package/src/style/style.ts +312 -0
- package/src/style/stylesheet.ts +209 -0
- package/src/test/setup.ts +7 -0
- package/src/test/utils.ts +45 -0
- package/src/test.ts +2 -0
- package/src/theme/contract.ts +183 -0
- package/src/theme/glyph-contract.ts +57 -0
- package/src/theme/presets/rmx-01/glyphs.tsx +308 -0
- package/src/theme/presets/rmx-01/index.ts +121 -0
- package/src/theme/runtime.ts +116 -0
- package/src/theme/theme.ts +15 -0
- package/src/utils/flash-attribute.ts +11 -0
- package/src/utils/scroll-lock.ts +97 -0
- package/src/utils/wait-for-css-transition.ts +66 -0
- package/src/utils/wait.ts +5 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createMixin } from './mixin.ts'
|
|
2
|
+
import type { ElementProps } from '../jsx.ts'
|
|
3
|
+
import type { MixinDescriptor } from './mixin.ts'
|
|
4
|
+
import type {
|
|
5
|
+
EventType as AddEventType,
|
|
6
|
+
ListenerFor as AddEventListenerFor,
|
|
7
|
+
} from '../event-listeners.ts'
|
|
8
|
+
|
|
9
|
+
export type { Dispatched } from '../event-listeners.ts'
|
|
10
|
+
|
|
11
|
+
type SignaledListener<event extends Event> = (
|
|
12
|
+
event: event,
|
|
13
|
+
signal: AbortSignal,
|
|
14
|
+
) => void | Promise<void>
|
|
15
|
+
|
|
16
|
+
type EventType<target extends Element> = Extract<AddEventType<target>, string>
|
|
17
|
+
type ListenerFor<target extends Element, type extends EventType<target>> = SignaledListener<
|
|
18
|
+
Parameters<AddEventListenerFor<target, type>>[0]
|
|
19
|
+
>
|
|
20
|
+
|
|
21
|
+
const onMixin = createMixin<
|
|
22
|
+
Element,
|
|
23
|
+
[type: string, handler: SignaledListener<Event>, captureBoolean?: boolean],
|
|
24
|
+
ElementProps
|
|
25
|
+
>((handle) => {
|
|
26
|
+
let currentHandler: SignaledListener<Event> = () => {}
|
|
27
|
+
let currentType = ''
|
|
28
|
+
let currentCapture = false
|
|
29
|
+
let currentNode: Element | null = null
|
|
30
|
+
let reentry: AbortController | null = null
|
|
31
|
+
|
|
32
|
+
let stableHandler = (event: Event) => {
|
|
33
|
+
reentry?.abort(new DOMException('', 'EventReentry'))
|
|
34
|
+
reentry = new AbortController()
|
|
35
|
+
void currentHandler(event, reentry.signal)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
handle.addEventListener('insert', (event) => {
|
|
39
|
+
currentNode = event.node
|
|
40
|
+
currentNode.addEventListener(currentType, stableHandler, currentCapture)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
handle.addEventListener('remove', () => {
|
|
44
|
+
currentNode?.removeEventListener(currentType, stableHandler, currentCapture)
|
|
45
|
+
currentNode = null
|
|
46
|
+
reentry?.abort(new DOMException('', 'AbortError'))
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return (type, handler, captureBoolean = false) => {
|
|
50
|
+
let previousType = currentType
|
|
51
|
+
let previousCapture = currentCapture
|
|
52
|
+
let needsRebind = currentType !== type || currentCapture !== captureBoolean
|
|
53
|
+
currentType = type
|
|
54
|
+
currentHandler = handler
|
|
55
|
+
currentCapture = captureBoolean
|
|
56
|
+
|
|
57
|
+
if (needsRebind && currentNode) {
|
|
58
|
+
currentNode.removeEventListener(previousType, stableHandler, previousCapture)
|
|
59
|
+
currentNode.addEventListener(type, stableHandler, captureBoolean)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return handle.element
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Attaches a typed DOM event handler through the mixin system.
|
|
68
|
+
*
|
|
69
|
+
* @param type Event type to listen for.
|
|
70
|
+
* @param handler Event handler.
|
|
71
|
+
* @param captureBoolean Whether to listen during capture.
|
|
72
|
+
* @returns A mixin descriptor for the target element.
|
|
73
|
+
*/
|
|
74
|
+
export function on<
|
|
75
|
+
target extends Element = Element,
|
|
76
|
+
type extends EventType<target> = EventType<target>,
|
|
77
|
+
>(
|
|
78
|
+
type: type,
|
|
79
|
+
handler: ListenerFor<target, type>,
|
|
80
|
+
captureBoolean?: boolean,
|
|
81
|
+
): MixinDescriptor<target, [type, ListenerFor<target, type>, boolean?], ElementProps> {
|
|
82
|
+
// Keep this typed wrapper so JSX host context can infer event/currentTarget
|
|
83
|
+
// from `type`, rather than exposing the raw `string` + `Event` runtime signature.
|
|
84
|
+
return onMixin(
|
|
85
|
+
type as string,
|
|
86
|
+
handler as unknown as SignaledListener<Event>,
|
|
87
|
+
captureBoolean,
|
|
88
|
+
) as unknown as MixinDescriptor<target, [type, ListenerFor<target, type>, boolean?], ElementProps>
|
|
89
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createMixin } from './mixin.ts'
|
|
2
|
+
import type { ElementProps } from '../jsx.ts'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Callback invoked with the bound node and a lifetime signal.
|
|
6
|
+
*/
|
|
7
|
+
export type RefCallback<node extends EventTarget> = (node: node, signal: AbortSignal) => void
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Calls a callback when an element is inserted and aborts it when removed.
|
|
11
|
+
*/
|
|
12
|
+
export const ref = createMixin<Element, [callback: RefCallback<Element>], ElementProps>(
|
|
13
|
+
(handle) => {
|
|
14
|
+
let controller: AbortController | undefined
|
|
15
|
+
|
|
16
|
+
handle.addEventListener('insert', (event) => {
|
|
17
|
+
controller = new AbortController()
|
|
18
|
+
callback(event.node, controller.signal)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
handle.addEventListener('remove', () => {
|
|
22
|
+
controller?.abort(new DOMException('', 'AbortError'))
|
|
23
|
+
controller = undefined
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
let callback: RefCallback<Element> = () => {}
|
|
27
|
+
return (nextCallback) => {
|
|
28
|
+
callback = nextCallback
|
|
29
|
+
return handle.element
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { getTopFrame, getNamedFrame } from './run.ts'
|
|
2
|
+
|
|
3
|
+
type NavigationState = {
|
|
4
|
+
target: string | undefined
|
|
5
|
+
src: string
|
|
6
|
+
resetScroll: boolean
|
|
7
|
+
$rmx: true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type SourceElementNavigateEvent = NavigateEvent & {
|
|
11
|
+
sourceElement?: Element | null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Options for client-side frame-aware navigation.
|
|
16
|
+
*/
|
|
17
|
+
export type NavigationOptions = {
|
|
18
|
+
src?: string
|
|
19
|
+
target?: string
|
|
20
|
+
history?: 'push' | 'replace'
|
|
21
|
+
resetScroll?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Performs a Navigation API transition understood by Remix frame runtime state.
|
|
26
|
+
*
|
|
27
|
+
* @param href Destination URL.
|
|
28
|
+
* @param options Navigation options.
|
|
29
|
+
*/
|
|
30
|
+
export async function navigate(href: string, options?: NavigationOptions) {
|
|
31
|
+
let state = {
|
|
32
|
+
target: options?.target,
|
|
33
|
+
src: options?.src ?? href,
|
|
34
|
+
resetScroll: options?.resetScroll !== false,
|
|
35
|
+
$rmx: true,
|
|
36
|
+
} satisfies NavigationState
|
|
37
|
+
let transition = window.navigation.navigate(href, { state, history: options?.history })
|
|
38
|
+
await transition.finished
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Starts listening for Navigation API transitions and routes them through frame reloads.
|
|
43
|
+
*
|
|
44
|
+
* @param signal Abort signal used to remove the listener.
|
|
45
|
+
*/
|
|
46
|
+
export function startNavigationListener(signal: AbortSignal) {
|
|
47
|
+
let navigation = window.navigation
|
|
48
|
+
|
|
49
|
+
navigation.updateCurrentEntry({
|
|
50
|
+
state: { target: undefined, src: window.location.href, resetScroll: true, $rmx: true },
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
navigation.addEventListener(
|
|
54
|
+
'navigate',
|
|
55
|
+
(event) => {
|
|
56
|
+
if (!event.canIntercept) return
|
|
57
|
+
|
|
58
|
+
let state = getRuntimeNavigationState(event)
|
|
59
|
+
if (!state) return
|
|
60
|
+
|
|
61
|
+
let topFrame = getTopFrame()
|
|
62
|
+
let namedFrame = state.target ? getNamedFrame(state.target) : undefined
|
|
63
|
+
let frame = namedFrame ?? topFrame
|
|
64
|
+
|
|
65
|
+
event.intercept({
|
|
66
|
+
async handler() {
|
|
67
|
+
if (event.navigationType !== 'traverse') {
|
|
68
|
+
navigation.updateCurrentEntry({ state })
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
frame.src = frame === topFrame ? event.destination.url : state.src
|
|
72
|
+
await frame.reload()
|
|
73
|
+
|
|
74
|
+
let isNewEntry = event.navigationType === 'push' || event.navigationType === 'replace'
|
|
75
|
+
if (state.resetScroll && isNewEntry) {
|
|
76
|
+
window.scrollTo(0, 0)
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
},
|
|
81
|
+
{ signal },
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isRuntimeNavigation(info: unknown): info is NavigationState {
|
|
86
|
+
return typeof info === 'object' && info != null && '$rmx' in info
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getRuntimeNavigationState(event: NavigateEvent): NavigationState | undefined {
|
|
90
|
+
if (event.navigationType === 'traverse') {
|
|
91
|
+
return getTraverseNavigationState(event)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let sourceState = getSourceElementNavigationState(event)
|
|
95
|
+
if (sourceState) return sourceState
|
|
96
|
+
|
|
97
|
+
let destinationState = event.destination.getState()
|
|
98
|
+
if (isRuntimeNavigation(destinationState)) return destinationState
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getTraverseNavigationState(event: NavigateEvent): NavigationState | undefined {
|
|
102
|
+
let destinationState = event.destination.getState()
|
|
103
|
+
if (isRuntimeNavigation(destinationState)) {
|
|
104
|
+
return destinationState
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Safari returns `null` for destination.getState(), even though its in the
|
|
108
|
+
// navigation.entries(), so we do its job for it and look it up.
|
|
109
|
+
let navigation = window.navigation
|
|
110
|
+
let matchingEntry = navigation.entries().find((entry) => entry.key === event.destination.key)
|
|
111
|
+
if (matchingEntry) {
|
|
112
|
+
let state = matchingEntry.getState()
|
|
113
|
+
if (isRuntimeNavigation(state)) {
|
|
114
|
+
return state
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return undefined
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function getSourceElementNavigationState(event: NavigateEvent): NavigationState | undefined {
|
|
122
|
+
let sourceEvent = event as SourceElementNavigateEvent
|
|
123
|
+
let sourceElement = sourceEvent.sourceElement
|
|
124
|
+
if (!(sourceElement instanceof Element)) return
|
|
125
|
+
let linkElement = sourceElement.closest('a, area')
|
|
126
|
+
if (!(linkElement instanceof Element)) return
|
|
127
|
+
if (linkElement.hasAttribute('rmx-document')) return
|
|
128
|
+
if (linkElement.hasAttribute('download')) return
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
target: linkElement.getAttribute('rmx-target') ?? undefined,
|
|
132
|
+
src: linkElement.getAttribute('rmx-src') ?? event.destination.url,
|
|
133
|
+
resetScroll: linkElement.getAttribute('rmx-reset-scroll') !== 'false',
|
|
134
|
+
$rmx: true,
|
|
135
|
+
} satisfies NavigationState
|
|
136
|
+
}
|