Skip to content
Merged
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
4 changes: 4 additions & 0 deletions docs/.vuepress/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import sidebar from "./config-client/sidebar";
import social from "./config-client/social";

import Chat from "./components/Chat.vue";
import CodeTabs from "./components/CodeTabs.vue";
import CodeWithCopy from "./components/CodeWithCopy.vue";

export default defineClientConfig({
rootComponents: [
Chat,
],
async enhance({ app }) {
app.config.globalProperties.$eventBus = mitt();
app.component("CodeTabs", CodeTabs);
app.component("CodeWithCopy", CodeWithCopy);
},
layouts: {
Layout,
Expand Down
160 changes: 160 additions & 0 deletions docs/.vuepress/components/CodeTabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<template>
<div class="code-tabs">
<div class="tab-buttons">
<button v-for="(tab, index) in tabs" :key="index" :class="{ active: activeTab === index }" @click="activeTab = index">
{{ tab.title }}
</button>
</div>

<div class="tab-content code-block-wrapper">
<button class="copy-button" @click="copyCode" aria-label="Copy code">
<svg v-if="!copied" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"/>
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/>
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"/>
</svg>
</button>

<pre><code ref="codeRef" class="language-bash">{{ tabs[activeTab].content }}</code></pre>
</div>
</div>
</template>

<script>
export default {
name: 'CodeTabs',
props: {
tabs: {
type: Array,
required: true
}
},
data() {
return {
activeTab: 0,
copied: false
}
},
watch: {
activeTab() {
this.highlight()
}
},
mounted() {
this.highlight()
},
methods: {
highlight() {
this.$nextTick(() => {
if (typeof window !== 'undefined' && window.hljs && this.$refs.codeRef) {
window.hljs.highlightElement(this.$refs.codeRef)
}
})
},
copyCode() {
const text = this.tabs[this.activeTab].content
navigator.clipboard.writeText(text).then(() => {
this.copied = true
setTimeout(() => (this.copied = false), 2000)
})
}
}
}
</script>

<style scoped>
.code-tabs {
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
margin-bottom: 1.5rem;
}

.tab-buttons {
display: flex;
background-color: #2d2d2d;
border-bottom: 1px solid #444;
}

.tab-buttons button {
padding: 0.85em;
flex: 1;
background: none;
border: none;
cursor: pointer;
font-weight: 500;
color: #ccc;
}

.tab-buttons button.active {
color: #fff;
border-bottom: 2px solid #1994f9;
font-weight: bold;
}

.tab-content {
position: relative;
background-color: #2d2d2d;
font-family: monospace;
padding: 1rem;
}

.code-block-wrapper {
background-color: #2d2d2d;
padding: 12px;
position: relative;
overflow: hidden;
}

pre {
margin: 0;
background-color: transparent;
color: #2d2d2d;
font-size: 14px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
max-width: 100%;
line-height: 1.5;
box-shadow: none;
}

code {
color: #ccc;
background: none;
display: block;
white-space: pre-wrap;
word-wrap: break-word;
}

.copy-button {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: none;
border: none;
cursor: pointer;
padding: 0.2rem;
z-index: 10;
}

.copy-button svg {
fill: #ccc;
width: 20px;
height: 20px;
transition: fill 0.2s;
}

.copy-button:hover svg {
fill: #1994f9;
}

.language-bash {
font-size: 0.85em;
padding: 0;
}
</style>


64 changes: 64 additions & 0 deletions docs/.vuepress/components/CodeWithCopy.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div class="code-block-wrapper">
<button class="copy-button" @click="copyCode" aria-label="Copy code">
<svg v-if="!copied" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" class="copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path>
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" class="copy-icon">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</button>
<slot />
</div>
</template>

<script setup>
import { ref } from 'vue';

const copied = ref(false);

function copyCode() {
const code = document.querySelector('.code-block-wrapper pre code')?.innerText;
if (code) {
navigator.clipboard.writeText(code);
copied.value = true;

setTimeout(() => {
copied.value = false;
}, 2000);
}
}
</script>

<style scoped>
.copy-button svg {
transition: fill 0.3s;
}

.copy-icon {
fill: #ccc;
width: 20px;
height: 20px;
}

.code-block-wrapper {
position: relative;
}

.copy-button {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: none;
border: none;
cursor: pointer;
padding: 0.2rem;
z-index: 10;
}

.copy-button:hover .copy-icon {
fill: #1994f9;
}
</style>

65 changes: 50 additions & 15 deletions docs/.vuepress/theme/components/Breadcrumb.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,50 @@
<template>
<div class="breadcrumb-wrapper">
<span class="breadcrumb-title">{{ siteTitle }}:</span>
<router-link class="breadcrumb" v-for="crumb in breadCrumbs" :key="crumb.path" :to="crumb.path">
<router-link
v-for="(crumb, index) in breadCrumbs"
:key="crumb.path"
class="breadcrumb"
:to="crumb.path"
>
{{ crumb.title }}
</router-link>
</div>
</template>

<script setup>
import {computed, inject} from "vue";
import {usePageData, useSiteData} from "@vuepress/client";
import { computed } from "vue";
import { usePageData, useSiteData } from "@vuepress/client";

const page = usePageData();
const site = useSiteData();

const siteTitle = computed(() => site.value.title);

const titleMap = {
'/els-for-languages/': 'ELS for Languages',
};

const page = usePageData()
const site = useSiteData()
const { locales: {siteTitle}} = inject("themeConfig")
const breadCrumbs = computed(() => {
const crumbs = [];
if (page.value.path !== '/') {
crumbs.push({path: page.value.path, title: page.value.title});
const segments = page.value.path.split("/").filter(Boolean);
const crumbs = [{ path: "/", title: "Documentation" }];
let cumulativePath = "";

for (let i = 0; i < segments.length; i++) {
cumulativePath += `/${segments[i]}`;
const isLast = i === segments.length - 1;
const fullPath = cumulativePath.endsWith(".html") ? cumulativePath : `${cumulativePath}/`;

let title;

if (isLast) {
title = page.value.title;
} else {
title = titleMap[fullPath] || fullPath;
}

crumbs.push({ path: fullPath, title });
}

return crumbs;
});
</script>
Expand All @@ -28,17 +54,26 @@ const breadCrumbs = computed(() => {

.breadcrumb
color $breadcrumbColor
text-decoration none

&::after
&:not(:last-child)::after
content " > "
font-family inherit
font-size inherit
color $breadcrumbColor

&:not(:last-child)
cursor pointer

&:hover
color #1994f9

&:last-child
cursor default
color $breadcrumbColor


.breadcrumb-title
color $breadcrumbColor
font-weight 600
margin-right 2px
</style>



Loading