Skip to content

Commit 81666fa

Browse files
author
Christopher Mühl
committed
Implement synchronization and saving
1 parent ede1168 commit 81666fa

File tree

2 files changed

+80
-20
lines changed

2 files changed

+80
-20
lines changed

README.md

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,48 @@
1-
# `vuepress-plugin-code-switcher`
1+
# vuepress-plugin-code-switcher
2+
Component that allows having synchronized language switchable code blocks (e.g. to switch between Java and Kotlin examples). Selected languages are persisted to local storage to have language selection be permanent across page requests.
23

3-
### Installation
4-
Install `vuepress-plugin-code-switcher` as a dependency and add it to your config's plugin list:
4+
## Installation
5+
```
6+
$ npm install vuepress-plugin-code-switcher --save
7+
```
8+
9+
After installing, add it to your Vuepress configuration's plugin list:
510

611
```js
712
module.exports = {
813
plugins: [ 'code-switcher' ]
914
}
1015
```
1116

12-
### Example
13-
```markdown
17+
### Usage
18+
````markdown
1419
<CodeSwitcher :languages="{js:'JavaScript',ts:'TypeScript'}">
1520
<template v-slot:js>
1621

17-
```js
18-
module.exports = function (str) {
19-
return typeof str === 'string' && str.trim() === str
20-
}
21-
```
22+
```js
23+
module.exports = function (str) {
24+
return typeof str === 'string' && str.trim() === str
25+
}
26+
```
2227

2328
</template>
2429
<template v-slot:ts>
2530

26-
```ts
27-
export default function isString (str: string) : str is string {
28-
return typeof str === 'string' && str.trim() === str
29-
}
30-
```
31+
```ts
32+
export default function isString (str: string) : str is string {
33+
return typeof str === 'string' && str.trim() === str
34+
}
35+
```
3136

3237
</template>
3338
</CodeSwitcher>
34-
```
39+
````
40+
41+
> The extra newline between the `<template>` tags and their content is necessary if you want to have Markdown interpreted within the component.
3542
36-
The extra newline between the `<template>` tags and their content is necessary if you want to have Markdown interpreted within the component.
43+
#### Props
44+
| Prop | Description | Type | Default |
45+
| ----- | ----- | ---- | ---- |
46+
| languages | The languages that can be switched between. The object expects shorthands as keys and the tab title as values. The shorthands will also be used as slot names | Object | --- |
47+
| name | All code switchers on one page with the same name will be synchronized | String | `'default'` |
48+
| isolated | if true, this block will not synchronize with any others or load/save its state to/from localstorage | Boolean | `false` |

components/CodeSwitcher.vue

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
<div class="tab-header">
44
<ul>
55
<li v-for="(name, shorthand) in languages"
6-
@click="selectedLanguage = shorthand"
6+
:key="shorthand"
7+
@click="switchLanguage(shorthand)"
78
:class="{ active: selectedLanguage === shorthand }"
89
> {{ name }}
910
</li>
1011
</ul>
1112
</div>
1213

1314
<div class="tab-content"
15+
:key="shorthand"
1416
v-for="(name, shorthand) in languages"
1517
v-show="shorthand === selectedLanguage"
1618
>
@@ -22,13 +24,59 @@
2224
<script>
2325
export default {
2426
props: {
25-
languages: Object
27+
name: {
28+
type: String,
29+
default: 'default'
30+
},
31+
isolated: {
32+
type: Boolean,
33+
default: false
34+
},
35+
languages: Object,
2636
},
2737
2838
data () {
2939
return {
30-
selectedLanguage: 'js'
40+
selectedLanguage: Object.keys(this.languages)[0]
3141
}
42+
},
43+
44+
computed: {
45+
root () {
46+
let parent = this, p
47+
while (p = parent.$parent) {
48+
parent = p
49+
}
50+
51+
return parent
52+
},
53+
54+
localStorageKey () {
55+
return `vuepress-plugin-code-switcher@${this.name}`
56+
}
57+
},
58+
59+
methods: {
60+
switchLanguage (value) {
61+
if (this.isolated) {
62+
return this.selectedLanguage = value
63+
}
64+
65+
localStorage.setItem(this.localStorageKey, value)
66+
this.root.$emit('change', { name: this.name, value })
67+
}
68+
},
69+
70+
created () {
71+
if (this.isolated) return
72+
73+
let selected = localStorage.getItem(this.localStorageKey)
74+
if (selected) this.selectedLanguage = selected
75+
76+
this.root.$on('change', ({ name, value }) => {
77+
if (name === this.name)
78+
this.selectedLanguage = value
79+
})
3280
}
3381
}
3482
</script>

0 commit comments

Comments
 (0)