Skip to content

Commit

Permalink
docs: Add versioned docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dshafik committed Jan 27, 2025
1 parent 5be1e2d commit c887cba
Show file tree
Hide file tree
Showing 64 changed files with 6,124 additions and 546 deletions.
133 changes: 85 additions & 48 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -1,13 +1,59 @@
import taskLists from "markdown-it-task-lists";
import { withMermaid } from "vitepress-plugin-mermaid";
import defineVersionedConfig from "vitepress-versioning-plugin";
import {withMermaid} from "vitepress-plugin-mermaid";

const BASE_PATH = '/'

// https://vitepress.dev/reference/site-config
export default withMermaid({
const defaultSidebar = [
{
"text": "Get Started",
"items": [
{ "text": "Installation", "link": "./install" },
{ "text": "Basic Usage", "link": "./basic-usage" }
]
},
{
"text": "Using Bag",
"items": [
{ "text": "Collections", "link": "./collections" },
{ "text": "Casting Values", "link": "./casting" },
{ "text": "Mapping", "link": "./mapping" },
{ "text": "Variadics", "link": "./variadics" },
{ "text": "Hiding Properties", "link": "./hidden" },
{ "text": "Transformers", "link": "./transformers" },
{ "text": "Validation", "link": "./validation" },
{ "text": "Computed Properties", "link": "./computed-properties" },
{ "text": "Output", "link": "./output" },
{ "text": "Wrapping", "link": "./wrapping" },
{ "text": "Factories / Testing", "link": "./testing" }
]
},
{
"text": "Laravel Integration",
"items": [
{ "text": "Controller Injection", "link": "./laravel-controller-injection" },
{ "text": "Route Parameter Binding", "link": "./laravel-route-parameter-binding" },
{ "text": "Eloquent Casting", "link": "./laravel-eloquent-casting" },
{ "text": "Generating Bag Classes", "link": "./laravel-artisan-make-bag-command" }
]
},
{
"text": "Other",
"items": [
{ "text": "Creating Bags from Objects", "link": "./object-to-bag" },
{ "text": "Why Bag?", "link": "./why" },
{ "text": "How Bag Works", "link": "./how-bag-works" },
]
}
];
export default withMermaid(defineVersionedConfig({
title: "Bag",
description: "Immutable Value Objects for PHP 8.3+",
base: BASE_PATH,
versioning: {
latestVersion: '2.1',
},
head: [
[
'meta',
Expand Down Expand Up @@ -41,65 +87,56 @@ export default withMermaid({
},
search: {
provider: 'local',
options: {
locales: {
"root": {
translations: {
button: {
buttonText: "Search latest version…"
}
}
}
},
async _render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.match(/\d+\.(\d+|x)/) !== null) return ''
return html
}
},
},
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: 'Home', link: '/' },
{ text: 'Documentation', link: '/install' }
],

sidebar: [
{ text: 'Home', link: './' },
{ text: 'Documentation', link: './install' },
{
text: 'Get Started',
items: [
{ text: 'Installation', link: '/install' },
{ text: 'Basic Usage', link: '/basic-usage' },
]
},
{
text: 'Using Bag',
items: [
{ text: 'Collections', link: '/collections' },
{ text: 'Casting Values', link: '/casting' },
{ text: 'Mapping', link: '/mapping' },
{ text: 'Variadics', link: '/variadics' },
{ text: 'Hiding Properties', link: '/hidden' },
{ text: 'Transformers', link: '/transformers' },
{ text: 'Validation', link: '/validation' },
{ text: 'Computed Properties', link: '/computed-properties' },
{ text: 'Output', link: '/output' },
{ text: 'Wrapping', link: '/wrapping' },
{ text: 'Factories / Testing', link: '/testing' },
]
},
{
text: 'Laravel Integration',
items: [
{ text: 'Controller Injection', link: '/laravel-controller-injection' },
{ text: 'Route Parameter Binding', link: '/laravel-route-parameter-binding' },
{ text: 'Eloquent Casting', link: '/laravel-eloquent-casting' },
{ text: 'Generating Bag Classes', link: '/laravel-artisan-make-bag-command' },
]
},
{
text: 'Other',
items: [
{ text: 'Creating Bags from Objects', link: '/object-to-bag' },
{ text: 'Why Bag?', link: '/why' },
{ text: 'How Bag Works', link: '/how-bag-works' },
{ text: 'Roadmap', link: '/roadmap' },
]
component: 'VersionSwitcher',
}
],

sidebar: {
"/": [
...defaultSidebar,
{"text": "What's New", "link": "./whats-new"},
{"text": "Upgrading to Bag 2", "link": "./upgrading"}
],
"/2.0/": [
...defaultSidebar,
{"text": "Upgrading to Bag 2", "link": "./upgrading"}
],
"/1.x/": defaultSidebar,
},

footer: {
message: "Made with 🦁💖🏳️‍🌈 by <a href=\"https://www.daveyshafik.com\">Davey Shafik</a>.",
copyright: "Released under the MIT License. Copyright © 2024 Davey Shafik.",
},

socialLinks: [
{ icon: 'github', link: 'https://github.com/dshafik/bag' }
]
],

versionSwitcher: false,
},
markdown: {
theme: {
Expand All @@ -111,4 +148,4 @@ export default withMermaid({
md.use(taskLists)
}
},
})
}, __dirname))
42 changes: 42 additions & 0 deletions docs/.vitepress/theme/OldVersionWarning.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script setup>
import {useData, useRoute} from "vitepress";
import { computed } from "vue";
import NotFound from "vitepress/dist/client/theme-default/NotFound.vue";
// Access the current route
const route = useRoute();
// Compute whether the current route is an old version
const isOldVersion = computed(() => {
return route.path.match(/\/\d+\.(\d+|x)\//) !== null;
});
const { page } = useData()
</script>

<template>
<div v-if="isOldVersion" class="old-version-warning warning custom-block github-alert">
<p class="custom-block-content">
You're browsing the documentation for an old version of Bag. Consider upgrading to
<a href="/upgrading">the latest version</a>.
</p>
</div>
<div v-if="page.isNotFound">
<NotFound v-if="page.isNotFound" />
</div>
</template>

<style>
.old-version-warning {
padding-top: 8px;
margin-bottom: 16px;
}
.old-version-warning .custom-block-content {
text-align: center;
}
.old-version-warning a {
text-decoration: underline;
}
</style>
165 changes: 165 additions & 0 deletions docs/.vitepress/theme/VersionSwitcher.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<script setup lang="ts">
import {useRoute, useRouter} from "vitepress"
import { computed, ref } from 'vue'
import VPMenuLink from 'vitepress/dist/client/theme-default/components/VPMenuLink.vue'
import VPFlyout from 'vitepress/dist/client/theme-default/components/VPFlyout.vue'
const props = defineProps<{
versioningPlugin: { versions: string[], latestVersion: string }
screenMenu?: boolean
}>();
const router = useRouter();
const route = useRoute();
const currentVersion = computed(() => {
let version = props.versioningPlugin.latestVersion;
for (const v of props.versioningPlugin.versions) {
if (router.route.path.startsWith(`/${v}/`)) {
version = v;
break;
}
}
return version;
});
const isOpen = ref(false);
const toggle = () => {
isOpen.value = !isOpen.value;
};
</script>

<template>
<VPFlyout v-if="!screenMenu" class="VPVersionSwitcher" icon="vpi-versioning" :button="currentVersion"
:label="'Switch Version'">
<div class="items">
<VPMenuLink :item="{
text: versioningPlugin.latestVersion,
link: `${route.path.replace(currentVersion, './')}`,
}" />
<template v-for="version in versioningPlugin.versions.slice().reverse()" :key="version">
<VPMenuLink :item="{
text: version,
link: `${route.path.replace(
(currentVersion == versioningPlugin.latestVersion ? /^\// : currentVersion),
(currentVersion == versioningPlugin.latestVersion ? version + '/' : version)
)}`,
}" />
</template>
</div>
</VPFlyout>
<div v-else class="VPScreenVersionSwitcher" :class="{ open: isOpen }">
<button class="button" aria-controls="navbar-group-version" :aria-expanded="isOpen" @click="toggle">
<span class="button-text"><span class="vpi-versioning icon" />Switch Version</span>
<span class="vpi-plus button-icon" />
</button>

