Skip to content

Experiment with versions #899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions docs/.vuepress/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CloudBanner from "./components/CloudBanner.vue";
import KapaWidget from './components/KapaWidget.vue';
import UserFeedback from './components/TocWithFeedback';
import {usePostHog} from "./lib/usePosthog";
import SidebarLayout from "./layouts/SidebarLayout.vue";

declare const __VERSIONS__: { latest: string, selected: string, all: string[] }

Expand All @@ -30,14 +31,14 @@ const findEsMeta = (route) => {
}
}

interface ClientConfig {
enhance?: (context: {
app: any;
router: Router;
siteData: any;
}) => void | Promise<void>;
setup?: () => void;
}
// interface ClientConfig {
// enhance?: (context: {
// app: any;
// router: Router;
// siteData: any;
// }) => void | Promise<void>;
// setup?: () => void;
// }

const removeHtml = (path: string) => path.replace(".html", "");

Expand All @@ -55,9 +56,12 @@ const leave = (to: RouteLocationNormalized, from: RouteLocationNormalized) => {
}
}

const { posthog } = usePostHog();
const {posthog} = usePostHog();

export default defineClientConfig({
layouts: {
Layout: SidebarLayout
},
enhance({app, router, _}) {
app.component("CloudBanner", CloudBanner);
app.component("KapaWidget", KapaWidget);
Expand All @@ -84,11 +88,11 @@ export default defineClientConfig({
router.afterEach(() => {
setTimeout(() => { // to ensure this runs after DOM updates
try {
const {code} = JSON.parse(localStorage.getItem('VUEPRESS_TAB_STORE'));
const {code} = JSON.parse(localStorage.getItem('VUEPRESS_TAB_STORE')!);
if (code) { // If a valid 'code' is found in localStorage
Array.from(document.querySelectorAll('.vp-tab-nav'))
.forEach((button: HTMLButtonElement) => {
if (button.textContent.trim() === code) {
if (button.textContent!.trim() === code) {
button.click(); // click the button to switch the tab
}
});
Expand Down Expand Up @@ -135,13 +139,13 @@ export default defineClientConfig({
});
}, 1000);
}

// Check for 404 page after navigation completes
setTimeout(() => {
// Check for the specific elements with classes error-code and error-hint
const errorCodeElement = document.querySelector('p.error-code');
const errorHintElement = document.querySelector('p.error-hint');

// If both elements exist, we're on a 404 page
if (errorCodeElement && errorHintElement) {
// Capture the 404 event in PostHog
Expand All @@ -154,15 +158,15 @@ export default defineClientConfig({
});
}
}
}, 50);
}, 50);
});
router.beforeEach((to, from) => leave(to, from));
},
setup() {
onMounted(() => {
const route = useRoute();
if (route.path !== "/");
if (route.path !== "/") ;
});

},
} satisfies ClientConfig);
});
1 change: 0 additions & 1 deletion docs/.vuepress/components/KapaWidget.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script setup>
function triggerKapa() {
window.Kapa.open();

}
</script>

Expand Down
4 changes: 2 additions & 2 deletions docs/.vuepress/components/TocWithFeedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
usePageFrontmatter,
useRoute,
} from "vuepress/client";
import PrintButton from "vuepress-theme-hope/modules/info/components/PrintButton";
import { useMetaLocale } from "vuepress-theme-hope/modules/info/composables/index";
import PrintButton from "vuepress-theme-hope/components/base/PrintButton";
import { useMetaLocale } from "vuepress-theme-hope/composables/info/index";

import "../styles/toc.scss";

Expand Down
44 changes: 0 additions & 44 deletions docs/.vuepress/components/Version.vue

This file was deleted.

200 changes: 200 additions & 0 deletions docs/.vuepress/components/VersionDropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<script setup lang="ts">
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
import {useRoute, useRouter} from "vuepress/client";
import type {VersionDetail} from "../lib/versioning";
import VersionText from "./VersionText.vue";
import VersionSection from "./VersionSection.vue";

