Skip to content

Commit

Permalink
Merge branch 'radix-vue:dev' into docs/astro-guide
Browse files Browse the repository at this point in the history
  • Loading branch information
selemondev authored Oct 21, 2023
2 parents 49ccc6c + b2caaca commit 08c6749
Show file tree
Hide file tree
Showing 26 changed files with 2,145 additions and 174 deletions.
35 changes: 35 additions & 0 deletions apps/www/.vitepress/theme/components/CodeSandbox.vue
Original file line number Diff line number Diff line change
@@ -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>
7 changes: 7 additions & 0 deletions apps/www/.vitepress/theme/components/ComponentPreview.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script setup lang="ts">
import StyleSwitcher from './StyleSwitcher.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 { useConfigStore } from '@/stores/config'
import { cn } from '@/lib/utils'
Expand Down Expand Up @@ -39,6 +41,11 @@ const { style } = useConfigStore()
<TabsContent value="preview" class="relative rounded-md border">
<div class="flex items-center justify-between p-4">
<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
:class="cn('preview flex min-h-[350px] w-full justify-center p-6 lg:p-10', {
Expand Down
34 changes: 34 additions & 0 deletions apps/www/.vitepress/theme/components/Stackblitz.vue
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions apps/www/.vitepress/theme/components/Tooltip.vue
Original file line number Diff line number Diff line change
@@ -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>
41 changes: 22 additions & 19 deletions apps/www/.vitepress/theme/layout/MainLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,29 @@ watch(() => $route.path, (n) => {
</div>
</Button>

<div
v-for="link in links"
:key="link.name"
class="flex items-center space-x-1"
>
<a :href="link.href" target="_blank" class="text-foreground">
<component :is="link.icon" class="w-5 h-5" />
</a>
</div>
<div class="flex items-center gap-x-1">
<Button
v-for="link in links"
:key="link.name"
as="a"
:href="link.href" target="_blank"
:variant="'ghost'" :size="'icon'"
>
<component :is="link.icon" class="w-[20px] h-[20px]" />
</Button>

<button
class="flex items-center justify-center"
aria-label="Toggle dark mode"
@click="toggleDark()"
>
<component
:is="isDark ? RadixIconsSun : RadixIconsMoon"
class="w-5 h-5 text-foreground"
/>
</button>
<Button
class="flex items-center justify-center"
aria-label="Toggle dark mode"
:variant="'ghost'"
:size="'icon'" @click="toggleDark()"
>
<component
:is="isDark ? RadixIconsSun : RadixIconsMoon"
class="w-[20px] h-[20px] text-foreground"
/>
</Button>
</div>
</div>
</div>
</header>
Expand Down
212 changes: 212 additions & 0 deletions apps/www/.vitepress/theme/utils/codeeditor.ts
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit 08c6749

Please sign in to comment.