lint code

This commit is contained in:
Timothy Yin 2024-11-20 04:39:14 +08:00
parent 8cbef084da
commit 6e22ccc4c0
14 changed files with 170 additions and 139 deletions

View File

@ -7,14 +7,22 @@ const route = useRoute()
<template> <template>
<header <header
class="w-full flex justify-between items-center py-2 h-16 z-50 border-b sticky top-0 bg-white/90 dark:bg-neutral-900 transition-colors" class="w-full flex justify-between items-center py-2 h-16 z-50 border-b sticky top-0 bg-white/90 dark:bg-neutral-900 transition-colors"
:class="[route.path !== '/' ? 'border-b-neutral-100 dark:border-b-neutral-800' : 'border-b-transparent dark:border-b-transparent']"> :class="[route.path !== '/' ? 'border-b-neutral-100 dark:border-b-neutral-800' : 'border-b-transparent dark:border-b-transparent']"
>
<NuxtLink to="/" class="text-neutral-900 dark:text-neutral-100"> <NuxtLink to="/" class="text-neutral-900 dark:text-neutral-100">
<h1 class="font-medium text-xl">RayineSoft<sup class="text-sm"> &copy;</sup></h1> <h1 class="font-medium text-xl">
<h2 class="font-normal text-xs">Common Components</h2> RayineSoft<sup class="text-sm"> &copy;</sup>
</h1>
<h2 class="font-normal text-xs">
Common Components
</h2>
</NuxtLink> </NuxtLink>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<NuxtLink to="/getting-started" class="text-neutral-400 dark:text-neutral-500" <NuxtLink
active-class="!text-neutral-700 dark:!text-neutral-300">Docs</NuxtLink> to="/getting-started"
class="text-neutral-400 dark:text-neutral-500"
active-class="!text-neutral-700 dark:!text-neutral-300"
>Docs</NuxtLink>
</div> </div>
</header> </header>
</template> </template>

View File

@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from "vue"; import { ref, computed } from 'vue'
interface TocItem { interface TocItem {
id: string; id: string
depth: number; depth: number
text: string; text: string
children?: TocItem[]; children?: TocItem[]
} }
const props = defineProps<{ const props = defineProps<{
toc: TocItem[]; toc: TocItem[]
maxDepth?: number; maxDepth?: number
}>(); }>()
const maxDepth = props.maxDepth ?? 3; const maxDepth = props.maxDepth ?? 3
const filteredToc = computed(() => { const filteredToc = computed(() => {
const filterByDepth = (items: TocItem[]): TocItem[] => { const filterByDepth = (items: TocItem[]): TocItem[] => {
@ -22,54 +22,55 @@ const filteredToc = computed(() => {
.map(item => ({ .map(item => ({
...item, ...item,
children: item.children ? filterByDepth(item.children) : undefined, children: item.children ? filterByDepth(item.children) : undefined,
})); }))
}; }
return filterByDepth(props.toc); return filterByDepth(props.toc)
}); })
const activeLinks = ref<string[]>([]); const activeLinks = ref<string[]>([])
onMounted(() => { onMounted(() => {
const observer = new IntersectionObserver( const observer = new IntersectionObserver(
(entries) => { (entries) => {
entries.forEach(entry => { entries.forEach((entry) => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
activeLinks.value.push(entry.target.id); activeLinks.value.push(entry.target.id)
} else {
activeLinks.value = activeLinks.value.filter(link => link !== entry.target.id);
} }
}); else {
activeLinks.value = activeLinks.value.filter(link => link !== entry.target.id)
}
})
}, },
// { rootMargin: '0px 0px -80% 0px' } // { rootMargin: '0px 0px -80% 0px' }
); )
filteredToc.value.forEach(item => { filteredToc.value.forEach((item) => {
const element = document.getElementById(item.id); const element = document.getElementById(item.id)
if (element) { if (element) {
observer.observe(element); observer.observe(element)
} }
item.children?.forEach(child => { item.children?.forEach((child) => {
const childElement = document.getElementById(child.id); const childElement = document.getElementById(child.id)
if (childElement) { if (childElement) {
observer.observe(childElement); observer.observe(childElement)
} }
}); })
}); })
}); })
</script> </script>
<template> <template>
<ul> <ul>
<template v-for="item in filteredToc" :key="item.id"> <template v-for="item in filteredToc" :key="item.id">
<li> <li>
<NuxtLink :href="'#' + item.id" class="link" :class="{ 'active': activeLinks.includes(item.id) }"> <NuxtLink :href="'#' + item.id" class="link" :class="{ active: activeLinks.includes(item.id) }">
{{ item.text }} {{ item.text }}
</NuxtLink> </NuxtLink>
<ul v-if="item.children && item.children.length" class="ml-4"> <ul v-if="item.children && item.children.length" class="ml-4">
<template v-for="child in item.children" :key="child.id"> <template v-for="child in item.children" :key="child.id">
<li> <li>
<NuxtLink :href="'#' + child.id" class="link" :class="{ 'active': activeLinks.includes(child.id) }"> <NuxtLink :href="'#' + child.id" class="link" :class="{ active: activeLinks.includes(child.id) }">
{{ child.text }} {{ child.text }}
</NuxtLink> </NuxtLink>
</li> </li>