interface Props {
versions: VersionDetail[];
current: VersionDetail;
}

const props = defineProps<Props>();

const router = useRouter();
const route = useRoute();
const selectedVersion = ref(props.current);
const isOpen = ref(false);

const latestVersion = computed(() => props.versions[0]?.version);
const currentVersions = computed(() => props.versions.filter(v => !v.deprecated && !v.hide));
const deprecatedVersions = computed(() => props.versions.filter(v => v.deprecated && !v.hide));

watch(() => props.current, (newCurrent) => selectedVersion.value = newCurrent);

const toggleDropdown = (): void => {
isOpen.value = !isOpen.value;
}

const closeDropdown = (): void => {
isOpen.value = false;
}

const handleVersionSelect = (version: VersionDetail): void => {
const base = route.path.split('/').filter(seg => seg)[0];
router.replace(`/${base}/${version.path}/${version.startPage}`);

closeDropdown();
}

const handleClickOutside = (event: Event): void => {
const target = event.target as HTMLElement;
const dropdown = document.querySelector('.version-dropdown');

if (dropdown && !dropdown.contains(target)) {
closeDropdown();
}
}

const isSelected = (version: VersionDetail): boolean => {
return version.version === selectedVersion.value.version;
}

onMounted(() => document.addEventListener('click', handleClickOutside));
onUnmounted(() => document.removeEventListener('click', handleClickOutside));
</script>

<template>
<div class="version-dropdown">
<button
type="button"
class="version-trigger"
aria-label="Select documentation version"
:aria-expanded="isOpen"
aria-haspopup="listbox"
@click="toggleDropdown"
>
<VersionText class="selected-version" :version="selectedVersion" :latest="latestVersion"/>
<svg
class="dropdown-arrow"
:class="{ 'rotate-180': isOpen }"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L8 10L12 6"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>

<div
v-if="isOpen"
class="dropdown-menu"
role="listbox"
aria-label="Version options"
>
<!-- Current versions -->
<VersionSection
:versions="currentVersions"
title="Current"
:latest="latestVersion"
:is-selected="isSelected"
@select="handleVersionSelect"
/>

<!-- Deprecated versions -->
<VersionSection
:versions="deprecatedVersions"
title="Deprecated"
:margin-top="'8px'"
:latest="latestVersion"
:is-selected="isSelected"
:is-deprecated="true"
@select="handleVersionSelect"
/>
</div>
</div>
</template>

<style lang="scss" scoped>
.version-dropdown {
position: relative;
margin: 1rem 0.5rem 0;

.version-trigger {
width: 100%;
padding: 0.5rem 1rem;
border: 1px solid var(--vp-c-border);
border-radius: 0.375rem;
background-color: transparent;
font-size: 16px;
font-weight: 500;
color: var(--text-color);
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
text-align: left;
transition: all 0.2s ease;

&:hover,
&:focus {
outline: 2px solid rgba(78, 87, 90, 0.2);
outline-offset: 1px;
}

&:focus {
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.selected-version {
flex: 1;
}

.dropdown-arrow {
flex-shrink: 0;
margin-left: 0.5rem;
transition: transform 0.2s ease;

&.rotate-180 {
transform: rotate(180deg);
}
}
}

.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 50;
margin-top: 0.3rem;
border: 1px solid var(--vp-c-divider);
border-radius: 0.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
max-height: 250px;
overflow-y: auto;
background-color: var(--vp-c-bg-elv);

// Webkit scrollbar styles
&::-webkit-scrollbar {
width: 8px;
background-color: var(--vp-c-bg-elv);
}

&::-webkit-scrollbar-track {
background-color: var(--vp-c-bg-elv);
}

&::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.4);
border-radius: 4px;
}

// Firefox scrollbar
scrollbar-width: thin;
scrollbar-color: rgb(161, 161, 161) var(--vp-c-bg-elv);

// Styles for dropdown-separator and dropdown-item are now in VersionSection.vue
}
}
</style>
Loading