<div id="navbar-group-version" class="items">
<VPMenuLink :item="{
text: versioningPlugin.latestVersion,
link: `/`,
}" />
<template v-for="version in versioningPlugin.versions.reverse()" :key="version">
<VPMenuLink :item="{
text: version,
link: `/${version}/`,
}" />
</template>
</div>
</div>
</template>

<style>
.vpi-versioning.option-icon {
margin-right: 2px !important;
}
.vpi-versioning {
--icon: url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iNjRweCIgaGVpZ2h0PSI2NHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0cm9rZS13aWR0aD0iMi4yIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNvbG9yPSIjMDAwMDAwIj48cGF0aCBkPSJNMTcgN0MxOC4xMDQ2IDcgMTkgNi4xMDQ1NyAxOSA1QzE5IDMuODk1NDMgMTguMTA0NiAzIDE3IDNDMTUuODk1NCAzIDE1IDMuODk1NDMgMTUgNUMxNSA2LjEwNDU3IDE1Ljg5NTQgNyAxNyA3WiIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjIuMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48L3BhdGg+PHBhdGggZD0iTTcgN0M4LjEwNDU3IDcgOSA2LjEwNDU3IDkgNUM5IDMuODk1NDMgOC4xMDQ1NyAzIDcgM0M1Ljg5NTQzIDMgNSAzLjg5NTQzIDUgNUM1IDYuMTA0NTcgNS44OTU0MyA3IDcgN1oiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIyLjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PC9wYXRoPjxwYXRoIGQ9Ik03IDIxQzguMTA0NTcgMjEgOSAyMC4xMDQ2IDkgMTlDOSAxNy44OTU0IDguMTA0NTcgMTcgNyAxN0M1Ljg5NTQzIDE3IDUgMTcuODk1NCA1IDE5QzUgMjAuMTA0NiA1Ljg5NTQzIDIxIDcgMjFaIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMi4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjwvcGF0aD48cGF0aCBkPSJNNyA3VjE3IiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMi4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjwvcGF0aD48cGF0aCBkPSJNMTcgN1Y4QzE3IDEwLjUgMTUgMTEgMTUgMTFMOSAxM0M5IDEzIDcgMTMuNSA3IDE2VjE3IiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMi4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjwvcGF0aD48L3N2Zz4=")
}
</style>

