@resee-movies/nuxt-ux 0.17.0 → 0.18.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/dist/module.json +1 -1
- package/dist/runtime/components/GlobalHeader.vue +45 -13
- package/dist/runtime/components/GlobalHeader.vue.d.ts +10 -0
- package/dist/runtime/components/TableOfContents.vue +42 -5
- package/dist/runtime/components/TableOfContents.vue.d.ts +9 -1
- package/dist/runtime/composables/use-global-header-state.d.ts +52 -1
- package/dist/runtime/composables/use-global-header-state.js +22 -2
- package/dist/runtime/composables/use-resee-window-scroll.d.ts +18 -0
- package/dist/runtime/composables/use-resee-window-scroll.js +65 -0
- package/dist/runtime/composables/use-url-hash.d.ts +43 -0
- package/dist/runtime/composables/use-url-hash.js +25 -0
- package/dist/runtime/theme/css/brand/application.css +1 -1
- package/dist/runtime/theme/css/brand/typography.css +1 -1
- package/dist/runtime/utils/routing.d.ts +14 -0
- package/dist/runtime/utils/routing.js +14 -0
- package/package.json +10 -10
package/dist/module.json
CHANGED
|
@@ -10,18 +10,28 @@
|
|
|
10
10
|
'header-hidden': hideDrawerContent
|
|
11
11
|
}"
|
|
12
12
|
>
|
|
13
|
-
<div
|
|
14
|
-
ref = "drawerElement"
|
|
15
|
-
:class = "slots.subheader ? 'border-b border-b-global-background-accent' : void 0"
|
|
16
|
-
>
|
|
13
|
+
<div ref="drawerElement">
|
|
17
14
|
<LayoutPageColumn>
|
|
18
15
|
<slot name="default" />
|
|
19
16
|
</LayoutPageColumn>
|
|
17
|
+
|
|
18
|
+
<div
|
|
19
|
+
v-if = "renderSubheader"
|
|
20
|
+
class = "border-b border-b-global-background-accent"
|
|
21
|
+
/>
|
|
20
22
|
</div>
|
|
21
23
|
|
|
22
|
-
<div v-if="
|
|
23
|
-
<LayoutPageColumn>
|
|
24
|
-
<slot name="subheader"
|
|
24
|
+
<div v-if="renderSubheader" ref="subheadElement" class="subheader">
|
|
25
|
+
<LayoutPageColumn class="overflow-x-auto styled-scroll">
|
|
26
|
+
<slot name="subheader">
|
|
27
|
+
<TableOfContents
|
|
28
|
+
:toc = "props.subheaderToc ?? headerState.subheaderToc.value"
|
|
29
|
+
class = "flex items-center flex-nowrap"
|
|
30
|
+
link-class = "btn small borderless text-nowrap"
|
|
31
|
+
:min-depth = "2"
|
|
32
|
+
:max-depth = "2"
|
|
33
|
+
/>
|
|
34
|
+
</slot>
|
|
25
35
|
</LayoutPageColumn>
|
|
26
36
|
</div>
|
|
27
37
|
</header>
|
|
@@ -32,16 +42,20 @@
|
|
|
32
42
|
</script>
|
|
33
43
|
|
|
34
44
|
<script setup>
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
45
|
+
import { useHead } from "#imports";
|
|
46
|
+
import { computed, ref, useSlots, watch } from "vue";
|
|
47
|
+
import { useElementSize } from "@vueuse/core";
|
|
37
48
|
import { useGlobalHeaderState } from "../composables/use-global-header-state";
|
|
49
|
+
import { useReseeWindowScroll } from "../composables/use-resee-window-scroll";
|
|
38
50
|
import { useTwoFrameRefToggle } from "../composables/use-two-frame-ref-toggle";
|
|
39
51
|
import LayoutPageColumn from "./LayoutPageColumn.vue";
|
|
52
|
+
import TableOfContents from "./TableOfContents.vue";
|
|
40
53
|
defineOptions({
|
|
41
54
|
inheritAttrs: false
|
|
42
55
|
});
|
|
43
56
|
const props = defineProps({
|
|
44
|
-
drawer: { type: Boolean, required: false, default: true }
|
|
57
|
+
drawer: { type: Boolean, required: false, default: true },
|
|
58
|
+
subheaderToc: { type: Array, required: false }
|
|
45
59
|
});
|
|
46
60
|
const slots = useSlots();
|
|
47
61
|
const rulerElement = ref();
|
|
@@ -51,9 +65,23 @@ const subheadElement = ref();
|
|
|
51
65
|
const { height: headerHeight } = useElementSize(headerElement);
|
|
52
66
|
const { height: drawerHeight } = useElementSize(drawerElement);
|
|
53
67
|
const { height: subheadHeight } = useElementSize(subheadElement);
|
|
54
|
-
const {
|
|
68
|
+
const {
|
|
69
|
+
y: windowScrollY,
|
|
70
|
+
source: windowScrollSource
|
|
71
|
+
} = useReseeWindowScroll();
|
|
55
72
|
const [isHeaderAffixed, doTransitions, updateAffixState] = useTwoFrameRefToggle();
|
|
56
73
|
const hideDrawerContent = ref(false);
|
|
74
|
+
const headerState = useGlobalHeaderState();
|
|
75
|
+
const renderSubheader = computed(() => {
|
|
76
|
+
return !!(slots.subheader || props.subheaderToc?.length || headerState.subheaderToc.value?.length);
|
|
77
|
+
});
|
|
78
|
+
useHead({
|
|
79
|
+
bodyAttrs: {
|
|
80
|
+
style: () => ({
|
|
81
|
+
"--extra-scroll-margin": subheadHeight.value ? `${subheadHeight.value}px` : ""
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
});
|
|
57
85
|
let backscrollCounter = 0;
|
|
58
86
|
function disableAffix() {
|
|
59
87
|
updateAffixState(false);
|
|
@@ -73,6 +101,11 @@ const { pause, resume } = watch(windowScrollY, (newScrollY, oldScrollY) => {
|
|
|
73
101
|
if (!isHeaderAffixed.value && newScrollY > scrollCeiling + rawDrawerHeight) {
|
|
74
102
|
return enableAffix();
|
|
75
103
|
}
|
|
104
|
+
if (!windowScrollSource.value) {
|
|
105
|
+
hideDrawerContent.value = true;
|
|
106
|
+
backscrollCounter = 0;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
76
109
|
const scrollDelta = newScrollY - oldScrollY;
|
|
77
110
|
const isScrollDown = scrollDelta > 0;
|
|
78
111
|
const negDrawerHeight = rawDrawerHeight * -1;
|
|
@@ -83,7 +116,6 @@ const { pause, resume } = watch(windowScrollY, (newScrollY, oldScrollY) => {
|
|
|
83
116
|
hideDrawerContent.value = false;
|
|
84
117
|
}
|
|
85
118
|
});
|
|
86
|
-
const headerState = useGlobalHeaderState();
|
|
87
119
|
watch(
|
|
88
120
|
[() => props.drawer, headerHeight, subheadHeight, hideDrawerContent, isHeaderAffixed],
|
|
89
121
|
() => {
|
|
@@ -103,5 +135,5 @@ watch(
|
|
|
103
135
|
</script>
|
|
104
136
|
|
|
105
137
|
<style scoped>
|
|
106
|
-
.placeholder{height:calc(v-bind(headerHeight)*1px)}.header-affixed{box-shadow:var(--shadow-heavy);left:0;position:fixed;right:0;top:0;transform:translateY(0);z-index:100}.header-affixed.header-transit{transition-duration:calc(var(--default-transition-duration)*2);transition-property:transform,box-shadow;transition-timing-function:var(--default-transition-timing-function)}.header-affixed.header-hidden{box-shadow:none;transform:translateY(calc(v-bind(drawerHeight)*-1px))}
|
|
138
|
+
.placeholder{height:calc(v-bind(headerHeight)*1px)}.header-affixed{box-shadow:var(--shadow-heavy);left:0;position:fixed;right:0;top:0;transform:translateY(0);z-index:100}.header-affixed.header-transit{transition-duration:calc(var(--default-transition-duration)*2);transition-property:transform,box-shadow;transition-timing-function:var(--default-transition-timing-function)}.header-affixed.header-hidden{box-shadow:none;transform:translateY(calc(v-bind(drawerHeight)*-1px))}.subheader :deep(.btn){background:transparent;transition:background-color;transition-duration:var(--default-transition-duration);transition-timing-function:var(--default-transition-timing-function)}.subheader :deep(.btn).active{background:var(--color-global-background-accent)}
|
|
107
139
|
</style>
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import type { TableOfContentsItem } from './TableOfContents.vue.js';
|
|
1
2
|
export interface GlobalHeaderProps {
|
|
3
|
+
/**
|
|
4
|
+
* Whether the header will act like a flyout drawer when
|
|
5
|
+
* scrolling upward on the page.
|
|
6
|
+
*/
|
|
2
7
|
drawer?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Table of contents objects for the global subheader which
|
|
10
|
+
* will be turned into anchor links.
|
|
11
|
+
*/
|
|
12
|
+
subheaderToc?: TableOfContentsItem[];
|
|
3
13
|
}
|
|
4
14
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<GlobalHeaderProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<GlobalHeaderProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
5
15
|
default?: (props: {}) => any;
|
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<ol v-if="props.toc?.length">
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<template v-for="entry of props.toc" :key="entry.slug">
|
|
4
|
+
<li v-if="shouldRenderLevel(entry.level)">
|
|
5
|
+
<NuxtLink
|
|
6
|
+
v-slot = "config"
|
|
7
|
+
:href = "`#${entry.slug}`"
|
|
8
|
+
:custom = "true"
|
|
9
|
+
>
|
|
10
|
+
<a
|
|
11
|
+
v-html = "entry.text"
|
|
12
|
+
:class = "[props.linkClass, { active: mounted && areRoutesStrictEqual(config.route, route) }]"
|
|
13
|
+
:href = "config.href"
|
|
14
|
+
/>
|
|
15
|
+
</NuxtLink>
|
|
16
|
+
|
|
17
|
+
<TableOfContents
|
|
18
|
+
v-if = "entry.children?.length && shouldRenderLevel((entry.level ?? 1) + 1)"
|
|
19
|
+
:toc = "entry.children"
|
|
20
|
+
:link-class = "props.linkClass"
|
|
21
|
+
:min-depth = "props.minDepth"
|
|
22
|
+
:max-depth = "props.maxDepth"
|
|
23
|
+
/>
|
|
24
|
+
</li>
|
|
25
|
+
</template>
|
|
7
26
|
</ol>
|
|
8
27
|
</template>
|
|
9
28
|
|
|
@@ -12,8 +31,26 @@
|
|
|
12
31
|
</script>
|
|
13
32
|
|
|
14
33
|
<script setup>
|
|
34
|
+
import { NuxtLink } from "#components";
|
|
35
|
+
import { useRoute } from "#imports";
|
|
36
|
+
import { onMounted, ref } from "vue";
|
|
37
|
+
import { areRoutesStrictEqual } from "../utils/routing";
|
|
15
38
|
import TableOfContents from "./TableOfContents.vue";
|
|
16
39
|
const props = defineProps({
|
|
17
|
-
toc: { type: null, required: true }
|
|
40
|
+
toc: { type: null, required: true },
|
|
41
|
+
minDepth: { type: Number, required: false },
|
|
42
|
+
maxDepth: { type: Number, required: false },
|
|
43
|
+
linkClass: { type: null, required: false }
|
|
44
|
+
});
|
|
45
|
+
const route = useRoute();
|
|
46
|
+
const mounted = ref(false);
|
|
47
|
+
onMounted(() => {
|
|
48
|
+
mounted.value = true;
|
|
18
49
|
});
|
|
50
|
+
function shouldRenderLevel(level) {
|
|
51
|
+
if (!level) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return (!props.minDepth || props.minDepth <= level) && (!props.maxDepth || props.maxDepth >= level);
|
|
55
|
+
}
|
|
19
56
|
</script>
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { TableOfContents as TableOfContentsOptions } from '@resee-movies/utilities/dom/generate-table-of-contents';
|
|
2
|
+
import type { HTMLElementClassNames } from '../types/index.js';
|
|
3
|
+
export type TableOfContentsItem = Partial<TableOfContentsOptions> & {
|
|
4
|
+
text: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
};
|
|
2
7
|
export type UiTableOfContentsProps = {
|
|
3
|
-
toc:
|
|
8
|
+
toc: TableOfContentsItem[] | null | undefined;
|
|
9
|
+
minDepth?: number;
|
|
10
|
+
maxDepth?: number;
|
|
11
|
+
linkClass?: HTMLElementClassNames;
|
|
4
12
|
};
|
|
5
13
|
declare const __VLS_export: import("vue").DefineComponent<UiTableOfContentsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<UiTableOfContentsProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
14
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,10 +1,61 @@
|
|
|
1
|
+
import { type MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import type { TableOfContentsItem } from '../components/TableOfContents.vue.js';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
declare function tableOfContents(toc: UseGlobalHeaderStateOptions['tableOfContents']): void;
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for the {@link useGlobalHeaderState} composable.
|
|
9
|
+
*/
|
|
10
|
+
export type UseGlobalHeaderStateOptions = {
|
|
11
|
+
tableOfContents?: MaybeRefOrGetter<(TableOfContentsItem | undefined)[] | undefined>;
|
|
12
|
+
};
|
|
1
13
|
/**
|
|
2
14
|
* Stateful information about the GlobalHeader component.
|
|
3
15
|
*/
|
|
4
|
-
export declare function useGlobalHeaderState(): {
|
|
16
|
+
export declare function useGlobalHeaderState(options?: UseGlobalHeaderStateOptions): {
|
|
5
17
|
headerHeight: import("vue").Ref<number, number>;
|
|
6
18
|
subheaderHeight: import("vue").Ref<number, number>;
|
|
19
|
+
subheaderToc: import("vue").Ref<{
|
|
20
|
+
level?: number | undefined;
|
|
21
|
+
text: string;
|
|
22
|
+
slug: string;
|
|
23
|
+
parent?: {
|
|
24
|
+
level: number;
|
|
25
|
+
text: string;
|
|
26
|
+
slug: string;
|
|
27
|
+
parent: /*elided*/ any | undefined;
|
|
28
|
+
children: /*elided*/ any[];
|
|
29
|
+
} | undefined;
|
|
30
|
+
children?: {
|
|
31
|
+
level: number;
|
|
32
|
+
text: string;
|
|
33
|
+
slug: string;
|
|
34
|
+
parent: /*elided*/ any | undefined;
|
|
35
|
+
children: /*elided*/ any[];
|
|
36
|
+
}[] | undefined;
|
|
37
|
+
}[], TableOfContentsItem[] | {
|
|
38
|
+
level?: number | undefined;
|
|
39
|
+
text: string;
|
|
40
|
+
slug: string;
|
|
41
|
+
parent?: {
|
|
42
|
+
level: number;
|
|
43
|
+
text: string;
|
|
44
|
+
slug: string;
|
|
45
|
+
parent: /*elided*/ any | undefined;
|
|
46
|
+
children: /*elided*/ any[];
|
|
47
|
+
} | undefined;
|
|
48
|
+
children?: {
|
|
49
|
+
level: number;
|
|
50
|
+
text: string;
|
|
51
|
+
slug: string;
|
|
52
|
+
parent: /*elided*/ any | undefined;
|
|
53
|
+
children: /*elided*/ any[];
|
|
54
|
+
}[] | undefined;
|
|
55
|
+
}[]>;
|
|
56
|
+
tableOfContents: typeof tableOfContents;
|
|
7
57
|
isHeaderDrawerEnabled: import("vue").Ref<boolean, boolean>;
|
|
8
58
|
isHeaderPulledDown: import("vue").Ref<boolean, boolean>;
|
|
9
59
|
offsetFromHeaderStyles: import("vue").ComputedRef<string[]>;
|
|
10
60
|
};
|
|
61
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, ref } from "vue";
|
|
1
|
+
import { computed, onScopeDispose, ref, toValue, watch } from "vue";
|
|
2
2
|
const headerHeight = ref(0);
|
|
3
3
|
const subheaderHeight = ref(0);
|
|
4
4
|
const isHeaderDrawerEnabled = ref(true);
|
|
@@ -9,10 +9,30 @@ const offsetFromHeaderStyles = computed(() => {
|
|
|
9
9
|
`padding-top: ${headerHeight.value}px;`
|
|
10
10
|
];
|
|
11
11
|
});
|
|
12
|
-
|
|
12
|
+
const subheaderToc = ref([]);
|
|
13
|
+
function tableOfContents(toc) {
|
|
14
|
+
onScopeDispose(() => {
|
|
15
|
+
subheaderToc.value.length = 0;
|
|
16
|
+
}, true);
|
|
17
|
+
watch(
|
|
18
|
+
() => toValue(toc),
|
|
19
|
+
(entries) => {
|
|
20
|
+
subheaderToc.value.push(
|
|
21
|
+
...entries?.filter((entry) => !!entry) ?? []
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
{ immediate: true }
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
export function useGlobalHeaderState(options) {
|
|
28
|
+
if (options?.tableOfContents) {
|
|
29
|
+
tableOfContents(options.tableOfContents);
|
|
30
|
+
}
|
|
13
31
|
return {
|
|
14
32
|
headerHeight,
|
|
15
33
|
subheaderHeight,
|
|
34
|
+
subheaderToc,
|
|
35
|
+
tableOfContents,
|
|
16
36
|
isHeaderDrawerEnabled,
|
|
17
37
|
isHeaderPulledDown,
|
|
18
38
|
offsetFromHeaderStyles
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type UseWindowScrollOptions, type UseWindowScrollReturn } from '@vueuse/core';
|
|
2
|
+
import { type Ref } from 'vue';
|
|
3
|
+
export type UseReseeWindowScrollReturn = UseWindowScrollReturn & {
|
|
4
|
+
source: Ref<Event | undefined>;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* A specialized implementation of the Vueuse {@link useWindowScroll} composable, which adds
|
|
8
|
+
* the new property `source` to the returned object.
|
|
9
|
+
*
|
|
10
|
+
* The purpose of `source` is to provide a best-effort attempt at identifying _why_ the scroll
|
|
11
|
+
* was initiated. To do this, a series of common user interaction events - _wheel_, _touchmove_,
|
|
12
|
+
* etc. are listened to and correlated with the scroll event.
|
|
13
|
+
*
|
|
14
|
+
* In the case of a scroll **not** being initiated by direct user interaction - e.g. invocation of
|
|
15
|
+
* `window.scrollTo` or the user agent scrolling the page in response to a URL hash change - then
|
|
16
|
+
* `source` will be undefined.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useReseeWindowScroll(options?: UseWindowScrollOptions): UseReseeWindowScrollReturn;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useEventListener,
|
|
3
|
+
useWindowScroll
|
|
4
|
+
} from "@vueuse/core";
|
|
5
|
+
import { ref } from "vue";
|
|
6
|
+
const NavigationKeys = [
|
|
7
|
+
"ArrowUp",
|
|
8
|
+
"ArrowDown",
|
|
9
|
+
" ",
|
|
10
|
+
"Spacebar",
|
|
11
|
+
"ArrowRight",
|
|
12
|
+
"ArrowLeft",
|
|
13
|
+
"End",
|
|
14
|
+
"Home",
|
|
15
|
+
"PageDown",
|
|
16
|
+
"PageUp"
|
|
17
|
+
];
|
|
18
|
+
export function useReseeWindowScroll(options) {
|
|
19
|
+
const scrollSource = ref();
|
|
20
|
+
let scrollEndTimeoutId = void 0;
|
|
21
|
+
function clearScrollEndTimeout() {
|
|
22
|
+
if (scrollEndTimeoutId) {
|
|
23
|
+
clearTimeout(scrollEndTimeoutId);
|
|
24
|
+
scrollEndTimeoutId = void 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function setScrollEndTimeout() {
|
|
28
|
+
clearScrollEndTimeout();
|
|
29
|
+
scrollEndTimeoutId = setTimeout(
|
|
30
|
+
() => {
|
|
31
|
+
scrollSource.value = void 0;
|
|
32
|
+
scrollEndTimeoutId = void 0;
|
|
33
|
+
},
|
|
34
|
+
250
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
useEventListener(["wheel", "touchmove", "keydown", "keyup", "mousedown", "mouseup"], (e) => {
|
|
38
|
+
if (e instanceof KeyboardEvent) {
|
|
39
|
+
if (NavigationKeys.includes(e.key)) {
|
|
40
|
+
setScrollEndTimeout();
|
|
41
|
+
scrollSource.value = e;
|
|
42
|
+
}
|
|
43
|
+
} else if (e.type === "mouseup") {
|
|
44
|
+
clearScrollEndTimeout();
|
|
45
|
+
scrollSource.value = void 0;
|
|
46
|
+
} else {
|
|
47
|
+
setScrollEndTimeout();
|
|
48
|
+
scrollSource.value = e;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
const scrollProps = useWindowScroll({
|
|
52
|
+
...options,
|
|
53
|
+
onScroll(e) {
|
|
54
|
+
options?.onScroll?.(e);
|
|
55
|
+
clearScrollEndTimeout();
|
|
56
|
+
},
|
|
57
|
+
onStop(e) {
|
|
58
|
+
options?.onStop?.(e);
|
|
59
|
+
if (scrollSource.value?.type !== "mousedown") {
|
|
60
|
+
setScrollEndTimeout();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return { ...scrollProps, source: scrollSource };
|
|
65
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { RouteLocationResolvedGeneric } from 'vue-router';
|
|
3
|
+
/**
|
|
4
|
+
* Vue Router's `resolve` method creates a RouteLocationResolvedGeneric object,
|
|
5
|
+
* while Vue Router's `currentRoute` ref expects a RouteLocationNormalizedLoadedGeneric
|
|
6
|
+
* object (because of course). There is an inconsistency between the two in that the
|
|
7
|
+
* former's `name` property can be null, while the latter's cannot. This means you
|
|
8
|
+
* cannot directly assign the former to the latter without TS complaining.
|
|
9
|
+
*
|
|
10
|
+
* The exceptionally long name here is a nod to the 50+ other _Location_ types that
|
|
11
|
+
* Vue Route exposes.
|
|
12
|
+
*/
|
|
13
|
+
export type RouteLocationResolvedGenericWithNonNullableName = Omit<RouteLocationResolvedGeneric, 'name'> & {
|
|
14
|
+
name: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Options for the `update` method returned by the {@link useUrlHash} composable.
|
|
18
|
+
*/
|
|
19
|
+
export type UseUrlHashUpdateOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* Whether to update the hash in a way that will cause the browser
|
|
22
|
+
* to scroll to the identified element (default: false).
|
|
23
|
+
*/
|
|
24
|
+
scrollTo?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether to create a new history entry for the hash - push - or to replace the
|
|
27
|
+
* current (default: replace).
|
|
28
|
+
*/
|
|
29
|
+
mode?: 'push' | 'replace';
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The return type of the {@link useUrlHash} composable.
|
|
33
|
+
*/
|
|
34
|
+
export type UseUrlHashReturn = {
|
|
35
|
+
value: Readonly<Ref<string | undefined>>;
|
|
36
|
+
update: (newHash: string | undefined, options?: UseUrlHashUpdateOptions) => boolean;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Read/Write the current URL hash value. By default, this will be done in a way that does
|
|
40
|
+
* not cause browser scroll to behavior to occur - very useful when updating the hash
|
|
41
|
+
* based on the scroll position of the page.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useUrlHash(): UseUrlHashReturn;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useRouter } from "#imports";
|
|
2
|
+
import { isString } from "@resee-movies/utilities/strings/is-string";
|
|
3
|
+
import { computed } from "vue";
|
|
4
|
+
export function useUrlHash() {
|
|
5
|
+
const router = useRouter();
|
|
6
|
+
const value = computed(() => {
|
|
7
|
+
return router.currentRoute.value.hash || void 0;
|
|
8
|
+
});
|
|
9
|
+
const update = (newHash, options) => {
|
|
10
|
+
const normalizedHash = isString(newHash, { withContent: true }) ? !newHash.startsWith("#") ? `#${newHash}` : newHash : void 0;
|
|
11
|
+
const { path, query, hash } = router.currentRoute.value;
|
|
12
|
+
if (normalizedHash && hash && normalizedHash === hash) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (options?.scrollTo === true) {
|
|
16
|
+
(options?.mode === "push" ? router.push : router.replace)({ path, query, hash: normalizedHash });
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const newRoute = router.resolve({ path, query, hash: normalizedHash });
|
|
20
|
+
router.currentRoute.value = newRoute;
|
|
21
|
+
window.history[options?.mode === "push" ? "pushState" : "replaceState"](null, "", normalizedHash);
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
return { value, update };
|
|
25
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer base{:root{--p-scrollbar-width:0px}html:has(body.p-overflow-hidden){scrollbar-color:transparent var(--color-global-background)}body{background-color:var(--color-global-background);color:var(--color-global-foreground);min-height:100vh;transition:color,background-color;transition-duration:var(--default-transition-duration);@variant dark{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}}@property --background-grid-line-color{syntax:"<color>";inherits:false;initial-value:transparent}#app-root{min-height:100vh;@variant sm{background-position:top;background-size:160px
|
|
1
|
+
@layer base{:root{--p-scrollbar-width:0px}html{scroll-behavior:smooth}@media screen and (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}html:has(body.p-overflow-hidden){scrollbar-color:transparent var(--color-global-background)}body{background-color:var(--color-global-background);color:var(--color-global-foreground);min-height:100vh;transition:color,background-color;transition-duration:var(--default-transition-duration);@variant dark{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}}@property --background-grid-line-color{syntax:"<color>";inherits:false;initial-value:transparent}#app-root{min-height:100vh;@variant sm{background-position:top;background-size:160px 74px;transition:--background-grid-line-color;transition-duration:var(--default-transition-duration);--background-grid-line-color:var(--color-global-background-accent);background-image:linear-gradient(to bottom,transparent 0 45px,var(--background-grid-line-color) 45px 46px,transparent 46px 59px,var(--background-grid-line-color) 59px 60px,transparent 60px),linear-gradient(to right,transparent 0 80px,var(--background-grid-line-color) 80px 81px,transparent 81px)}}.app-main{min-height:100vh}.app-footer{position:sticky;top:100vh}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@utility prose-layout-container{margin-left:auto;margin-right:auto;max-width:var(--container-3xl);width:100%;&.sm{max-width:var(--container-md)}}@layer components{:root{--typo-h6:clamp(var(--text-base),2.500vw,1.2rem);--typo-h5:clamp(var(--typo-h6),3.000vw,1.44rem);--typo-h4:clamp(var(--typo-h5),3.600vw,1.728rem);--typo-h3:clamp(var(--typo-h4),4.320vw,2.0736rem);--typo-h2:clamp(var(--typo-h3),5.184vw,2.4883rem);--typo-h1:clamp(var(--typo-h2),6.221vw,2.986rem);--typo-h1-hero:clamp(var(--typo-h1),9.331vw,4.479rem);--typo-p-hero:clamp(1.25rem,3.125vw,1.5rem)}.font-variant-small-caps{font-variant:small-caps}.icon-inline{align-items:center;display:inline-flex}.icon-inline:before{content:"";display:block}.prose-container{@apply prose-layout-container}.prose-container:where(:not(.prose+.prose-container,.prose-container+.prose-container))>:first-child,.prose-container:where(:not(.prose+.prose-container,.prose-container+.prose-container))>:first-child>:first-child,.prose:where(:not(.prose+.prose,.prose-container+.prose))>:first-child,.prose:where(:not(.prose+.prose,.prose-container+.prose))>:first-child>:first-child{margin-block-start:0}.prose-container>:last-child,.prose-container>:last-child>:last-child,.prose>:last-child,.prose>:last-child>:last-child{margin-block-end:0}:where(.h1,.h2,.h3,.h4,.h5,.h6).prose,:where(.prose-container,.prose) :where(h1,h2,h3,h4,h5,h6){margin-block-end:.4lh;margin-block-start:.9lh;text-wrap:pretty}:where(.p,.pre,.table,.ol,.ul,.img,.figure,.blockquote).prose,:where(.prose-container,.prose) :where(p,pre,table,ol,ul,img,figure,blockquote){margin-block-end:1lh;text-wrap:pretty}:where(.prose-container,.prose) hr+*{margin-block-start:0}:where(.prose-container,.prose) :has(+hr){margin-block-end:0}.hr,.prose hr,.prose-container hr{border-color:var(--color-global-background-accent);margin-block-end:1lh;margin-block-start:1lh}.h1,.prose h1,.prose-container h1{color:color-mix(in srgb-linear,var(--custom-accent-color) 40%,currentColor);font-size:var(--typo-h1);letter-spacing:.0025em;line-height:1.125}.h1.hero,.prose h1.hero,.prose-container h1.hero{font-size:var(--typo-h1-hero);line-height:1}.h2,.prose h2,.prose-container h2{font-size:var(--typo-h2);font-weight:var(--font-weight-extralight);letter-spacing:.0108em;line-height:1.1765}.h3,.prose h3,.prose-container h3{font-size:var(--typo-h3);font-weight:var(--font-weight-extralight);letter-spacing:.022em;line-height:1.2}.h4,.prose h4,.prose-container h4{font-size:var(--typo-h4);letter-spacing:.035em;line-height:1.25}.h5,.prose h5,.prose-container h5{font-size:var(--typo-h5);letter-spacing:.0532em;line-height:1.28}.h6,.prose h6,.prose-container h6{font-size:var(--typo-h6);letter-spacing:.0532em;line-height:1.28}.p,.prose p,.prose-container p{font-size:1rem;letter-spacing:.03em;line-height:1.5}.p.hero,.prose p.hero,.prose-container p.hero{font-size:var(--typo-p-hero);line-height:1.3}.note{color:var(--color-foreground-scale-g);font-size:.95rem!important;letter-spacing:.05rem!important;line-height:1.5!important}.code,.pre,.prose code,.prose pre,.prose-container code,.prose-container pre{border-radius:.25rem;color:var(--color-foreground-scale-e);font-family:monospace;font-size:.9rem;font-weight:bolder;outline:dashed 2px var(--color-background-scale-g);outline-offset:-2px;padding:.2rem .25rem;transition:color,outline-color;transition-duration:.15s}.code:hover,.pre:hover,.prose code:hover,.prose pre:hover,.prose-container code:hover,.prose-container pre:hover{color:var(--color-global-foreground)}.pre,.prose pre,.prose-container pre{padding:.5rem .75rem}.prose table,.prose-container table,.table{border-collapse:collapse}.prose table td,.prose table th,.prose-container table td,.prose-container table th,.table td,.table th{border:1px solid var(--color-background-scale-f);padding:.5rem;vertical-align:top}.prose table tr:nth-child(2n),.prose-container table tr:nth-child(2n),.table tr:nth-child(2n){background-color:var(--color-background-scale-a)}.prose table th,.prose-container table th,.table th{background-color:var(--color-background-scale-c);font-weight:var(--font-weight-normal);letter-spacing:.1em;text-align:start}.prose table td>:last-child,.prose-container table td>:last-child,.table td>:last-child{margin-block-end:0}.ol,.prose ol,.prose ul,.prose-container ol,.prose-container ul,.ul{list-style-type:disc;padding-inline-start:1.25rem}.ol li ol,.ol li ul,.prose ol li ol,.prose ol li ul,.prose ul li ol,.prose ul li ul,.prose-container ol li ol,.prose-container ol li ul,.prose-container ul li ol,.prose-container ul li ul,.ul li ol,.ul li ul{padding-inline-start:2rem}.ol li:not(:last-child) ol:not(p+ol),.ol li:not(:last-child) ul:not(p+ul),.prose ol li:not(:last-child) ol:not(p+ol),.prose ol li:not(:last-child) ul:not(p+ul),.prose ul li:not(:last-child) ol:not(p+ol),.prose ul li:not(:last-child) ul:not(p+ul),.prose-container ol li:not(:last-child) ol:not(p+ol),.prose-container ol li:not(:last-child) ul:not(p+ul),.prose-container ul li:not(:last-child) ol:not(p+ol),.prose-container ul li:not(:last-child) ul:not(p+ul),.ul li:not(:last-child) ol:not(p+ol),.ul li:not(:last-child) ul:not(p+ul){margin-block-end:0}.ol,.prose ol,.prose-container ol{counter-reset:item;list-style-type:none}.ol>li,.prose ol>li,.prose-container ol>li{counter-increment:item}.ol>li::marker,.prose ol>li::marker,.prose-container ol>li::marker{content:counters(item,".") ". "}.img,.prose img,.prose-container img{border:2px solid var(--color-background-scale-e);border-radius:.25rem;margin-left:auto;margin-right:auto;max-height:450px;width:auto}.figure,.prose figure,.prose-container figure{display:table;margin-left:auto;margin-right:auto}.figure img,.prose figure img,.prose-container figure img{display:block;margin:0}.figure img:has(+figcaption),.prose figure img:has(+figcaption),.prose-container figure img:has(+figcaption){border-bottom-left-radius:0;border-bottom-right-radius:0}.figure figcaption,.prose figure figcaption,.prose-container figure figcaption{background-color:var(--color-background-scale-e);border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;caption-side:bottom;display:table-caption;font-size:.85rem;padding:.5rem;text-align:center}.figure figcaption>*,.prose figure figcaption>*,.prose-container figure figcaption>*{font-size:.85rem}.figure figcaption>:last-child,.prose figure figcaption>:last-child,.prose-container figure figcaption>:last-child{margin-block-end:0}.blockquote,.prose blockquote,.prose-container blockquote{background-color:var(--color-background-scale-b);border-radius:.25rem;font-family:serif;font-size:1.1rem;padding:.25rem .75rem}.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6{counter-reset:l1}:where(.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h2{counter-reset:l2}:where(.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h2:before{content:counter(l1) ". ";counter-increment:l1}:where(.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h3{counter-reset:l3}:where(.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h3:before{content:counter(l1) "." counter(l2) ". ";counter-increment:l2}:where(.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h4{counter-reset:l4}:where(.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h4:before{content:counter(l1) "." counter(l2) "." counter(l3) ". ";counter-increment:l3}:where(.prose-numbering-5,.prose-numbering-6) h5{counter-reset:l5}:where(.prose-numbering-5,.prose-numbering-6) h5:before{content:counter(l1) "." counter(l2) "." counter(l3) "." counter(l4) ". ";counter-increment:l4}.prose-numbering-6 h6{counter-reset:l6}.prose-numbering-6 h6:before{content:counter(l1) "." counter(l2) "." counter(l3) "." counter(l4) "." counter(l5) ". ";counter-increment:l5}}
|
|
1
|
+
@utility prose-layout-container{margin-left:auto;margin-right:auto;max-width:var(--container-3xl);width:100%;&.sm{max-width:var(--container-md)}}@layer components{:root{--typo-h6:clamp(var(--text-base),2.500vw,1.2rem);--typo-h5:clamp(var(--typo-h6),3.000vw,1.44rem);--typo-h4:clamp(var(--typo-h5),3.600vw,1.728rem);--typo-h3:clamp(var(--typo-h4),4.320vw,2.0736rem);--typo-h2:clamp(var(--typo-h3),5.184vw,2.4883rem);--typo-h1:clamp(var(--typo-h2),6.221vw,2.986rem);--typo-h1-hero:clamp(var(--typo-h1),9.331vw,4.479rem);--typo-p-hero:clamp(1.25rem,3.125vw,1.5rem);--extra-scroll-margin:0px}.font-variant-small-caps{font-variant:small-caps}.icon-inline{align-items:center;display:inline-flex}.icon-inline:before{content:"";display:block}.prose-container{@apply prose-layout-container}.prose-container:where(:not(.prose+.prose-container,.prose-container+.prose-container))>:first-child,.prose-container:where(:not(.prose+.prose-container,.prose-container+.prose-container))>:first-child>:first-child,.prose:where(:not(.prose+.prose,.prose-container+.prose))>:first-child,.prose:where(:not(.prose+.prose,.prose-container+.prose))>:first-child>:first-child{margin-block-start:0}.prose-container>:last-child,.prose-container>:last-child>:last-child,.prose>:last-child,.prose>:last-child>:last-child{margin-block-end:0}:where(.h1,.h2,.h3,.h4,.h5,.h6).prose,:where(.prose-container,.prose) :where(h1,h2,h3,h4,h5,h6){margin-block-end:.4lh;margin-block-start:.9lh;scroll-margin-block-start:calc(--spacing(6) + var(--extra-scroll-margin, 0px));text-wrap:pretty}:where(.p,.pre,.table,.ol,.ul,.img,.figure,.blockquote).prose,:where(.prose-container,.prose) :where(p,pre,table,ol,ul,img,figure,blockquote){margin-block-end:1lh;text-wrap:pretty}:where(.prose-container,.prose) hr+*{margin-block-start:0}:where(.prose-container,.prose) :has(+hr){margin-block-end:0}.hr,.prose hr,.prose-container hr{border-color:var(--color-global-background-accent);margin-block-end:1lh;margin-block-start:1lh}.h1,.prose h1,.prose-container h1{color:color-mix(in srgb-linear,var(--custom-accent-color) 40%,currentColor);font-size:var(--typo-h1);letter-spacing:.0025em;line-height:1.125}.h1.hero,.prose h1.hero,.prose-container h1.hero{font-size:var(--typo-h1-hero);line-height:1}.h2,.prose h2,.prose-container h2{font-size:var(--typo-h2);font-weight:var(--font-weight-extralight);letter-spacing:.0108em;line-height:1.1765}.h3,.prose h3,.prose-container h3{font-size:var(--typo-h3);font-weight:var(--font-weight-extralight);letter-spacing:.022em;line-height:1.2}.h4,.prose h4,.prose-container h4{font-size:var(--typo-h4);letter-spacing:.035em;line-height:1.25}.h5,.prose h5,.prose-container h5{font-size:var(--typo-h5);letter-spacing:.0532em;line-height:1.28}.h6,.prose h6,.prose-container h6{font-size:var(--typo-h6);letter-spacing:.0532em;line-height:1.28}.p,.prose p,.prose-container p{font-size:1rem;letter-spacing:.03em;line-height:1.5}.p.hero,.prose p.hero,.prose-container p.hero{font-size:var(--typo-p-hero);line-height:1.3}.note{color:var(--color-foreground-scale-g);font-size:.95rem!important;letter-spacing:.05rem!important;line-height:1.5!important}.code,.pre,.prose code,.prose pre,.prose-container code,.prose-container pre{border-radius:.25rem;color:var(--color-foreground-scale-e);font-family:monospace;font-size:.9rem;font-weight:bolder;outline:dashed 2px var(--color-background-scale-g);outline-offset:-2px;padding:.2rem .25rem;transition:color,outline-color;transition-duration:.15s}.code:hover,.pre:hover,.prose code:hover,.prose pre:hover,.prose-container code:hover,.prose-container pre:hover{color:var(--color-global-foreground)}.pre,.prose pre,.prose-container pre{padding:.5rem .75rem}.prose table,.prose-container table,.table{border-collapse:collapse}.prose table td,.prose table th,.prose-container table td,.prose-container table th,.table td,.table th{border:1px solid var(--color-background-scale-f);padding:.5rem;vertical-align:top}.prose table tr:nth-child(2n),.prose-container table tr:nth-child(2n),.table tr:nth-child(2n){background-color:var(--color-background-scale-a)}.prose table th,.prose-container table th,.table th{background-color:var(--color-background-scale-c);font-weight:var(--font-weight-normal);letter-spacing:.1em;text-align:start}.prose table td>:last-child,.prose-container table td>:last-child,.table td>:last-child{margin-block-end:0}.ol,.prose ol,.prose ul,.prose-container ol,.prose-container ul,.ul{list-style-type:disc;padding-inline-start:1.25rem}.ol li ol,.ol li ul,.prose ol li ol,.prose ol li ul,.prose ul li ol,.prose ul li ul,.prose-container ol li ol,.prose-container ol li ul,.prose-container ul li ol,.prose-container ul li ul,.ul li ol,.ul li ul{padding-inline-start:2rem}.ol li:not(:last-child) ol:not(p+ol),.ol li:not(:last-child) ul:not(p+ul),.prose ol li:not(:last-child) ol:not(p+ol),.prose ol li:not(:last-child) ul:not(p+ul),.prose ul li:not(:last-child) ol:not(p+ol),.prose ul li:not(:last-child) ul:not(p+ul),.prose-container ol li:not(:last-child) ol:not(p+ol),.prose-container ol li:not(:last-child) ul:not(p+ul),.prose-container ul li:not(:last-child) ol:not(p+ol),.prose-container ul li:not(:last-child) ul:not(p+ul),.ul li:not(:last-child) ol:not(p+ol),.ul li:not(:last-child) ul:not(p+ul){margin-block-end:0}.ol,.prose ol,.prose-container ol{counter-reset:item;list-style-type:none}.ol>li,.prose ol>li,.prose-container ol>li{counter-increment:item}.ol>li::marker,.prose ol>li::marker,.prose-container ol>li::marker{content:counters(item,".") ". "}.img,.prose img,.prose-container img{border:2px solid var(--color-background-scale-e);border-radius:.25rem;margin-left:auto;margin-right:auto;max-height:450px;width:auto}.figure,.prose figure,.prose-container figure{display:table;margin-left:auto;margin-right:auto}.figure img,.prose figure img,.prose-container figure img{display:block;margin:0}.figure img:has(+figcaption),.prose figure img:has(+figcaption),.prose-container figure img:has(+figcaption){border-bottom-left-radius:0;border-bottom-right-radius:0}.figure figcaption,.prose figure figcaption,.prose-container figure figcaption{background-color:var(--color-background-scale-e);border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;caption-side:bottom;display:table-caption;font-size:.85rem;padding:.5rem;text-align:center}.figure figcaption>*,.prose figure figcaption>*,.prose-container figure figcaption>*{font-size:.85rem}.figure figcaption>:last-child,.prose figure figcaption>:last-child,.prose-container figure figcaption>:last-child{margin-block-end:0}.blockquote,.prose blockquote,.prose-container blockquote{background-color:var(--color-background-scale-b);border-radius:.25rem;font-family:serif;font-size:1.1rem;padding:.25rem .75rem}.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6{counter-reset:l1}:where(.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h2{counter-reset:l2}:where(.prose-numbering-2,.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h2:before{content:counter(l1) ". ";counter-increment:l1}:where(.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h3{counter-reset:l3}:where(.prose-numbering-3,.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h3:before{content:counter(l1) "." counter(l2) ". ";counter-increment:l2}:where(.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h4{counter-reset:l4}:where(.prose-numbering-4,.prose-numbering-5,.prose-numbering-6) h4:before{content:counter(l1) "." counter(l2) "." counter(l3) ". ";counter-increment:l3}:where(.prose-numbering-5,.prose-numbering-6) h5{counter-reset:l5}:where(.prose-numbering-5,.prose-numbering-6) h5:before{content:counter(l1) "." counter(l2) "." counter(l3) "." counter(l4) ". ";counter-increment:l4}.prose-numbering-6 h6{counter-reset:l6}.prose-numbering-6 h6:before{content:counter(l1) "." counter(l2) "." counter(l3) "." counter(l4) "." counter(l5) ". ";counter-increment:l5}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RouteLocationGeneric } from 'vue-router';
|
|
2
|
+
/**
|
|
3
|
+
* Strictly compare the entirety of two URLs, including their hashes.
|
|
4
|
+
*
|
|
5
|
+
* This is required for two reasons:
|
|
6
|
+
*
|
|
7
|
+
* 1) NuxtLink does not provide equivalent results when parsing `:to` and `:href`
|
|
8
|
+
* props (the value of a URL's `hash` will appear in the `fullPath` of the former,
|
|
9
|
+
* but not the latter).
|
|
10
|
+
* 2) NuxtLink does not take into account the value of `hash` when computing whether
|
|
11
|
+
* a link is active. This makes sense for a lot of circumstances, but in some cases
|
|
12
|
+
* is required.
|
|
13
|
+
*/
|
|
14
|
+
export declare function areRoutesStrictEqual(routeA: RouteLocationGeneric | undefined, routeB: RouteLocationGeneric | undefined): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function areRoutesStrictEqual(routeA, routeB) {
|
|
2
|
+
if (!(routeA && routeB)) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
let fullPathA = routeA.fullPath;
|
|
6
|
+
let fullPathB = routeB.fullPath;
|
|
7
|
+
if (routeA.hash && !fullPathA.endsWith(routeA.hash)) {
|
|
8
|
+
fullPathA += routeA.hash;
|
|
9
|
+
}
|
|
10
|
+
if (routeB.hash && !fullPathB.endsWith(routeB.hash)) {
|
|
11
|
+
fullPathB += routeB.hash;
|
|
12
|
+
}
|
|
13
|
+
return fullPathA === fullPathB;
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@resee-movies/nuxt-ux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "The next-gen user experience library for ReSee Movies - currently in development. ",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/ReSee-Movies/nuxt-ux.git"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dist"
|
|
36
36
|
],
|
|
37
37
|
"scripts": {
|
|
38
|
-
"dev": "npm run dev:prepare && nuxi dev playground --
|
|
38
|
+
"dev": "npm run dev:prepare && nuxi dev playground --port 3003 --public",
|
|
39
39
|
"dev:preview": "npm run dev:build && nuxi preview playground --port 3003",
|
|
40
40
|
"dev:build": "nuxi build playground",
|
|
41
41
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
|
|
@@ -72,19 +72,19 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@egoist/tailwindcss-icons": "^1.9.0",
|
|
74
74
|
"@iconify-json/ph": "^1.2.2",
|
|
75
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
75
|
+
"@iconify-json/simple-icons": "^1.2.65",
|
|
76
76
|
"@iconify-json/solar": "^1.2.5",
|
|
77
77
|
"@nuxt/fonts": "^0.12.1",
|
|
78
78
|
"@nuxtjs/device": "^4.0.0",
|
|
79
79
|
"@primeuix/utils": "^0.6.1",
|
|
80
|
-
"@primevue/forms": "^4.5.
|
|
81
|
-
"@primevue/nuxt-module": "^4.5.
|
|
80
|
+
"@primevue/forms": "^4.5.4",
|
|
81
|
+
"@primevue/nuxt-module": "^4.5.4",
|
|
82
82
|
"@resee-movies/utilities": "^0.11.0",
|
|
83
|
-
"@tailwindcss/postcss": "^4.1.
|
|
84
|
-
"@tailwindcss/vite": "^4.1.
|
|
83
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
84
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
85
85
|
"@vueuse/core": "^14.1.0",
|
|
86
|
-
"primevue": "^4.5.
|
|
87
|
-
"tailwindcss": "^4.1.
|
|
88
|
-
"zod": "^4.
|
|
86
|
+
"primevue": "^4.5.4",
|
|
87
|
+
"tailwindcss": "^4.1.18",
|
|
88
|
+
"zod": "^4.3.5"
|
|
89
89
|
}
|
|
90
90
|
}
|