完整版BedrockWiki镜像!
This commit is contained in:
100
docs/.vitepress/theme/components/content/Button.vue
Normal file
100
docs/.vitepress/theme/components/content/Button.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<component
|
||||
:is="link ? `a` : `button`"
|
||||
class="btn"
|
||||
:class="classes"
|
||||
:href="link"
|
||||
>
|
||||
<component
|
||||
:is="icon"
|
||||
v-if="icon"
|
||||
class="btn-icon"
|
||||
:class="[iconColor]"
|
||||
/>
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
<component
|
||||
:is="iconRight"
|
||||
v-if="iconRight"
|
||||
class="btn-icon"
|
||||
:class="[iconColor]"
|
||||
/>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { Component } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
color?: '' | 'green' | 'blue' | 'red'
|
||||
link?: string
|
||||
text?: boolean
|
||||
// Expecting Vue Components
|
||||
icon?: Component
|
||||
iconRight?: Component
|
||||
iconColor?: string
|
||||
}>()
|
||||
|
||||
const classes = computed(() => {
|
||||
let classes = []
|
||||
if (props.color) classes.push(props.color)
|
||||
if (props.text) classes.push('text')
|
||||
return classes
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
@apply px-3 py-1 mx-1 my-2 bg-white rounded-md !no-underline !shadow-md !hover:shadow-sm !focus:shadow-sm !active:shadow-none border !cursor-pointer border-box;
|
||||
@apply text-true-gray-500 hover:text-true-gray-600 focus:text-true-gray-600 active:text-true-gray-800;
|
||||
@apply !inline-flex justify-center items-center;
|
||||
@apply transition-colors;
|
||||
}
|
||||
|
||||
.btn.text {
|
||||
@apply !bg-transparent border-none !shadow-none !hover:shadow-none !hover:bg-light-50 !hover:bg-opacity-5 !hover:shadow-md;
|
||||
}
|
||||
|
||||
button.btn {
|
||||
@apply align-bottom;
|
||||
}
|
||||
|
||||
.dark .btn {
|
||||
@apply bg-true-gray-900;
|
||||
}
|
||||
.green {
|
||||
@apply text-green-500 hover:text-green-600 focus:text-green-600 active:text-green-800;
|
||||
}
|
||||
.blue {
|
||||
@apply text-blue-500 hover:text-blue-600 focus:text-blue-600 active:text-blue-800;
|
||||
}
|
||||
.red {
|
||||
@apply text-red-500 hover:text-red-600 focus:text-red-600 active:text-red-800;
|
||||
}
|
||||
|
||||
.default {
|
||||
@apply text-dark-500 hover:text-dark-600 focus:text-dark-600 active:text-dark-800;
|
||||
}
|
||||
|
||||
.dark .default {
|
||||
@apply text-light-500 hover:text-light-600 focus:text-light-600 active:text-light-800;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
fill: currentColor !important;
|
||||
}
|
||||
|
||||
.btn-icon:first-child {
|
||||
@apply mr-2;
|
||||
}
|
||||
|
||||
.btn-icon:last-child {
|
||||
@apply ml-2;
|
||||
}
|
||||
</style>
|
||||
129
docs/.vitepress/theme/components/content/Checklist.vue
Normal file
129
docs/.vitepress/theme/components/content/Checklist.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<label
|
||||
v-for="el, i in elementsObjects"
|
||||
:key="i"
|
||||
class="checklist-label"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="el.checked === true"
|
||||
disabled
|
||||
>
|
||||
<span
|
||||
class="checkbox"
|
||||
:class="{ 'checkbox-checked': el.checked }"
|
||||
/>
|
||||
<div
|
||||
v-if="el.checked"
|
||||
class="tickmark-checked"
|
||||
><img src="/assets/images/icons/tick.png"></div>
|
||||
<div
|
||||
v-else
|
||||
class="tickmark-unchecked"
|
||||
/>
|
||||
<span
|
||||
class="checklist-content"
|
||||
>
|
||||
{{ el.content }}
|
||||
</span>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useSlots, ref } from 'vue'
|
||||
|
||||
interface IElement {
|
||||
checked: boolean;
|
||||
content: string;
|
||||
}
|
||||
|
||||
const slots = useSlots()
|
||||
|
||||
let elementsObjects = ref<IElement[]>([])
|
||||
|
||||
// get content of slots
|
||||
// @ts-ignore
|
||||
slots.default()[0].children.forEach(element => {
|
||||
element = element.children
|
||||
if (typeof element === 'object') {
|
||||
let new_element = ''
|
||||
// @ts-ignore
|
||||
element.forEach( e => {
|
||||
// if element uses some markdown formatting, the formatting will be added manually
|
||||
if (typeof e.type === 'symbol') {
|
||||
new_element += e.children
|
||||
}
|
||||
else {
|
||||
// if element uses exactly TWO formattings, they both will be added.
|
||||
// currently, its not possible to add more than two. I dont know if its even necessary two add this, as the only use of two formattings i am aware of is ***text***.
|
||||
if (typeof e.children === 'object') {
|
||||
new_element += `<${e.type}><${e.children[0].type}>` + e.children[0].children + `</${e.children[0].type}></${e.type}>`
|
||||
}
|
||||
else {
|
||||
new_element += `<${e.type}>` + e.children + `</${e.type}>`
|
||||
}
|
||||
}
|
||||
})
|
||||
element = new_element
|
||||
}
|
||||
elementsObjects.value.push({
|
||||
content: element.startsWith('[x]') ? element.replace('[x]', '') : element.replace('[ ]', ''),
|
||||
checked: element.startsWith('[x]')
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:root {
|
||||
--tickmark-color: rgb(83, 146, 224);
|
||||
}
|
||||
.checklist-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
.checklist-label input[type='checkbox'] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.checklist-content {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 0;
|
||||
background: rgba(39, 38, 38, 0.719);
|
||||
border: 1px solid rgb(22, 21, 21);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.checkbox-checked {
|
||||
background: rgb(204, 225, 250);
|
||||
}
|
||||
|
||||
.tickmark-unchecked {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 1.1rem;
|
||||
height: 1rem;
|
||||
left: -1.08rem;
|
||||
bottom: 0.27rem;
|
||||
}
|
||||
|
||||
.tickmark-checked {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 1.1rem;
|
||||
height: 1rem;
|
||||
left: -0.9rem;
|
||||
bottom: 0.52rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px){
|
||||
.checklist-content {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="border-2 p-2 m-2 rounded-md border-gray">
|
||||
<FolderViewChild
|
||||
:depth="-1"
|
||||
:name="'.'"
|
||||
:nodes="getData()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import FolderViewChild from './FolderViewChild.vue'
|
||||
|
||||
export default {
|
||||
name: 'FolderView',
|
||||
components: {
|
||||
FolderViewChild
|
||||
},
|
||||
props: {
|
||||
paths: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fillDict(data, path) {
|
||||
let first = path.shift()
|
||||
|
||||
// Create if needed
|
||||
if (!(first in data)) {
|
||||
data[first] = {
|
||||
name: first,
|
||||
children: {},
|
||||
}
|
||||
}
|
||||
|
||||
// If there are more paths, recurse
|
||||
if (path.length > 0) {
|
||||
this.fillDict(data[first]['children'], path)
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
let data = {
|
||||
name: 'root',
|
||||
children: {},
|
||||
}
|
||||
|
||||
this.paths.forEach(path => {
|
||||
path = path.split('/')
|
||||
this.fillDict(data['children'], path)
|
||||
})
|
||||
|
||||
return data
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div
|
||||
:style="indent"
|
||||
:class="{ collapsed: collapsed }"
|
||||
@click="toggleChildren"
|
||||
>
|
||||
{{ getDisplay() }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="{ hidden: collapsed }">
|
||||
<FolderViewChild
|
||||
v-for="(node, i) in getNodes()"
|
||||
:key="i"
|
||||
:depth="depth + 1"
|
||||
:nodes="node"
|
||||
:name="node.name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
|
||||
export default {
|
||||
name: 'FolderViewChild',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-prop-types
|
||||
nodes: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
default: () => {},
|
||||
},
|
||||
depth: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
name : {
|
||||
type: String,
|
||||
default: () => '???',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return { collapsed: false }
|
||||
},
|
||||
computed: {
|
||||
indent() {
|
||||
return { transform: `translate(${this.depth * 30}px)` }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
toggleChildren() {
|
||||
if (this.isFolder()) {
|
||||
this.collapsed = !this.collapsed
|
||||
}
|
||||
},
|
||||
getDisplay() {
|
||||
if (this.depth === -1) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return this.getIcon(this.name) + this.getName(this.name)
|
||||
},
|
||||
isFolder() {
|
||||
return Object.keys(this.nodes.children).length > 0
|
||||
},
|
||||
getNodes() {
|
||||
return Object.values(this.nodes.children)
|
||||
},
|
||||
getIcon(path) {
|
||||
if (this.isFolder())
|
||||
{
|
||||
return '📁'
|
||||
}
|
||||
|
||||
let type = path.split('.').pop()
|
||||
|
||||
if (type === 'js' || type === 'ts' || type === 'json' || type === 'mcfunction') {
|
||||
return '📝'
|
||||
} else if (type === 'mcstructure') {
|
||||
return '🏛'
|
||||
} else if (type === 'png' || type === 'jpg' || type === 'jpeg') {
|
||||
return '🖼️'
|
||||
} else if (type === 'ogg' || type === 'wav' || type === 'mp3' || type === 'fsb') {
|
||||
return '🔊'
|
||||
} else if (type === 'lang') {
|
||||
return '🈵'
|
||||
} else {
|
||||
return '📁'
|
||||
}
|
||||
},
|
||||
getName(path) {
|
||||
return path.split('/')[0]
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.collapsed {
|
||||
opacity: 0.5;
|
||||
font-style: italic;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user