<style scoped>
.VPVersionSwitcher {
display: flex;
align-items: center;
}
.icon {
padding: 8px;
}
.title {
padding: 0 24px 0 12px;
line-height: 32px;
font-size: 14px;
font-weight: 700;
color: var(--vp-c-text-1);
}
.VPScreenVersionSwitcher {
border-bottom: 1px solid var(--vp-c-divider);
height: 48px;
overflow: hidden;
transition: border-color 0.5s;
}
.VPScreenVersionSwitcher .items {
visibility: hidden;
}
.VPScreenVersionSwitcher.open .items {
visibility: visible;
}
.VPScreenVersionSwitcher.open {
padding-bottom: 10px;
height: auto;
}
.VPScreenVersionSwitcher.open .button {
padding-bottom: 6px;
color: var(--vp-c-brand-1);
}
.VPScreenVersionSwitcher.open .button-icon {
/*rtl:ignore*/
transform: rotate(45deg);
}
.VPScreenVersionSwitcher button .icon {
margin-right: 8px;
}
.button {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 4px 11px 0;
width: 100%;
line-height: 24px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-text-1);
transition: color 0.25s;
}
.button:hover {
color: var(--vp-c-brand-1);
}
.button-icon {
transition: transform 0.25s;
}
.group:first-child {
padding-top: 0px;
}
.group+.group,
.group+.item {
padding-top: 4px;
}
</style>
Loading

0 comments on commit c887cba

Please sign in to comment.