docs: add themePopover to MainLayout
This commit is contained in:
parent
efef57a2c1
commit
ad5b25d3bc
136
apps/www/.vitepress/theme/components/ThemePopover.vue
Normal file
136
apps/www/.vitepress/theme/components/ThemePopover.vue
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, watch } from 'vue'
|
||||||
|
import { Paintbrush } from 'lucide-vue-next'
|
||||||
|
import { useData } from 'vitepress'
|
||||||
|
import { allColors } from './theming/utils/data'
|
||||||
|
import { RADII, useConfigStore } from '@/stores/config'
|
||||||
|
import { colors } from '@/lib/registry'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { Label } from '@/lib/registry/new-york/ui/label'
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||||
|
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||||
|
import RadixIconsSun from '~icons/radix-icons/sun'
|
||||||
|
import RadixIconsMoon from '~icons/radix-icons/moon'
|
||||||
|
|
||||||
|
defineProps<{ title?: string }>()
|
||||||
|
|
||||||
|
const { theme, radius, setRadius, setTheme } = useConfigStore()
|
||||||
|
const { isDark } = useData()
|
||||||
|
|
||||||
|
// Whenever the component is mounted, update the document class list
|
||||||
|
onMounted(() => {
|
||||||
|
document.documentElement.style.setProperty('--radius', `${radius.value}rem`)
|
||||||
|
document.documentElement.classList.add(`theme-${theme.value}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Whenever the theme value changes, update the document class list
|
||||||
|
watch(theme, (theme) => {
|
||||||
|
document.documentElement.classList.remove(
|
||||||
|
...allColors.map(color => `theme-${color}`),
|
||||||
|
)
|
||||||
|
document.documentElement.classList.add(`theme-${theme}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Whenever the radius value changes, update the document style
|
||||||
|
watch(radius, (radius) => {
|
||||||
|
document.documentElement.style.setProperty('--radius', `${radius}rem`)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button variant="outline" class="h-9 rounded-[0.5rem]">
|
||||||
|
<Paintbrush class="w-4 h-4" />
|
||||||
|
<span v-if="title" class="ml-2">{{ title }}</span>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent :side-offset="8" align="end" class="w-96">
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="grid space-y-1">
|
||||||
|
<h1 class="text-md text-foreground font-semibold">
|
||||||
|
Customize
|
||||||
|
</h1>
|
||||||
|
<p class="text-xs text-muted-foreground">
|
||||||
|
Pick a style and color for your components.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="color" class="text-xs"> Color </Label>
|
||||||
|
<div class="grid grid-cols-3 gap-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
v-for="(color, index) in allColors"
|
||||||
|
:key="index"
|
||||||
|
variant="outline"
|
||||||
|
class="h-8 justify-start px-3"
|
||||||
|
:class="
|
||||||
|
color === theme
|
||||||
|
? 'border-foreground border-2'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="setTheme(color)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="h-5 w-5 rounded-full flex items-center justify-center"
|
||||||
|
:style="{ backgroundColor: colors[color][7].rgb }"
|
||||||
|
>
|
||||||
|
<RadixIconsCheck
|
||||||
|
v-if="color === theme"
|
||||||
|
class="h-3 w-3 text-white"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span class="ml-2 text-xs capitalize">
|
||||||
|
{{ color }}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="radius" class="text-xs"> Radius </Label>
|
||||||
|
<div class="grid grid-cols-5 gap-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
v-for="(r, index) in RADII"
|
||||||
|
:key="index"
|
||||||
|
variant="outline"
|
||||||
|
class="h-8 justify-center px-3"
|
||||||
|
:class="
|
||||||
|
r === radius
|
||||||
|
? 'border-foreground border-2'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="setRadius(r)"
|
||||||
|
>
|
||||||
|
<span class="text-xs">
|
||||||
|
{{ r }}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5 pt-6">
|
||||||
|
<Label for="theme" class="text-xs"> Theme </Label>
|
||||||
|
|
||||||
|
<div class="flex space-x-2 py-1.5">
|
||||||
|
<Button
|
||||||
|
class="h-8"
|
||||||
|
variant="outline"
|
||||||
|
:class="{ 'border-2 border-foreground': !isDark }"
|
||||||
|
@click="isDark = false"
|
||||||
|
>
|
||||||
|
<RadixIconsSun class="w-4 h-4 mr-2" />
|
||||||
|
<span class="text-xs">Light</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
class="h-8"
|
||||||
|
variant="outline"
|
||||||
|
:class="{ 'border-2 border-foreground': isDark }"
|
||||||
|
@click="isDark = true"
|
||||||
|
>
|
||||||
|
<RadixIconsMoon class="w-4 h-4 mr-2" />
|
||||||
|
<span class="text-xs">Dark</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</template>
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { ChevronDown, Minus, Plus, Send } from 'lucide-vue-next'
|
|
||||||
import { addDays, startOfToday } from 'date-fns'
|
import { addDays, startOfToday } from 'date-fns'
|
||||||
import ThemingLayout from './../../layout/ThemingLayout.vue'
|
import ThemingLayout from './../../layout/ThemingLayout.vue'
|
||||||
|
|
||||||
import Container from '@/examples/cards/components/Container.vue'
|
|
||||||
import CookieSettings from '@/examples/cards/components/CookieSettings.vue'
|
import CookieSettings from '@/examples/cards/components/CookieSettings.vue'
|
||||||
import CreateAccount from '@/examples/cards/components/CreateAccount.vue'
|
import CreateAccount from '@/examples/cards/components/CreateAccount.vue'
|
||||||
import DatePicker from '@/examples/cards/components/DatePicker.vue'
|
|
||||||
import GitHubCard from '@/examples/cards/components/GitHubCard.vue'
|
|
||||||
import Notifications from '@/examples/cards/components/Notifications.vue'
|
|
||||||
import PaymentMethod from '@/examples/cards/components/PaymentMethod.vue'
|
import PaymentMethod from '@/examples/cards/components/PaymentMethod.vue'
|
||||||
import ReportAnIssue from '@/examples/cards/components/ReportAnIssue.vue'
|
import ReportAnIssue from '@/examples/cards/components/ReportAnIssue.vue'
|
||||||
import ShareDocument from '@/examples/cards/components/ShareDocument.vue'
|
import ShareDocument from '@/examples/cards/components/ShareDocument.vue'
|
||||||
|
|
@ -21,19 +16,9 @@ import Metric from '@/lib/registry/new-york/example/Cards/Metric.vue'
|
||||||
import DataTable from '@/lib/registry/new-york/example/Cards/DataTable.vue'
|
import DataTable from '@/lib/registry/new-york/example/Cards/DataTable.vue'
|
||||||
import CardStats from '@/lib/registry/default/example/CardStats.vue'
|
import CardStats from '@/lib/registry/default/example/CardStats.vue'
|
||||||
|
|
||||||
import {
|
import { Card } from '@/lib/registry/new-york/ui/card'
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardFooter,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from '@/lib/registry/new-york/ui/card'
|
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
|
||||||
import { Calendar } from '@/lib/registry/new-york/ui/calendar'
|
import { Calendar } from '@/lib/registry/new-york/ui/calendar'
|
||||||
|
|
||||||
const goal = ref(350)
|
|
||||||
|
|
||||||
const range = ref({
|
const range = ref({
|
||||||
start: startOfToday(),
|
start: startOfToday(),
|
||||||
end: addDays(startOfToday(), 8),
|
end: addDays(startOfToday(), 8),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,36 @@ import { CreditCard } from 'lucide-vue-next'
|
||||||
import RiAppleFill from '~icons/ri/apple-fill'
|
import RiAppleFill from '~icons/ri/apple-fill'
|
||||||
import RiPaypalFill from '~icons/ri/paypal-fill'
|
import RiPaypalFill from '~icons/ri/paypal-fill'
|
||||||
|
|
||||||
|
type Color =
|
||||||
|
| 'zinc'
|
||||||
|
| 'slate'
|
||||||
|
| 'stone'
|
||||||
|
| 'gray'
|
||||||
|
| 'neutral'
|
||||||
|
| 'red'
|
||||||
|
| 'rose'
|
||||||
|
| 'orange'
|
||||||
|
| 'green'
|
||||||
|
| 'blue'
|
||||||
|
| 'yellow'
|
||||||
|
| 'violet'
|
||||||
|
|
||||||
|
// Create an array of color values
|
||||||
|
export const allColors: Color[] = [
|
||||||
|
'zinc',
|
||||||
|
'rose',
|
||||||
|
'blue',
|
||||||
|
'green',
|
||||||
|
'orange',
|
||||||
|
'red',
|
||||||
|
'slate',
|
||||||
|
'stone',
|
||||||
|
'gray',
|
||||||
|
'neutral',
|
||||||
|
'yellow',
|
||||||
|
'violet',
|
||||||
|
]
|
||||||
|
|
||||||
interface Payment {
|
interface Payment {
|
||||||
status: string
|
status: string
|
||||||
email: string
|
email: string
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import Logo from '../components/Logo.vue'
|
||||||
import MobileNav from '../components/MobileNav.vue'
|
import MobileNav from '../components/MobileNav.vue'
|
||||||
|
|
||||||
import Kbd from '../components/Kbd.vue'
|
import Kbd from '../components/Kbd.vue'
|
||||||
|
import ThemePopover from '../components/ThemePopover.vue'
|
||||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/lib/registry/default/ui/command'
|
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/lib/registry/default/ui/command'
|
||||||
|
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
|
@ -105,10 +106,10 @@ watch(() => $route.path, (n) => {
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" flex items-center justify-end space-x-4 ">
|
<div class=" flex items-center justify-end space-x-2 ">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="w-72 h-8 px-3 hidden lg:flex lg:justify-between lg:items-center"
|
class="w-72 h-9 px-3 hidden lg:flex lg:justify-between lg:items-center"
|
||||||
@click="isOpen = true"
|
@click="isOpen = true"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
|
@ -119,6 +120,7 @@ watch(() => $route.path, (n) => {
|
||||||
<Kbd> <span>⌘</span>K </Kbd>
|
<Kbd> <span>⌘</span>K </Kbd>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
<ThemePopover />
|
||||||
|
|
||||||
<div class="flex items-center gap-x-1">
|
<div class="flex items-center gap-x-1">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -1,73 +1,19 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, watch } from 'vue'
|
import { onMounted, watch } from 'vue'
|
||||||
import { Paintbrush } from 'lucide-vue-next'
|
|
||||||
import { useData } from 'vitepress'
|
|
||||||
import PageHeader from '../components/PageHeader.vue'
|
import PageHeader from '../components/PageHeader.vue'
|
||||||
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
||||||
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
||||||
import CustomizerCode from '../components/CustomizerCode.vue'
|
import CustomizerCode from '../components/CustomizerCode.vue'
|
||||||
import { RADII, useConfigStore } from '@/stores/config'
|
import ThemePopover from '../components/ThemePopover.vue'
|
||||||
|
import { allColors } from '../components/theming/utils/data'
|
||||||
|
import { useConfigStore } from '@/stores/config'
|
||||||
import { colors } from '@/lib/registry'
|
import { colors } from '@/lib/registry'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
import { Label } from '@/lib/registry/new-york/ui/label'
|
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/lib/registry/new-york/ui/dialog'
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/lib/registry/new-york/ui/dialog'
|
||||||
import RadixIconsCheck from '~icons/radix-icons/check'
|
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||||
import RadixIconsSun from '~icons/radix-icons/sun'
|
|
||||||
import RadixIconsMoon from '~icons/radix-icons/moon'
|
|
||||||
|
|
||||||
type Color =
|
const { theme, setTheme } = useConfigStore()
|
||||||
| 'zinc'
|
|
||||||
| 'slate'
|
|
||||||
| 'stone'
|
|
||||||
| 'gray'
|
|
||||||
| 'neutral'
|
|
||||||
| 'red'
|
|
||||||
| 'rose'
|
|
||||||
| 'orange'
|
|
||||||
| 'green'
|
|
||||||
| 'blue'
|
|
||||||
| 'yellow'
|
|
||||||
| 'violet'
|
|
||||||
|
|
||||||
// Create an array of color values
|
|
||||||
const allColors: Color[] = [
|
|
||||||
'zinc',
|
|
||||||
'rose',
|
|
||||||
'blue',
|
|
||||||
'green',
|
|
||||||
'orange',
|
|
||||||
'red',
|
|
||||||
'slate',
|
|
||||||
'stone',
|
|
||||||
'gray',
|
|
||||||
'neutral',
|
|
||||||
'yellow',
|
|
||||||
'violet',
|
|
||||||
]
|
|
||||||
|
|
||||||
const { theme, radius, setRadius, setTheme } = useConfigStore()
|
|
||||||
const { isDark } = useData()
|
|
||||||
|
|
||||||
// Whenever the component is mounted, update the document class list
|
|
||||||
onMounted(() => {
|
|
||||||
document.documentElement.style.setProperty('--radius', `${radius.value}rem`)
|
|
||||||
document.documentElement.classList.add(`theme-${theme.value}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Whenever the theme value changes, update the document class list
|
|
||||||
watch(theme, (theme) => {
|
|
||||||
document.documentElement.classList.remove(
|
|
||||||
...allColors.map(color => `theme-${color}`),
|
|
||||||
)
|
|
||||||
document.documentElement.classList.add(`theme-${theme}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Whenever the radius value changes, update the document style
|
|
||||||
watch(radius, (radius) => {
|
|
||||||
document.documentElement.style.setProperty('--radius', `${radius}rem`)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -124,101 +70,7 @@ watch(radius, (radius) => {
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
<Popover>
|
<ThemePopover title="Customize" />
|
||||||
<PopoverTrigger as-child>
|
|
||||||
<Button variant="outline" class="h-9 rounded-[0.5rem]">
|
|
||||||
<Paintbrush class="w-4 h-4 mr-2" />
|
|
||||||
Customize
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent :side-offset="8" align="end" class="w-96">
|
|
||||||
<div class="p-4">
|
|
||||||
<div class="grid space-y-1">
|
|
||||||
<h1 class="text-md text-foreground font-semibold">
|
|
||||||
Customize
|
|
||||||
</h1>
|
|
||||||
<p class="text-xs text-muted-foreground">
|
|
||||||
Pick a style and color for your components.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="color" class="text-xs"> Color </Label>
|
|
||||||
<div class="grid grid-cols-3 gap-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
v-for="(color, index) in allColors"
|
|
||||||
:key="index"
|
|
||||||
variant="outline"
|
|
||||||
class="h-8 justify-start px-3"
|
|
||||||
:class="
|
|
||||||
color === theme
|
|
||||||
? 'border-foreground border-2'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="setTheme(color)"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="h-5 w-5 rounded-full flex items-center justify-center"
|
|
||||||
:style="{ backgroundColor: colors[color][7].rgb }"
|
|
||||||
>
|
|
||||||
<RadixIconsCheck
|
|
||||||
v-if="color === theme"
|
|
||||||
class="h-3 w-3 text-white"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span class="ml-2 text-xs capitalize">
|
|
||||||
{{ color }}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="radius" class="text-xs"> Radius </Label>
|
|
||||||
<div class="grid grid-cols-5 gap-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
v-for="(r, index) in RADII"
|
|
||||||
:key="index"
|
|
||||||
variant="outline"
|
|
||||||
class="h-8 justify-center px-3"
|
|
||||||
:class="
|
|
||||||
r === radius
|
|
||||||
? 'border-foreground border-2'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="setRadius(r)"
|
|
||||||
>
|
|
||||||
<span class="text-xs">
|
|
||||||
{{ r }}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-1.5 pt-6">
|
|
||||||
<Label for="theme" class="text-xs"> Theme </Label>
|
|
||||||
|
|
||||||
<div class="flex space-x-2 py-1.5">
|
|
||||||
<Button
|
|
||||||
class="h-8"
|
|
||||||
variant="outline"
|
|
||||||
:class="{ 'border-2 border-foreground': !isDark }"
|
|
||||||
@click="isDark = false"
|
|
||||||
>
|
|
||||||
<RadixIconsSun class="w-4 h-4 mr-2" />
|
|
||||||
<span class="text-xs">Light</span>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
class="h-8"
|
|
||||||
variant="outline"
|
|
||||||
:class="{ 'border-2 border-foreground': isDark }"
|
|
||||||
@click="isDark = true"
|
|
||||||
>
|
|
||||||
<RadixIconsMoon class="w-4 h-4 mr-2" />
|
|
||||||
<span class="text-xs">Dark</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger as-child>
|
<DialogTrigger as-child>
|
||||||
<Button class="h-9 ml-2 rounded-[0.5rem]">
|
<Button class="h-9 ml-2 rounded-[0.5rem]">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user