mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-02-01 20:57:57 +01:00
feat(module): add support for vue using unplugin (#2416)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
120
playground-vue/src/app.vue
Normal file
120
playground-vue/src/app.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<script setup lang="ts">
|
||||
import { splitByCase, upperFirst } from 'scule'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore included for compatibility with Nuxt playground
|
||||
import { useAppConfig } from '#imports'
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
|
||||
appConfig.toaster = reactive({
|
||||
position: 'bottom-right' as const,
|
||||
expand: true,
|
||||
duration: 5000
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const components = [
|
||||
'accordion',
|
||||
'alert',
|
||||
'avatar',
|
||||
'badge',
|
||||
'breadcrumb',
|
||||
'button',
|
||||
'button-group',
|
||||
'card',
|
||||
'carousel',
|
||||
'checkbox',
|
||||
'chip',
|
||||
'collapsible',
|
||||
'context-menu',
|
||||
'command-palette',
|
||||
'drawer',
|
||||
'dropdown-menu',
|
||||
'form',
|
||||
'form-field',
|
||||
'input',
|
||||
'input-menu',
|
||||
'kbd',
|
||||
'link',
|
||||
'modal',
|
||||
'navigation-menu',
|
||||
'pagination',
|
||||
'popover',
|
||||
'progress',
|
||||
'radio-group',
|
||||
'select',
|
||||
'select-menu',
|
||||
'separator',
|
||||
'shortcuts',
|
||||
'skeleton',
|
||||
'slideover',
|
||||
'slider',
|
||||
'switch',
|
||||
'tabs',
|
||||
'textarea',
|
||||
'toast',
|
||||
'tooltip'
|
||||
]
|
||||
|
||||
const items = components.map(component => ({ label: upperName(component), to: `/components/${component}` }))
|
||||
|
||||
function upperName(name: string) {
|
||||
return splitByCase(name).map(p => upperFirst(p)).join('')
|
||||
}
|
||||
|
||||
const isCommandPaletteOpen = ref(false)
|
||||
|
||||
function onSelect(item: any) {
|
||||
router.push(item.to)
|
||||
}
|
||||
|
||||
defineShortcuts({
|
||||
meta_k: () => isCommandPaletteOpen.value = true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UApp :toaster="(appConfig.toaster as any)">
|
||||
<div class="h-screen w-screen overflow-hidden flex min-h-0 bg-[var(--ui-bg)]" vaul-drawer-wrapper>
|
||||
<UNavigationMenu :items="items" orientation="vertical" class="hidden lg:flex border-r border-[var(--ui-border)] overflow-y-auto w-48 p-4" />
|
||||
<UNavigationMenu :items="items" orientation="horizontal" class="lg:hidden border-b border-[var(--ui-border)] overflow-x-auto" />
|
||||
|
||||
<div class="flex-1 flex flex-col items-center justify-around overflow-y-auto w-full py-12 px-4">
|
||||
<Suspense>
|
||||
<RouterView />
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UModal v-model:open="isCommandPaletteOpen" class="sm:h-96">
|
||||
<template #content>
|
||||
<UCommandPalette placeholder="Search a component..." :groups="[{ id: 'items', items }]" :fuse="{ resultLimit: 100 }" @update:model-value="onSelect" @update:open="value => isCommandPaletteOpen = value" />
|
||||
</template>
|
||||
</UModal>
|
||||
</UApp>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
|
||||
@theme {
|
||||
--font-family-sans: 'Public Sans', sans-serif;
|
||||
|
||||
--color-green-50: #EFFDF5;
|
||||
--color-green-100: #D9FBE8;
|
||||
--color-green-200: #B3F5D1;
|
||||
--color-green-300: #75EDAE;
|
||||
--color-green-400: #00DC82;
|
||||
--color-green-500: #00C16A;
|
||||
--color-green-600: #00A155;
|
||||
--color-green-700: #007F45;
|
||||
--color-green-800: #016538;
|
||||
--color-green-900: #0A5331;
|
||||
--color-green-950: #052E16;
|
||||
}
|
||||
</style>
|
||||
54
playground-vue/src/main.ts
Normal file
54
playground-vue/src/main.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { createApp, ref } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import uiPlugin from '@nuxt/ui/vue-plugin'
|
||||
|
||||
import App from './app.vue'
|
||||
|
||||
const pages = import.meta.glob('../../playground/app/pages/**/*.vue')
|
||||
const components = import.meta.glob('../../playground/app/components/**/*.vue')
|
||||
|
||||
const routes = Object.keys(pages).map((path) => {
|
||||
const name = path.match(/\.\.\/\.\.\/playground\/app\/pages(.*)\.vue$/)![1].toLowerCase()
|
||||
return {
|
||||
path: name === '/index' ? '/' : name,
|
||||
component: pages[path]
|
||||
}
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
routes,
|
||||
history: createWebHistory()
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
Object.entries(components).forEach(([path, component]) => {
|
||||
const name = path.split('/').pop()!.replace('.vue', '')
|
||||
app.component(name, defineAsyncComponent(component as any))
|
||||
})
|
||||
|
||||
app.use(router)
|
||||
app.use(uiPlugin)
|
||||
|
||||
// @ts-expect-error unknown global property
|
||||
globalThis.useFetch = async (url: string, options: RequestInit & { transform?: (data) => any } = {}) => {
|
||||
const data = ref()
|
||||
const status = ref('idle')
|
||||
async function _fetch() {
|
||||
status.value = 'loading'
|
||||
try {
|
||||
data.value = await fetch(url, options).then(r => r.json()).then(r => options.transform ? options.transform(r) : r)
|
||||
status.value = 'success'
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
status.value = 'error'
|
||||
}
|
||||
}
|
||||
_fetch()
|
||||
return Promise.resolve({
|
||||
data,
|
||||
status
|
||||
})
|
||||
}
|
||||
|
||||
app.mount('#app')
|
||||
1
playground-vue/src/vite-env.d.ts
vendored
Normal file
1
playground-vue/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
Reference in New Issue
Block a user