feat: stackblitz/codesandbox editor (#130)
* feat: stackblitz editor * chore: update lockfile * fix: cant fetch ?raw dynamically after bundling * feat: add codesandbox
This commit is contained in:
parent
63197f03ce
commit
b2caaca1e2
35
apps/www/.vitepress/theme/components/CodeSandbox.vue
Normal file
35
apps/www/.vitepress/theme/components/CodeSandbox.vue
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { Icon } from '@iconify/vue'
|
||||||
|
import { makeCodeSandboxParams } from '../utils/codeeditor'
|
||||||
|
import Tooltip from './Tooltip.vue'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { type Style } from '@/lib/registry/styles'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
name: string
|
||||||
|
code: string
|
||||||
|
style: Style
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const sources = ref<Record<string, string>>({})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
sources.value['App.vue'] = props.code
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form action="https://codesandbox.io/api/v1/sandboxes/define" method="POST" target="_blank">
|
||||||
|
<input type="hidden" name="query" value="file=src/App.vue">
|
||||||
|
<input type="hidden" name="environment" value="server">
|
||||||
|
<input type="hidden" name="hidedevtools" value="1">
|
||||||
|
<input type="hidden" name="parameters" :value="makeCodeSandboxParams(name, style, sources)">
|
||||||
|
|
||||||
|
<Tooltip :content="`Open ${name} in CodeSandbox`">
|
||||||
|
<Button :variant="'ghost'" :size="'icon'" type="submit">
|
||||||
|
<Icon icon="ph-codesandbox-logo" />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import StyleSwitcher from './StyleSwitcher.vue'
|
import StyleSwitcher from './StyleSwitcher.vue'
|
||||||
import ComponentLoader from './ComponentLoader.vue'
|
import ComponentLoader from './ComponentLoader.vue'
|
||||||
|
import Stackblitz from './Stackblitz.vue'
|
||||||
|
import CodeSandbox from './CodeSandbox.vue'
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
|
||||||
import { useConfigStore } from '@/stores/config'
|
import { useConfigStore } from '@/stores/config'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
@ -39,6 +41,11 @@ const { style } = useConfigStore()
|
||||||
<TabsContent value="preview" class="relative rounded-md border">
|
<TabsContent value="preview" class="relative rounded-md border">
|
||||||
<div class="flex items-center justify-between p-4">
|
<div class="flex items-center justify-between p-4">
|
||||||
<StyleSwitcher />
|
<StyleSwitcher />
|
||||||
|
|
||||||
|
<div class="flex items-center gap-x-1">
|
||||||
|
<Stackblitz :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
|
||||||
|
<CodeSandbox :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:class="cn('preview flex min-h-[350px] w-full justify-center p-6 lg:p-10', {
|
:class="cn('preview flex min-h-[350px] w-full justify-center p-6 lg:p-10', {
|
||||||
|
|
|
||||||
34
apps/www/.vitepress/theme/components/Stackblitz.vue
Normal file
34
apps/www/.vitepress/theme/components/Stackblitz.vue
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { Icon } from '@iconify/vue'
|
||||||
|
import { makeStackblitzParams } from '../utils/codeeditor'
|
||||||
|
import Tooltip from './Tooltip.vue'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { type Style } from '@/lib/registry/styles'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
name: string
|
||||||
|
code: string
|
||||||
|
style: Style
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const sources = ref<Record<string, string>>({})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
sources.value['App.vue'] = props.code
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleClick() {
|
||||||
|
makeStackblitzParams(props.name, props.style, sources.value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Tooltip :content="`Open ${name} in Stackblitz`">
|
||||||
|
<Button :variant="'ghost'" :size="'icon'" @click="handleClick">
|
||||||
|
<Icon icon="simple-icons:stackblitz" />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
26
apps/www/.vitepress/theme/components/Tooltip.vue
Normal file
26
apps/www/.vitepress/theme/components/Tooltip.vue
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/tooltip'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
content: string
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger as-child>
|
||||||
|
<slot />
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
{{ content }}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</template>
|
||||||
|
|
@ -119,26 +119,29 @@ watch(() => $route.path, (n) => {
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div
|
<div class="flex items-center gap-x-1">
|
||||||
|
<Button
|
||||||
v-for="link in links"
|
v-for="link in links"
|
||||||
:key="link.name"
|
:key="link.name"
|
||||||
class="flex items-center space-x-1"
|
as="a"
|
||||||
|
:href="link.href" target="_blank"
|
||||||
|
:variant="'ghost'" :size="'icon'"
|
||||||
>
|
>
|
||||||
<a :href="link.href" target="_blank" class="text-foreground">
|
<component :is="link.icon" class="w-[20px] h-[20px]" />
|
||||||
<component :is="link.icon" class="w-5 h-5" />
|
</Button>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
<Button
|
||||||
class="flex items-center justify-center"
|
class="flex items-center justify-center"
|
||||||
aria-label="Toggle dark mode"
|
aria-label="Toggle dark mode"
|
||||||
@click="toggleDark()"
|
:variant="'ghost'"
|
||||||
|
:size="'icon'" @click="toggleDark()"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:is="isDark ? RadixIconsSun : RadixIconsMoon"
|
:is="isDark ? RadixIconsSun : RadixIconsMoon"
|
||||||
class="w-5 h-5 text-foreground"
|
class="w-[20px] h-[20px] text-foreground"
|
||||||
/>
|
/>
|
||||||
</button>
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
||||||
212
apps/www/.vitepress/theme/utils/codeeditor.ts
Normal file
212
apps/www/.vitepress/theme/utils/codeeditor.ts
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
import { getParameters } from 'codesandbox/lib/api/define'
|
||||||
|
import sdk from '@stackblitz/sdk'
|
||||||
|
import { dependencies as deps } from '../../../package.json'
|
||||||
|
import { Index as demoIndex } from '../../../../www/__registry__'
|
||||||
|
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
||||||
|
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
||||||
|
import { type Style } from '@/lib/registry/styles'
|
||||||
|
|
||||||
|
export function makeCodeSandboxParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||||
|
let files = {}
|
||||||
|
files = constructFiles(componentName, style, sources)
|
||||||
|
return getParameters({ files, template: 'node' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||||
|
const files: Record<string, string> = {}
|
||||||
|
Object.entries(constructFiles(componentName, style, sources)).forEach(([k, v]) => (files[`${k}`] = typeof v.content === 'object' ? JSON.stringify(v.content, null, 2) : v.content))
|
||||||
|
return sdk.openProject({
|
||||||
|
title: `${componentName} - Radix Vue`,
|
||||||
|
files,
|
||||||
|
template: 'node',
|
||||||
|
}, {
|
||||||
|
newWindow: true,
|
||||||
|
openFile: ['src/App.vue'],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const viteConfig = {
|
||||||
|
'vite.config.js': {
|
||||||
|
content: `import path from "path"
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'index.html': {
|
||||||
|
content: `<!DOCTYPE html>
|
||||||
|
<html class="dark" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Vue + TS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructFiles(componentName: string, style: Style, sources: Record<string, string>) {
|
||||||
|
const componentsJson = {
|
||||||
|
style,
|
||||||
|
tailwind: {
|
||||||
|
config: 'tailwind.config.js',
|
||||||
|
css: 'src/assets/index.css',
|
||||||
|
baseColor: 'zinc',
|
||||||
|
cssVariables: true,
|
||||||
|
},
|
||||||
|
aliases: {
|
||||||
|
utils: '@/utils',
|
||||||
|
components: '@/components',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconPackage = style === 'default' ? 'lucide-vue-next' : '@radix-icons/vue'
|
||||||
|
const dependencies = {
|
||||||
|
'vue': 'latest',
|
||||||
|
'radix-vue': deps['radix-vue'],
|
||||||
|
'@radix-ui/colors': 'latest',
|
||||||
|
'clsx': 'latest',
|
||||||
|
'class-variance-authority': 'latest',
|
||||||
|
'tailwind-merge': 'latest',
|
||||||
|
'tailwindcss-animate': 'latest',
|
||||||
|
[iconPackage]: 'latest',
|
||||||
|
'shadcn-vue': 'latest',
|
||||||
|
'typescript': 'latest',
|
||||||
|
}
|
||||||
|
|
||||||
|
const devDependencies = {
|
||||||
|
'vite': 'latest',
|
||||||
|
'@vitejs/plugin-vue': 'latest',
|
||||||
|
'vue-tsc': 'latest',
|
||||||
|
'tailwindcss': 'latest',
|
||||||
|
'postcss': 'latest',
|
||||||
|
'autoprefixer': 'latest',
|
||||||
|
}
|
||||||
|
|
||||||
|
const transformImportPath = (code: string) => {
|
||||||
|
let parsed = code
|
||||||
|
parsed = parsed.replaceAll(`@/lib/registry/${style}`, '@/components')
|
||||||
|
parsed = parsed.replaceAll('@/lib/utils', '@/utils')
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
const componentFiles = Object.keys(sources).filter(key => key.endsWith('.vue') && key !== 'index.vue')
|
||||||
|
const components: Record<string, any> = {}
|
||||||
|
componentFiles.forEach((i) => {
|
||||||
|
components[`src/${i}`] = {
|
||||||
|
isBinary: false,
|
||||||
|
content: transformImportPath(sources[i]),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// @ts-expect-error componentName migth not exist in Index
|
||||||
|
const registryDependencies = demoIndex[style][componentName as any]?.registryDependencies?.filter(i => i !== 'utils')
|
||||||
|
|
||||||
|
const files = {
|
||||||
|
'package.json': {
|
||||||
|
content: {
|
||||||
|
name: `shadcn-vue-${componentName.toLowerCase().replace(/ /g, '-')}`,
|
||||||
|
scripts: { start: `shadcn-vue add ${registryDependencies.join(' ')} -y && vite` },
|
||||||
|
dependencies,
|
||||||
|
devDependencies,
|
||||||
|
},
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'components.json': {
|
||||||
|
content: componentsJson,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
...viteConfig,
|
||||||
|
'tailwind.config.js': {
|
||||||
|
content: tailwindConfigRaw,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'postcss.config.js': {
|
||||||
|
content: `module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'tsconfig.json': {
|
||||||
|
content: `{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'src/utils.ts': {
|
||||||
|
isBinary: false,
|
||||||
|
content: `import { type ClassValue, clsx } from 'clsx'
|
||||||
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
import { camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs))
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
'src/assets/index.css': {
|
||||||
|
content: cssRaw,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'src/main.ts': {
|
||||||
|
content: `import { createApp } from 'vue';
|
||||||
|
import App from './App.vue';
|
||||||
|
import './assets/global.css';
|
||||||
|
import './assets/index.css';
|
||||||
|
|
||||||
|
createApp(App).mount('#app')`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
'src/App.vue': {
|
||||||
|
isBinary: false,
|
||||||
|
content: sources['index.vue'],
|
||||||
|
},
|
||||||
|
...components,
|
||||||
|
'src/assets/global.css': {
|
||||||
|
content: `body {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 120px;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: hsl(var(--background));
|
||||||
|
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
@apply w-full flex items-center justify-center px-12;
|
||||||
|
}`,
|
||||||
|
isBinary: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
@ -576,27 +576,7 @@ export const Index = {
|
||||||
component: () => import('../src/lib/registry/default/example/TypographyTable.vue').then(m => m.default),
|
component: () => import('../src/lib/registry/default/example/TypographyTable.vue').then(m => m.default),
|
||||||
files: ['../src/lib/registry/default/example/TypographyTable.vue'],
|
files: ['../src/lib/registry/default/example/TypographyTable.vue'],
|
||||||
},
|
},
|
||||||
ActivityGoal: {
|
|
||||||
name: 'ActivityGoal',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['button', 'card', 'themes', 'config'],
|
|
||||||
component: () => import('../src/lib/registry/default/example/ActivityGoal.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/default/example/ActivityGoal.vue'],
|
|
||||||
},
|
|
||||||
DataTable: {
|
|
||||||
name: 'DataTable',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['button', 'checkbox', 'dropdown-menu', 'input', 'table', 'card', 'utils'],
|
|
||||||
component: () => import('../src/lib/registry/default/example/DataTable.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/default/example/DataTable.vue'],
|
|
||||||
},
|
|
||||||
Metric: {
|
|
||||||
name: 'Metric',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['card', 'config'],
|
|
||||||
component: () => import('../src/lib/registry/default/example/Metric.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/default/example/Metric.vue'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'new-york': {
|
'new-york': {
|
||||||
AccordionDemo: {
|
AccordionDemo: {
|
||||||
|
|
@ -1173,26 +1153,5 @@ export const Index = {
|
||||||
component: () => import('../src/lib/registry/new-york/example/TypographyTable.vue').then(m => m.default),
|
component: () => import('../src/lib/registry/new-york/example/TypographyTable.vue').then(m => m.default),
|
||||||
files: ['../src/lib/registry/new-york/example/TypographyTable.vue'],
|
files: ['../src/lib/registry/new-york/example/TypographyTable.vue'],
|
||||||
},
|
},
|
||||||
ActivityGoal: {
|
|
||||||
name: 'ActivityGoal',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['button', 'card', 'themes', 'config'],
|
|
||||||
component: () => import('../src/lib/registry/new-york/example/ActivityGoal.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/new-york/example/ActivityGoal.vue'],
|
|
||||||
},
|
|
||||||
DataTable: {
|
|
||||||
name: 'DataTable',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['button', 'checkbox', 'dropdown-menu', 'input', 'table', 'card', 'utils'],
|
|
||||||
component: () => import('../src/lib/registry/new-york/example/DataTable.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/new-york/example/DataTable.vue'],
|
|
||||||
},
|
|
||||||
Metric: {
|
|
||||||
name: 'Metric',
|
|
||||||
type: 'components:example',
|
|
||||||
registryDependencies: ['card', 'config'],
|
|
||||||
component: () => import('../src/lib/registry/new-york/example/Metric.vue').then(m => m.default),
|
|
||||||
files: ['../src/lib/registry/new-york/example/Metric.vue'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
"@formkit/auto-animate": "^0.8.0",
|
"@formkit/auto-animate": "^0.8.0",
|
||||||
"@morev/vue-transitions": "^2.3.6",
|
"@morev/vue-transitions": "^2.3.6",
|
||||||
"@radix-icons/vue": "^1.0.0",
|
"@radix-icons/vue": "^1.0.0",
|
||||||
|
"@stackblitz/sdk": "^1.9.0",
|
||||||
"@tanstack/vue-table": "^8.10.3",
|
"@tanstack/vue-table": "^8.10.3",
|
||||||
"@unovis/ts": "^1.2.1",
|
"@unovis/ts": "^1.2.1",
|
||||||
"@unovis/vue": "1.3.0-alpha.3",
|
"@unovis/vue": "1.3.0-alpha.3",
|
||||||
|
|
@ -22,8 +23,10 @@
|
||||||
"@vueuse/core": "^10.4.1",
|
"@vueuse/core": "^10.4.1",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
|
"codesandbox": "^2.2.3",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"lucide-vue-next": "^0.276.0",
|
"lucide-vue-next": "^0.276.0",
|
||||||
|
"radix-vue": "^0.4.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"v-calendar": "^3.1.0",
|
"v-calendar": "^3.1.0",
|
||||||
"vee-validate": "4.11.7",
|
"vee-validate": "4.11.7",
|
||||||
|
|
@ -44,7 +47,6 @@
|
||||||
"@vue/compiler-dom": "^3.3.4",
|
"@vue/compiler-dom": "^3.3.4",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"lodash.template": "^4.5.0",
|
"lodash.template": "^4.5.0",
|
||||||
"radix-vue": "^0.4.1",
|
|
||||||
"rimraf": "^5.0.1",
|
"rimraf": "^5.0.1",
|
||||||
"tailwind-merge": "^1.14.0",
|
"tailwind-merge": "^1.14.0",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,4 @@ export const styles = [
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export type Style = (typeof styles)[number]
|
export type Style = typeof styles[number]['name']
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ import { computed } from 'vue'
|
||||||
import { useSessionStorage } from '@vueuse/core'
|
import { useSessionStorage } from '@vueuse/core'
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress'
|
||||||
import { type Theme, themes } from './../lib/registry/themes'
|
import { type Theme, themes } from './../lib/registry/themes'
|
||||||
import { styles } from '@/lib/registry/styles'
|
import { type Style, styles } from '@/lib/registry/styles'
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
theme: Theme['name']
|
theme: Theme['name']
|
||||||
radius: number
|
radius: number
|
||||||
style: string
|
style: Style
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RADII = [0, 0.25, 0.5, 0.75, 1]
|
export const RADII = [0, 0.25, 0.5, 0.75, 1]
|
||||||
|
|
|
||||||
|
|
@ -5,69 +5,65 @@
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 0 0% 100%;
|
--background: 0 0% 100%;
|
||||||
--foreground: 222.2 84% 4.9%;
|
--foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
--muted: 210 40% 96.1%;
|
|
||||||
--muted-foreground: 215.4 16.3% 46.9%;
|
|
||||||
|
|
||||||
--popover: 0 0% 100%;
|
|
||||||
--popover-foreground: 222.2 84% 4.9%;
|
|
||||||
|
|
||||||
--card: 0 0% 100%;
|
--card: 0 0% 100%;
|
||||||
--card-foreground: 222.2 84% 4.9%;
|
--card-foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
--border: 214.3 31.8% 91.4%;
|
--popover: 0 0% 100%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
--popover-foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
--primary: 222.2 47.4% 11.2%;
|
--primary: 240 5.9% 10%;
|
||||||
--primary-foreground: 210 40% 98%;
|
--primary-foreground: 0 0% 98%;
|
||||||
|
|
||||||
--secondary: 210 40% 96.1%;
|
--secondary: 240 4.8% 95.9%;
|
||||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
--secondary-foreground: 240 5.9% 10%;
|
||||||
|
--muted: 240 4.8% 95.9%;
|
||||||
--accent: 210 40% 96.1%;
|
--muted-foreground: 240 3.8% 46.1%;
|
||||||
--accent-foreground: 222.2 47.4% 11.2%;
|
--accent: 240 4.8% 95.9%;
|
||||||
|
--accent-foreground: 240 5.9% 10%;
|
||||||
|
|
||||||
--destructive: 0 84.2% 60.2%;
|
--destructive: 0 84.2% 60.2%;
|
||||||
--destructive-foreground: 210 40% 98%;
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
|
||||||
--ring: 222.2 84% 4.9%;
|
|
||||||
|
|
||||||
|
--border:240 5.9% 90%;
|
||||||
|
--input:240 5.9% 90%;
|
||||||
|
--ring:240 5.9% 10%;
|
||||||
--radius: 0.5rem;
|
--radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: 222.2 84% 4.9%;
|
--background:240 10% 3.9%;
|
||||||
--foreground: 210 40% 98%;
|
--foreground:0 0% 98%;
|
||||||
|
|
||||||
--muted: 217.2 32.6% 17.5%;
|
--card:240 10% 3.9%;
|
||||||
--muted-foreground: 215 20.2% 65.1%;
|
--card-foreground:0 0% 98%;
|
||||||
|
|
||||||
--popover: 222.2 84% 4.9%;
|
--popover:240 10% 3.9%;
|
||||||
--popover-foreground: 210 40% 98%;
|
--popover-foreground:0 0% 98%;
|
||||||
|
|
||||||
--card: 222.2 84% 4.9%;
|
--primary:0 0% 98%;
|
||||||
--card-foreground: 210 40% 98%;
|
--primary-foreground:240 5.9% 10%;
|
||||||
|
|
||||||
--border: 217.2 32.6% 17.5%;
|
--secondary:240 3.7% 15.9%;
|
||||||
--input: 217.2 32.6% 17.5%;
|
--secondary-foreground:0 0% 98%;
|
||||||
|
|
||||||
--primary: 210 40% 98%;
|
--muted:240 3.7% 15.9%;
|
||||||
--primary-foreground: 222.2 47.4% 11.2%;
|
--muted-foreground:240 5% 64.9%;
|
||||||
|
|
||||||
--secondary: 217.2 32.6% 17.5%;
|
--accent:240 3.7% 15.9%;
|
||||||
--secondary-foreground: 210 40% 98%;
|
--accent-foreground:0 0% 98%;
|
||||||
|
|
||||||
--accent: 217.2 32.6% 17.5%;
|
--destructive:0 62.8% 30.6%;
|
||||||
--accent-foreground: 210 40% 98%;
|
--destructive-foreground:0 0% 98%;
|
||||||
|
|
||||||
--destructive: 0 62.8% 30.6%;
|
--border:240 3.7% 15.9%;
|
||||||
--destructive-foreground: 210 40% 98%;
|
--input:240 3.7% 15.9%;
|
||||||
|
--ring:240 4.9% 83.9%;
|
||||||
--ring: 212.7 26.8% 83.9%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-border;
|
||||||
|
|
|
||||||
1470
pnpm-lock.yaml
1470
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user