feat: add style switcher
This commit is contained in:
parent
22e548f452
commit
b37ba515dd
20
apps/www/.vitepress/theme/components/ComponentLoader.vue
Normal file
20
apps/www/.vitepress/theme/components/ComponentLoader.vue
Normal 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>
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineAsyncComponent } from 'vue'
|
import StyleSwitcher from './StyleSwitcher.vue'
|
||||||
import Spinner from './Spinner.vue'
|
import ComponentLoader from './ComponentLoader.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 { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
|
@ -11,11 +12,7 @@ const props = withDefaults(defineProps<{
|
||||||
sfcTsHtml?: string
|
sfcTsHtml?: string
|
||||||
}>(), { align: 'center' })
|
}>(), { align: 'center' })
|
||||||
|
|
||||||
const Component = defineAsyncComponent({
|
const { style } = useConfigStore()
|
||||||
loadingComponent: Spinner,
|
|
||||||
loader: () => import(`../../../src/lib/registry/default/example/${props.name}.vue`),
|
|
||||||
timeout: 5000,
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -40,6 +37,9 @@ const Component = defineAsyncComponent({
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</div>
|
</div>
|
||||||
<TabsContent value="preview" class="relative rounded-md border">
|
<TabsContent value="preview" class="relative rounded-md border">
|
||||||
|
<div className="flex items-center justify-between p-4">
|
||||||
|
<StyleSwitcher />
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
:class="cn('preview flex min-h-[350px] w-full justify-center p-10', {
|
:class="cn('preview flex min-h-[350px] w-full justify-center p-10', {
|
||||||
'items-center': align === 'center',
|
'items-center': align === 'center',
|
||||||
|
|
@ -47,7 +47,7 @@ const Component = defineAsyncComponent({
|
||||||
'items-end': align === 'end',
|
'items-end': align === 'end',
|
||||||
})"
|
})"
|
||||||
>
|
>
|
||||||
<Component :is="Component" />
|
<ComponentLoader :key="style" :name="name" />
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="code">
|
<TabsContent value="code">
|
||||||
|
|
|
||||||
33
apps/www/.vitepress/theme/components/StyleSwitcher.vue
Normal file
33
apps/www/.vitepress/theme/components/StyleSwitcher.vue
Normal 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>
|
||||||
4
apps/www/.vitepress/theme/composables/style.ts
Normal file
4
apps/www/.vitepress/theme/composables/style.ts
Normal 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)
|
||||||
|
|
@ -3,10 +3,10 @@ export const styles = [
|
||||||
name: 'default',
|
name: 'default',
|
||||||
label: 'Default',
|
label: 'Default',
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// name: 'new-york',
|
name: 'new-york',
|
||||||
// label: 'New York',
|
label: 'New York',
|
||||||
// },
|
},
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export type Style = (typeof styles)[number]
|
export type Style = (typeof styles)[number]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useSessionStorage } from '@vueuse/core'
|
import { useSessionStorage } from '@vueuse/core'
|
||||||
import type { Theme } from './../lib/registry/themes'
|
import type { Theme } from './../lib/registry/themes'
|
||||||
|
import { styles } from '@/lib/registry/styles'
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
theme: Theme['name']
|
theme: Theme['name']
|
||||||
radius: number
|
radius: number
|
||||||
|
style: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RADII = [0, 0.25, 0.5, 0.75, 1]
|
export const RADII = [0, 0.25, 0.5, 0.75, 1]
|
||||||
|
|
@ -13,13 +15,14 @@ export function useConfigStore() {
|
||||||
const config = useSessionStorage<Config>('config', {
|
const config = useSessionStorage<Config>('config', {
|
||||||
theme: 'zinc',
|
theme: 'zinc',
|
||||||
radius: 0.5,
|
radius: 0.5,
|
||||||
|
style: styles[0].name,
|
||||||
})
|
})
|
||||||
|
|
||||||
const themeClass = computed(() => `theme-${config.value.theme}`)
|
const themeClass = computed(() => `theme-${config.value.theme}`)
|
||||||
|
|
||||||
const theme = computed(() => config.value.theme)
|
const theme = computed(() => config.value.theme)
|
||||||
|
|
||||||
const radius = computed(() => config.value.radius)
|
const radius = computed(() => config.value.radius)
|
||||||
|
const style = computed(() => config.value.style)
|
||||||
|
|
||||||
function setTheme(themeName: Theme['name']) {
|
function setTheme(themeName: Theme['name']) {
|
||||||
config.value.theme = themeName
|
config.value.theme = themeName
|
||||||
|
|
@ -29,5 +32,5 @@ export function useConfigStore() {
|
||||||
config.value.radius = newRadius
|
config.value.radius = newRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
return { config, theme, setTheme, radius, setRadius, themeClass }
|
return { config, theme, setTheme, radius, setRadius, themeClass, style }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user