View File

@ -1,15 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import FileTypeVue from "../icon/VscodeIconsFileTypeVue.vue" import { camelCase, kebabCase, upperFirst } from 'scule'
import FileTypeTypescript from "../icon/VscodeIconsFileTypeTypescriptOfficial.vue" import FileTypeVue from '../icon/VscodeIconsFileTypeVue.vue'
import FileTypeJavascript from "../icon/VscodeIconsFileTypeJsOfficial.vue" import FileTypeTypescript from '../icon/VscodeIconsFileTypeTypescriptOfficial.vue'
import TablerTerminal from "../icon/TablerTerminal.vue"; import FileTypeJavascript from '../icon/VscodeIconsFileTypeJsOfficial.vue'
import { camelCase, kebabCase, upperFirst } from "scule"; import TablerTerminal from '../icon/TablerTerminal.vue'
const route = useRoute(); const route = useRoute()
const slots = defineSlots<{
default?: () => VNode[];
}>();
const IconComponents = { const IconComponents = {
'vue': FileTypeVue, 'vue': FileTypeVue,
@ -57,26 +53,27 @@ const code = computed(() => {
code += `/>\n</template> code += `/>\n</template>
\`\`\` \`\`\`
` `
return code; return code
}) })
const { data: codeRender, error: codeRenderError } = await useAsyncData(`${componentName}-renderer-${JSON.stringify({ slots: slots, code: code.value })}`, async () => { const { data: codeRender, error: codeRenderError } = await useAsyncData(`${componentName}-renderer-${JSON.stringify({ slots: props.slots, code: code.value })}`, async () => {
let formatted = '' let formatted = ''
try { try {
// @ts-ignore // @ts-ignore
formatted = await $prettier.format(code.value, { formatted = await $prettier.format(code.value, {
trailingComma: 'none', trailingComma: 'none',
semi: false, semi: false,
singleQuote: true singleQuote: true,
}) })
} catch { }
catch {
formatted = code.value formatted = code.value
} }
return parseMarkdown(formatted, { return parseMarkdown(formatted, {
}) })
}, { }, {
watch: [code] watch: [code],
}) })
</script> </script>
@ -84,21 +81,21 @@ const { data: codeRender, error: codeRenderError } = await useAsyncData(`${compo
<div class="border border-neutral-200 dark:border-neutral-700 rounded-lg not-prose my-2 overflow-hidden"> <div class="border border-neutral-200 dark:border-neutral-700 rounded-lg not-prose my-2 overflow-hidden">
<div v-if="filename" class="p-4 py-2 border-b border-neutral-200 dark:border-neutral-700"> <div v-if="filename" class="p-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<component v-if="lang" :is="IconComponents[lang]" class="inline" /> <component :is="IconComponents[lang]" v-if="lang" class="inline" />
<span class="text-sm text-neutral-500 dark:text-neutral-400">{{ filename }}</span> <span class="text-sm text-neutral-500 dark:text-neutral-400">{{ filename }}</span>
</span> </span>
</div> </div>
<div :class="['p-4 overflow-auto', !!codeRender ? 'border-b border-neutral-200 dark:border-neutral-700' : '']"> <div :class="['p-4 overflow-auto', !!codeRender ? 'border-b border-neutral-200 dark:border-neutral-700' : '']">
<component :is="componentName" v-bind="componentProps"> <component :is="componentName" v-bind="componentProps">
<slot></slot> <slot />
</component> </component>
</div> </div>
<template v-if="codeRender || codeRenderError"> <template v-if="codeRender || codeRenderError">
<div class="overflow-auto"> <div class="overflow-auto">
<ContentRenderer v-if="codeRender" :value="codeRender" class="p-4 bg-neutral-50 dark:bg-neutral-800/50" /> <ContentRenderer v-if="codeRender" :value="codeRender" class="p-4 bg-neutral-50 dark:bg-neutral-800/50" />
<pre class="p-4" v-if="codeRenderError">{{ codeRenderError }}</pre> <pre v-if="codeRenderError" class="p-4">{{ codeRenderError }}</pre>
</div> </div>
</template> </template>
</div> </div>

View File

@ -1,10 +1,16 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m5 7l5 5l-5 5m7 2h7"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m5 7l5 5l-5 5m7 2h7"
/></svg>
</template> </template>
<script> <script>
export default { export default {
name: 'TablerTerminal' name: 'TablerTerminal',
} }
</script> </script>

View File

@ -1,10 +1,9 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M2 2h28v28H2z"></path><path d="M20.809 23.875a2.87 2.87 0 0 0 2.6 1.6c1.09 0 1.787-.545 1.787-1.3c0-.9-.716-1.222-1.916-1.747l-.658-.282c-1.9-.809-3.16-1.822-3.16-3.964c0-1.973 1.5-3.476 3.853-3.476a3.89 3.89 0 0 1 3.742 2.107L25 18.128A1.79 1.79 0 0 0 23.311 17a1.145 1.145 0 0 0-1.259 1.128c0 .789.489 1.109 1.618 1.6l.658.282c2.236.959 3.5 1.936 3.5 4.133c0 2.369-1.861 3.667-4.36 3.667a5.06 5.06 0 0 1-4.795-2.691Zm-9.295.228c.413.733.789 1.353 1.693 1.353c.864 0 1.41-.338 1.41-1.653v-8.947h2.631v8.982c0 2.724-1.6 3.964-3.929 3.964a4.085 4.085 0 0 1-3.947-2.4Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M2 2h28v28H2z" /><path d="M20.809 23.875a2.87 2.87 0 0 0 2.6 1.6c1.09 0 1.787-.545 1.787-1.3c0-.9-.716-1.222-1.916-1.747l-.658-.282c-1.9-.809-3.16-1.822-3.16-3.964c0-1.973 1.5-3.476 3.853-3.476a3.89 3.89 0 0 1 3.742 2.107L25 18.128A1.79 1.79 0 0 0 23.311 17a1.145 1.145 0 0 0-1.259 1.128c0 .789.489 1.109 1.618 1.6l.658.282c2.236.959 3.5 1.936 3.5 4.133c0 2.369-1.861 3.667-4.36 3.667a5.06 5.06 0 0 1-4.795-2.691Zm-9.295.228c.413.733.789 1.353 1.693 1.353c.864 0 1.41-.338 1.41-1.653v-8.947h2.631v8.982c0 2.724-1.6 3.964-3.929 3.964a4.085 4.085 0 0 1-3.947-2.4Z" /></svg>
</template> </template>
<script> <script>
export default { export default {
name: 'VscodeIconsFileTypeJsOfficial' name: 'VscodeIconsFileTypeJsOfficial',
} }
</script> </script>

View File

@ -1,10 +1,16 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><rect width="28" height="28" x="2" y="2" fill="#3178c6" rx="1.312"></rect><path fill="#fff" fillRule="evenodd" d="M18.245 23.759v3.068a6.5 6.5 0 0 0 1.764.575a11.6 11.6 0 0 0 2.146.192a10 10 0 0 0 2.088-.211a5.1 5.1 0 0 0 1.735-.7a3.54 3.54 0 0 0 1.181-1.266a4.47 4.47 0 0 0 .186-3.394a3.4 3.4 0 0 0-.717-1.117a5.2 5.2 0 0 0-1.123-.877a12 12 0 0 0-1.477-.734q-.6-.249-1.08-.484a5.5 5.5 0 0 1-.813-.479a2.1 2.1 0 0 1-.516-.518a1.1 1.1 0 0 1-.181-.618a1.04 1.04 0 0 1 .162-.571a1.4 1.4 0 0 1 .459-.436a2.4 2.4 0 0 1 .726-.283a4.2 4.2 0 0 1 .956-.1a6 6 0 0 1 .808.058a6 6 0 0 1 .856.177a6 6 0 0 1 .836.3a4.7 4.7 0 0 1 .751.422V13.9a7.5 7.5 0 0 0-1.525-.4a12.4 12.4 0 0 0-1.9-.129a8.8 8.8 0 0 0-2.064.235a5.2 5.2 0 0 0-1.716.733a3.66 3.66 0 0 0-1.171 1.271a3.73 3.73 0 0 0-.431 1.845a3.6 3.6 0 0 0 .789 2.34a6 6 0 0 0 2.395 1.639q.63.26 1.175.509a6.5 6.5 0 0 1 .942.517a2.5 2.5 0 0 1 .626.585a1.2 1.2 0 0 1 .23.719a1.1 1.1 0 0 1-.144.552a1.3 1.3 0 0 1-.435.441a2.4 2.4 0 0 1-.726.292a4.4 4.4 0 0 1-1.018.105a5.8 5.8 0 0 1-1.969-.35a5.9 5.9 0 0 1-1.805-1.045m-5.154-7.638h4v-2.527H5.938v2.527H9.92v11.254h3.171Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><rect
width="28"
height="28"
x="2"
y="2"
fill="#3178c6"
rx="1.312"
/><path fill="#fff" fillRule="evenodd" d="M18.245 23.759v3.068a6.5 6.5 0 0 0 1.764.575a11.6 11.6 0 0 0 2.146.192a10 10 0 0 0 2.088-.211a5.1 5.1 0 0 0 1.735-.7a3.54 3.54 0 0 0 1.181-1.266a4.47 4.47 0 0 0 .186-3.394a3.4 3.4 0 0 0-.717-1.117a5.2 5.2 0 0 0-1.123-.877a12 12 0 0 0-1.477-.734q-.6-.249-1.08-.484a5.5 5.5 0 0 1-.813-.479a2.1 2.1 0 0 1-.516-.518a1.1 1.1 0 0 1-.181-.618a1.04 1.04 0 0 1 .162-.571a1.4 1.4 0 0 1 .459-.436a2.4 2.4 0 0 1 .726-.283a4.2 4.2 0 0 1 .956-.1a6 6 0 0 1 .808.058a6 6 0 0 1 .856.177a6 6 0 0 1 .836.3a4.7 4.7 0 0 1 .751.422V13.9a7.5 7.5 0 0 0-1.525-.4a12.4 12.4 0 0 0-1.9-.129a8.8 8.8 0 0 0-2.064.235a5.2 5.2 0 0 0-1.716.733a3.66 3.66 0 0 0-1.171 1.271a3.73 3.73 0 0 0-.431 1.845a3.6 3.6 0 0 0 .789 2.34a6 6 0 0 0 2.395 1.639q.63.26 1.175.509a6.5 6.5 0 0 1 .942.517a2.5 2.5 0 0 1 .626.585a1.2 1.2 0 0 1 .23.719a1.1 1.1 0 0 1-.144.552a1.3 1.3 0 0 1-.435.441a2.4 2.4 0 0 1-.726.292a4.4 4.4 0 0 1-1.018.105a5.8 5.8 0 0 1-1.969-.35a5.9 5.9 0 0 1-1.805-1.045m-5.154-7.638h4v-2.527H5.938v2.527H9.92v11.254h3.171Z" /></svg>
</template> </template>
<script> <script>
export default { export default {
name: 'VscodeIconsFileTypeTypescriptOfficial' name: 'VscodeIconsFileTypeTypescriptOfficial',
} }
</script> </script>

View File

@ -1,10 +1,9 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#41b883" d="M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z"></path><path fill="#41b883" d="m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z"></path><path fill="#35495e" d="M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#41b883" d="M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z" /><path fill="#41b883" d="m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z" /><path fill="#35495e" d="M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z" /></svg>
</template> </template>
<script> <script>
export default { export default {
name: 'VscodeIconsFileTypeVue' name: 'VscodeIconsFileTypeVue',
} }
</script> </script>

View File

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
useSeoMeta({ useSeoMeta({
title: 'RayineSoft Common Components' title: 'RayineSoft Common Components',
}) })
</script> </script>
@ -8,7 +8,7 @@ useSeoMeta({
<div class="max-w-6xl mx-auto px-4"> <div class="max-w-6xl mx-auto px-4">
<TitleBar /> <TitleBar />
<main class="pt-4"> <main class="pt-4">
<slot></slot> <slot />
</main> </main>
</div> </div>
</template> </template>
@ -23,7 +23,6 @@ body {
background-color: rgba(0, 0, 0, 0) !important; background-color: rgba(0, 0, 0, 0) !important;
} */ } */
/* /*
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {

View File

@ -1,49 +1,49 @@
import module from "../src/module"; import defaultTheme from 'tailwindcss/defaultTheme'
import defaultTheme from "tailwindcss/defaultTheme"; import module from '../src/module'
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
compatibilityDate: "2024-04-03",
modules: ["@nuxt/content", "@nuxt/fonts", "@nuxtjs/color-mode", module], modules: ['@nuxt/content', '@nuxt/fonts', '@nuxtjs/color-mode', module],
devtools: { enabled: true }, devtools: { enabled: true },
colorMode: {
preference: 'system',
classSuffix: '',
},
content: {
highlight: {
langs: ['postcss', 'mdc', 'html', 'vue', 'ts', 'js', 'bash'],
},
},
mdc: {
highlight: {
theme: {
light: 'material-theme-lighter',
dark: 'material-theme',
},
themes: ['material-theme-lighter', 'material-theme'],
},
},
routeRules: {
'/components': { redirect: '/components/button' },
}, compatibilityDate: '2024-04-03',
typescript: {
includeWorkspace: true,
},
rayui: { rayui: {
// @ts-ignore // @ts-ignore
globalComponents: true, globalComponents: true,
safeColors: ["amber", "emerald", "red", "sky", "violet", "cyan"], safeColors: ['amber', 'emerald', 'red', 'sky', 'violet', 'cyan'],
},
routeRules: {
"/components": { redirect: "/components/button" },
}, },
tailwindcss: { tailwindcss: {
config: { config: {
theme: { theme: {
extend: { extend: {
fontFamily: { fontFamily: {
sans: ["Rubik", '"Noto Sans SC"', ...defaultTheme.fontFamily.sans], sans: ['Rubik', '"Noto Sans SC"', ...defaultTheme.fontFamily.sans],
}, },
}, },
}, },
}, },
}, },
colorMode: { })
preference: "system",
classSuffix: "",
},
content: {
highlight: {
langs: ["postcss", "mdc", "html", "vue", "ts", "js", "bash"],
},
},
mdc: {
highlight: {
theme: {
light: "material-theme-lighter",
dark: "material-theme",
},
themes: ["material-theme-lighter", "material-theme"],
},
},
typescript: {
includeWorkspace: true,
},
});

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { withoutTrailingSlash } from 'ufo'; import { withoutTrailingSlash } from 'ufo'
const route = useRoute() const route = useRoute()
@ -10,7 +10,7 @@ const { data: page } = await useAsyncData(route.path, () => queryContent(route.p
if (!page.value) { if (!page.value) {
throw createError({ throw createError({
statusCode: 404, statusMessage: 'Page not found', fatal: true statusCode: 404, statusMessage: 'Page not found', fatal: true,
}) })
} }
@ -21,8 +21,8 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
.where({ .where({
_extension: 'md', _extension: 'md',
navigation: { navigation: {
$ne: false $ne: false,
} },
}) })
.only(['title', 'description', '_path']) .only(['title', 'description', '_path'])
.findSurround(withoutTrailingSlash(route.path)) .findSurround(withoutTrailingSlash(route.path))
@ -41,8 +41,11 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
</NuxtLink> </NuxtLink>
<ul v-if="link.children" class="pl-4 pt-2 space-y-1"> <ul v-if="link.children" class="pl-4 pt-2 space-y-1">
<li v-for="child in link.children" :key="child._path"> <li v-for="child in link.children" :key="child._path">
<NuxtLink :to="child._path" class="text-sm text-neutral-500 dark:text-neutral-400" <NuxtLink
active-class="text-primary font-medium"> :to="child._path"
class="text-sm text-neutral-500 dark:text-neutral-400"
active-class="text-primary font-medium"
>
{{ child.title }} {{ child.title }}
</NuxtLink> </NuxtLink>
</li> </li>
@ -55,22 +58,27 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
<div class="col-span-12" :class="[hasToc ? 'md:col-span-8' : 'md:col-span-10']"> <div class="col-span-12" :class="[hasToc ? 'md:col-span-8' : 'md:col-span-10']">
<div> <div>
<h1 class="text-3xl text-primary font-medium">{{ page?.title || 'untitled' }}</h1> <h1 class="text-3xl text-primary font-medium">
<p v-if="page?.description" class="text-lg text-neutral-500 mt-2">{{ page.description }}</p> {{ page?.title || 'untitled' }}
</h1>
<p v-if="page?.description" class="text-lg text-neutral-500 mt-2">
{{ page.description }}
</p>
</div> </div>
<hr class="my-4 dark:border-neutral-700" /> <hr class="my-4 dark:border-neutral-700">
<div class="doc-body"> <div class="doc-body">
<ContentRenderer v-if="page?.body" :value="page" /> <ContentRenderer v-if="page?.body" :value="page" />
</div> </div>
<div <div
class="w-full flex justify-between gap-4 mt-12 pt-12 border-t border-t-neutral-200 dark:border-t-neutral-700"> class="w-full flex justify-between gap-4 mt-12 pt-12 border-t border-t-neutral-200 dark:border-t-neutral-700"
>
<div class="flex-1"> <div class="flex-1">
<NuxtLink v-if="surround?.[0]" :to="surround[0]._path" class="surround-btn"> <NuxtLink v-if="surround?.[0]" :to="surround[0]._path" class="surround-btn">
<div> <div>
<span class="tip">Previous</span> <span class="tip">Previous</span>
<span class="title">{{ surround[0].title }}</span> <span class="title">{{ surround[0].title }}</span>
<span class="description" v-if="surround[0].description">{{ surround[0].description }}</span> <span v-if="surround[0].description" class="description">{{ surround[0].description }}</span>
</div> </div>
</NuxtLink> </NuxtLink>
</div> </div>
@ -79,7 +87,7 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
<div> <div>
<span class="tip">Next</span> <span class="tip">Next</span>
<span class="title">{{ surround[1].title }}</span> <span class="title">{{ surround[1].title }}</span>
<span class="description" v-if="surround[1].description">{{ surround[1].description }}</span> <span v-if="surround[1].description" class="description">{{ surround[1].description }}</span>
</div> </div>
</NuxtLink> </NuxtLink>
</div> </div>
@ -88,7 +96,8 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
<div v-if="hasToc" class="hidden" :class="{ 'col-span-2 md:block': hasToc }"> <div v-if="hasToc" class="hidden" :class="{ 'col-span-2 md:block': hasToc }">
<div <div
class="bg-neutral-50 dark:bg-neutral-800/50 rounded-lg px-4 py-3 overflow-hidden overflow-y-auto sticky top-[calc(64px+16px)]"> class="bg-neutral-50 dark:bg-neutral-800/50 rounded-lg px-4 py-3 overflow-hidden overflow-y-auto sticky top-[calc(64px+16px)]"
>
<span class="text-xs text-neutral-600 dark:text-neutral-300 font-medium inline-block mb-2"> <span class="text-xs text-neutral-600 dark:text-neutral-300 font-medium inline-block mb-2">
Table of contents Table of contents
</span> </span>

View File

@ -5,11 +5,18 @@ const router = useRouter()
<template> <template>
<div class="flex flex-col gap-8"> <div class="flex flex-col gap-8">
<div <div
class="py-20 flex flex-col justify-center items-center rounded-xl border border-neutral-200 dark:border-neutral-800 pattern"> class="py-20 flex flex-col justify-center items-center rounded-xl border border-neutral-200 dark:border-neutral-800 pattern"
>
<div class="text-xl text-neutral-600 dark:text-neutral-300 font-bold"> <div class="text-xl text-neutral-600 dark:text-neutral-300 font-bold">
<h2 class="text-xl">RayineUI <span class="font-medium">is multi-purpose</span></h2> <h2 class="text-xl">
<h1 class="text-4xl text-primary">Customizable</h1> RayineUI <span class="font-medium">is multi-purpose</span>
<h1 class="text-2xl text-primary font-medium pl-0.5">UI Library</h1> </h2>
<h1 class="text-4xl text-primary">
Customizable
</h1>
<h1 class="text-2xl text-primary font-medium pl-0.5">
UI Library
</h1>
</div> </div>
</div> </div>
<div class="flex justify-center items-center gap-4"> <div class="flex justify-center items-center gap-4">

View File

@ -1,17 +1,17 @@
export const renderObject = (obj: any): string => { export const renderObject = (obj: any): string => {
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
return `[${obj.map(renderObject).join(", ")}]`; return `[${obj.map(renderObject).join(', ')}]`
} }
if (typeof obj === "object") { if (typeof obj === 'object') {
return `{ ${Object.entries(obj) return `{ ${Object.entries(obj)
.map(([key, value]) => `${key}: ${renderObject(value)}`) .map(([key, value]) => `${key}: ${renderObject(value)}`)
.join(", ")} }`; .join(', ')} }`
} }
if (typeof obj === "string") { if (typeof obj === 'string') {
return `'${obj}'`; return `'${obj}'`
} }
return obj; return obj
}; }

View File

@ -86,13 +86,13 @@ export default defineNuxtModule<ModuleOptions>({
watch: false, watch: false,
}) })
addComponentsDir({ addComponentsDir({
path: resolve(runtimePath, "components", "overlays"), path: resolve(runtimePath, 'components', 'overlays'),
prefix: _options.prefix, prefix: _options.prefix,
global: _options.globalComponents, global: _options.globalComponents,
watch: false, watch: false,
}) })
addComponentsDir({ addComponentsDir({
path: resolve(runtimePath, "components", "icons"), path: resolve(runtimePath, 'components', 'icons'),
prefix: 'Icon', prefix: 'Icon',
global: _options.globalComponents, global: _options.globalComponents,
watch: false, watch: false,

View File

@ -28,12 +28,12 @@ export const installTailwind = (
}) })
const configTemplate = addTemplate({ const configTemplate = addTemplate({
filename: "ray-tailwind.config.cjs", filename: 'ray-tailwind.config.cjs',
write: true, write: true,
getContents: ({ nuxt }) => ` getContents: ({ nuxt }) => `
const { defaultExtractor: createDefaultExtractor } = require('tailwindcss/lib/lib/defaultExtractor.js') const { defaultExtractor: createDefaultExtractor } = require('tailwindcss/lib/lib/defaultExtractor.js')
const { customSafelistExtractor, generateSafelist } = require(${JSON.stringify( const { customSafelistExtractor, generateSafelist } = require(${JSON.stringify(
resolve(runtimePath, "utils", "colors") resolve(runtimePath, 'utils', 'colors'),
)}) )})
const defaultExtractor = createDefaultExtractor({ tailwindConfig: { separator: ':' } }) const defaultExtractor = createDefaultExtractor({ tailwindConfig: { separator: ':' } })
@ -46,10 +46,10 @@ export const installTailwind = (
content: { content: {
files: [ files: [
${JSON.stringify( ${JSON.stringify(
resolve(runtimePath, "components/**/*.{vue,mjs,ts}") resolve(runtimePath, 'components/**/*.{vue,mjs,ts}'),
)}, )},
${JSON.stringify( ${JSON.stringify(
resolve(runtimePath, "ui.config/**/*.{mjs,js,ts}") resolve(runtimePath, 'ui.config/**/*.{mjs,js,ts}'),
)} )}
], ],
}, },
@ -63,19 +63,19 @@ export const installTailwind = (
return [ return [
...defaultExtractor(content), ...defaultExtractor(content),
...customSafelistExtractor(${JSON.stringify( ...customSafelistExtractor(${JSON.stringify(
moduleOptions.prefix moduleOptions.prefix,
)}, content, ${JSON.stringify( )}, content, ${JSON.stringify(
nuxt.options.appConfig.rayui.colors nuxt.options.appConfig.rayui.colors,
)}, ${JSON.stringify(moduleOptions.safeColors)}) )}, ${JSON.stringify(moduleOptions.safeColors)})
] ]
} }
}, },
safelist: generateSafelist(${JSON.stringify( safelist: generateSafelist(${JSON.stringify(
moduleOptions.safeColors || [] moduleOptions.safeColors || [],
)}, ${JSON.stringify(nuxt.options.appConfig.rayui.colors)}), )}, ${JSON.stringify(nuxt.options.appConfig.rayui.colors)}),
} }
`, `,
}); })
const { configPath: userTwConfigPath = [], ...twModuleConfig } const { configPath: userTwConfigPath = [], ...twModuleConfig }
= nuxt.options.tailwindcss ?? {} = nuxt.options.tailwindcss ?? {}