feat: add style switcher

This commit is contained in:
zernonia 2023-09-08 14:51:54 +08:00
parent 22e548f452
commit b37ba515dd
6 changed files with 74 additions and 14 deletions

View File

@ -0,0 +1,20 @@
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import Spinner from './Spinner.vue'
import { useConfigStore } from '@/stores/config'
const props = defineProps<{
name: string
}>()
const { style } = useConfigStore()
const Component = defineAsyncComponent({
loadingComponent: Spinner,
loader: () => import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue`),
timeout: 5000,
})
</script>
<template>
<Component :is="Component" />
</template>

View File

@ -1,7 +1,8 @@
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import Spinner from './Spinner.vue'
import StyleSwitcher from './StyleSwitcher.vue'
import ComponentLoader from './ComponentLoader.vue'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
import { useConfigStore } from '@/stores/config'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<{
@ -11,11 +12,7 @@ const props = withDefaults(defineProps<{
sfcTsHtml?: string
}>(), { align: 'center' })
const Component = defineAsyncComponent({
loadingComponent: Spinner,
loader: () => import(`../../../src/lib/registry/default/example/${props.name}.vue`),
timeout: 5000,
})
const { style } = useConfigStore()
</script>
<template>
@ -40,6 +37,9 @@ const Component = defineAsyncComponent({
</TabsList>
</div>
<TabsContent value="preview" class="relative rounded-md border">
<div className="flex items-center justify-between p-4">
<StyleSwitcher />
</div>
<div
:class="cn('preview flex min-h-[350px] w-full justify-center p-10', {
'items-center': align === 'center',
@ -47,7 +47,7 @@ const Component = defineAsyncComponent({
'items-end': align === 'end',
})"
>
<Component :is="Component" />
<ComponentLoader :key="style" :name="name" />
</div>
</TabsContent>
<TabsContent value="code">

View File

@ -0,0 +1,33 @@
<script setup lang="ts">
import { type SelectTriggerProps } from 'radix-vue'
import { useConfigStore } from '@/stores/config'
import { cn } from '@/lib/utils'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/lib/registry/new-york/ui/select'
import { styles } from '@/lib/registry/styles'
const props = defineProps<SelectTriggerProps & { class?: string }>()
const { config } = useConfigStore()
</script>
<template>
<Select v-model="config.style">
<SelectTrigger :class="cn('h-7 w-[145px] text-xs [&_svg]:h-4 [&_svg]:w-4', props.class)">
<span class="text-muted-foreground">Style: </span>
<SelectValue placeholder="Select style">
{{ styles.find(s => s.name === config.style)?.label }}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem v-for="style in styles" :key="style.name" :value="style.name" class="text-xs">
{{ style.label }}
</SelectItem>
</SelectContent>
</Select>
</template>

View File

@ -0,0 +1,4 @@
import { useStorage } from '@vueuse/core'
import { styles } from '../../../src/lib/registry/styles'
export const useStyle = () => useStorage('selected-style', styles[0].name)

View File

@ -3,10 +3,10 @@ export const styles = [
name: 'default',
label: 'Default',
},
// {
// name: 'new-york',
// label: 'New York',
// },
{
name: 'new-york',
label: 'New York',
},
] as const
export type Style = (typeof styles)[number]

View File

@ -1,10 +1,12 @@
import { computed } from 'vue'
import { useSessionStorage } from '@vueuse/core'
import type { Theme } from './../lib/registry/themes'
import { styles } from '@/lib/registry/styles'
interface Config {
theme: Theme['name']
radius: number
style: string
}
export const RADII = [0, 0.25, 0.5, 0.75, 1]
@ -13,13 +15,14 @@ export function useConfigStore() {
const config = useSessionStorage<Config>('config', {
theme: 'zinc',
radius: 0.5,
style: styles[0].name,
})
const themeClass = computed(() => `theme-${config.value.theme}`)
const theme = computed(() => config.value.theme)
const radius = computed(() => config.value.radius)
const style = computed(() => config.value.style)
function setTheme(themeName: Theme['name']) {
config.value.theme = themeName
@ -29,5 +32,5 @@ export function useConfigStore() {
config.value.radius = newRadius
}
return { config, theme, setTheme, radius, setRadius, themeClass }
return { config, theme, setTheme, radius, setRadius, themeClass, style }
}