mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-17 13:38:07 +01:00
docs: improve with examples
This commit is contained in:
46
docs/components/ColorPicker.vue
Normal file
46
docs/components/ColorPicker.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<div class="grid grid-cols-5 gap-px">
|
||||
<ColorPickerButton v-for="color in primaryColors" :key="color.value" :color="color" :selected="primary" @select="primary = color" />
|
||||
</div>
|
||||
|
||||
<hr class="border-gray-200 dark:border-gray-800 my-2">
|
||||
|
||||
<div class="grid grid-cols-5 gap-px">
|
||||
<ColorPickerButton v-for="color in grayColors" :key="color.value" :color="color" :selected="gray" @select="gray = color" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import colors from '#tailwind-config/theme/colors'
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
// Computed
|
||||
|
||||
const primaryColors = computed(() => useWithout(appConfig.ui.colors, 'primary').map(color => ({ value: color, text: color, hex: colors[color][colorMode.value === 'dark' ? 400 : 500] })))
|
||||
const primary = computed({
|
||||
get () {
|
||||
return primaryColors.value.find(option => option.value === appConfig.ui.primary)
|
||||
},
|
||||
set (option) {
|
||||
appConfig.ui.primary = option.value
|
||||
|
||||
window.localStorage.setItem('nuxt-ui-primary', appConfig.ui.primary)
|
||||
}
|
||||
})
|
||||
|
||||
const grayColors = computed(() => ['slate', 'cool', 'zinc', 'neutral', 'stone'].map(color => ({ value: color, text: color, hex: colors[color][colorMode.value === 'dark' ? 400 : 500] })))
|
||||
const gray = computed({
|
||||
get () {
|
||||
return grayColors.value.find(option => option.value === appConfig.ui.gray)
|
||||
},
|
||||
set (option) {
|
||||
appConfig.ui.gray = option.value
|
||||
|
||||
window.localStorage.setItem('nuxt-ui-gray', appConfig.ui.gray)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
25
docs/components/ColorPickerButton.vue
Normal file
25
docs/components/ColorPickerButton.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<UTooltip :text="color.value" class="capitalize" :open-delay="500">
|
||||
<UButton
|
||||
color="gray"
|
||||
square
|
||||
:ui="{
|
||||
color: {
|
||||
gray: {
|
||||
solid: 'bg-gray-100 dark:bg-gray-800',
|
||||
ghost: 'hover:bg-gray-50 dark:hover:bg-gray-800/50'
|
||||
}
|
||||
}
|
||||
}"
|
||||
:variant="color.value === selected.value ? 'solid' : 'ghost'"
|
||||
@click.stop.prevent="$emit('select')"
|
||||
>
|
||||
<span class="inline-block w-3 h-3 rounded-full" :style="{ backgroundColor: color.hex }" />
|
||||
</UButton>
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ color: { value: string, hex: string }, selected: { value: string} }>()
|
||||
defineEmits(['select'])
|
||||
</script>
|
||||
76
docs/components/DatePicker.vue
Normal file
76
docs/components/DatePicker.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { DatePicker as VCalendarDatePicker } from 'v-calendar'
|
||||
import 'v-calendar/dist/style.css'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:model-value', 'close'])
|
||||
|
||||
const colorMode = useColorMode()
|
||||
|
||||
const isDark = computed(() => colorMode.value === 'dark')
|
||||
|
||||
const date = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
emit('update:model-value', value)
|
||||
emit('close')
|
||||
}
|
||||
})
|
||||
|
||||
const attrs = [{
|
||||
key: 'today',
|
||||
highlight: {
|
||||
color: 'blue',
|
||||
fillMode: 'outline',
|
||||
class: '!bg-gray-100 dark:!bg-gray-800'
|
||||
},
|
||||
dates: new Date()
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCalendarDatePicker
|
||||
v-model="date"
|
||||
transparent
|
||||
borderless
|
||||
:attributes="attrs"
|
||||
:is-dark="isDark"
|
||||
title-position="left"
|
||||
trim-weeks
|
||||
:first-day-of-week="2"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--vc-gray-50: rgb(var(--color-gray-50));
|
||||
--vc-gray-100: rgb(var(--color-gray-100));
|
||||
--vc-gray-200: rgb(var(--color-gray-200));
|
||||
--vc-gray-300: rgb(var(--color-gray-300));
|
||||
--vc-gray-400: rgb(var(--color-gray-400));
|
||||
--vc-gray-500: rgb(var(--color-gray-500));
|
||||
--vc-gray-600: rgb(var(--color-gray-600));
|
||||
--vc-gray-700: rgb(var(--color-gray-700));
|
||||
--vc-gray-800: rgb(var(--color-gray-800));
|
||||
--vc-gray-900: rgb(var(--color-gray-900));
|
||||
}
|
||||
|
||||
.vc-blue {
|
||||
--vc-accent-50: rgb(var(--color-primary-50));
|
||||
--vc-accent-100: rgb(var(--color-primary-100));
|
||||
--vc-accent-200: rgb(var(--color-primary-200));
|
||||
--vc-accent-300: rgb(var(--color-primary-300));
|
||||
--vc-accent-400: rgb(var(--color-primary-400));
|
||||
--vc-accent-500: rgb(var(--color-primary-500));
|
||||
--vc-accent-600: rgb(var(--color-primary-600));
|
||||
--vc-accent-700: rgb(var(--color-primary-700));
|
||||
--vc-accent-800: rgb(var(--color-primary-800));
|
||||
--vc-accent-900: rgb(var(--color-primary-900));
|
||||
}
|
||||
</style>
|
||||
@@ -1,86 +1,16 @@
|
||||
<template>
|
||||
<header class="sticky top-0 z-50 w-full backdrop-blur flex-none border-b border-gray-900/10 dark:border-gray-50/[0.06] bg-white/75 dark:bg-gray-900/75">
|
||||
<header class="sticky top-0 z-50 w-full backdrop-blur flex-none border-b border-gray-200 dark:border-gray-800 bg-white/75 dark:bg-gray-900/75">
|
||||
<UContainer>
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<div class="flex items-center gap-3">
|
||||
<NuxtLink to="/getting-started" class="flex items-end gap-1.5 font-bold text-xl text-gray-900 dark:text-white">
|
||||
<Logo class="w-8 h-8 text-primary-500 dark:text-primary-400" />
|
||||
|
||||
NuxtLabs<span class="text-primary-500 dark:text-primary-400">UI</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center -mr-1.5 gap-1.5">
|
||||
<div class="hidden lg:block">
|
||||
<ThemeSelect />
|
||||
</div>
|
||||
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
class="lg:hidden"
|
||||
icon="i-heroicons-magnifying-glass-20-solid"
|
||||
@click="openDocsSearch"
|
||||
/>
|
||||
|
||||
<ClientOnly>
|
||||
<UButton
|
||||
:icon="isDark ? 'i-heroicons-moon' : 'i-heroicons-sun'"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
aria-label="Theme"
|
||||
@click="isDark = !isDark"
|
||||
/>
|
||||
|
||||
<template #fallback>
|
||||
<div class="w-8 h-8" />
|
||||
</template>
|
||||
</ClientOnly>
|
||||
|
||||
<UButton
|
||||
to="https://github.com/nuxtlabs/ui"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-simple-icons-github"
|
||||
/>
|
||||
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
class="lg:hidden"
|
||||
icon="i-heroicons-bars-3-20-solid"
|
||||
@click="isDialogOpen = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<HeaderLinks v-model="isDialogOpen" :links="links" />
|
||||
</UContainer>
|
||||
|
||||
<TransitionRoot :show="isDialogOpen" as="template">
|
||||
<Dialog as="div" @close="isDialogOpen = false">
|
||||
<DialogPanel class="fixed inset-0 z-50 overflow-y-auto bg-white dark:bg-gray-900 lg:hidden">
|
||||
<div class="px-4 sm:px-6 sticky top-0 border-b border-gray-900/10 dark:border-gray-50/[0.06] bg-white/75 dark:bg-gray-900/75 backdrop-blur z-10">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<div class="flex items-center gap-3">
|
||||
<NuxtLink to="/getting-started" class="flex items-end gap-1.5 font-bold text-xl text-gray-900 dark:text-white">
|
||||
<Logo class="w-8 h-8 text-primary-500 dark:text-primary-400" />
|
||||
NuxtLabs<span class="text-primary-500 dark:text-primary-400">UI</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="flex -mr-1.5">
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-heroicons-x-mark-20-solid"
|
||||
@click="isDialogOpen = false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 sm:px-6 sticky top-0 border-b border-gray-200 dark:border-gray-800 bg-white/75 dark:bg-gray-900/75 backdrop-blur z-10">
|
||||
<HeaderLinks v-model="isDialogOpen" :links="links" />
|
||||
</div>
|
||||
<div class="px-4 sm:px-6 py-4 sm:py-6">
|
||||
<ThemeSelect class="mb-4 sm:mb-6 w-full" />
|
||||
|
||||
<DocsAsideLinks @click="isDialogOpen = false" />
|
||||
</div>
|
||||
</DialogPanel>
|
||||
@@ -92,25 +22,11 @@
|
||||
<script setup lang="ts">
|
||||
import { Dialog, DialogPanel, TransitionRoot } from '@headlessui/vue'
|
||||
|
||||
const { isSearchModalOpen } = useDocs()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
const isDialogOpen = ref(false)
|
||||
|
||||
const isDark = computed({
|
||||
get () {
|
||||
return colorMode.value === 'dark'
|
||||
},
|
||||
set () {
|
||||
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||
}
|
||||
})
|
||||
|
||||
function openDocsSearch () {
|
||||
isDialogOpen.value = false
|
||||
|
||||
setTimeout(() => {
|
||||
isSearchModalOpen.value = true
|
||||
}, 100)
|
||||
}
|
||||
const links = [
|
||||
{ label: 'Documentation', to: '/getting-started' },
|
||||
{ label: 'Components', to: '/elements/avatar' },
|
||||
{ label: 'Examples', to: '/examples' }
|
||||
]
|
||||
</script>
|
||||
|
||||
64
docs/components/HeaderLinks.vue
Normal file
64
docs/components/HeaderLinks.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-between gap-3 h-16">
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<NuxtLink to="/getting-started" class="flex items-end gap-1.5 font-bold text-xl text-gray-900 dark:text-white">
|
||||
<Logo class="w-8 h-8 text-primary-500 dark:text-primary-400" />
|
||||
|
||||
<span class="hidden sm:block">NuxtLabs</span><span class="sm:text-primary-500 dark:sm:text-primary-400">UI</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end flex-1 -mr-1.5 gap-3">
|
||||
<DocsSearchButton class="ml-1.5 flex-1 lg:flex-none lg:w-48" />
|
||||
|
||||
<div class="flex items-center lg:gap-1.5">
|
||||
<UPopover>
|
||||
<template #default="{ open }">
|
||||
<UButton color="gray" variant="ghost" square :class="[open && 'bg-gray-50 dark:bg-gray-800']">
|
||||
<UIcon name="i-heroicons-swatch-20-solid" class="w-5 h-5 text-primary-500 dark:text-primary-400" />
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
<template #panel>
|
||||
<ColorPicker />
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
<ColorModeButton />
|
||||
|
||||
<UButton
|
||||
to="https://twitter.com/nuxtlabs"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-simple-icons-twitter"
|
||||
/>
|
||||
|
||||
<UButton
|
||||
to="https://github.com/nuxtlabs/ui"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-simple-icons-github"
|
||||
/>
|
||||
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
class="lg:hidden"
|
||||
:icon="isDialogOpen ? 'i-heroicons-x-mark-20-solid' : 'i-heroicons-bars-3-20-solid'"
|
||||
@click="isDialogOpen = !isDialogOpen"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ modelValue: boolean, links: { to: string, label: string }[] }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const isDialogOpen = useVModel(props, 'modelValue', emit)
|
||||
</script>
|
||||
@@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<div class="inline-flex shadow-sm rounded-md">
|
||||
<USelectMenu
|
||||
v-model="primary"
|
||||
name="primary"
|
||||
class="!rounded-r-none !shadow-none focus:z-[1]"
|
||||
color="gray"
|
||||
:ui="{ width: 'w-[194px]' }"
|
||||
:popper="{ placement: 'bottom-start' }"
|
||||
:options="primaryOptions"
|
||||
>
|
||||
<template #label>
|
||||
<span class="flex-shrink-0 h-3 w-3 rounded-full" :style="{ backgroundColor: `${primary.hex}`}" />
|
||||
|
||||
{{ primary.text }}
|
||||
</template>
|
||||
|
||||
<template #option="{ option }">
|
||||
<span class="flex-shrink-0 h-3 w-3 rounded-full" :style="{ backgroundColor: `${option.hex}`}" />
|
||||
|
||||
{{ option.text }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
|
||||
<USelectMenu
|
||||
v-model="gray"
|
||||
name="gray"
|
||||
class="!rounded-l-none !shadow-none"
|
||||
color="gray"
|
||||
:ui="{ width: 'w-[194px]', wrapper: '-ml-px' }"
|
||||
:popper="{ placement: 'bottom-end' }"
|
||||
:options="grayOptions"
|
||||
>
|
||||
<template #label>
|
||||
<span class="flex-shrink-0 h-3 w-3 rounded-full" :style="{ backgroundColor: `${gray.hex}`}" />
|
||||
|
||||
{{ gray.text }}
|
||||
</template>
|
||||
|
||||
<template #option="{ option }">
|
||||
<span class="flex-shrink-0 h-3 w-3 rounded-full" :style="{ backgroundColor: `${option.hex}`}" />
|
||||
|
||||
{{ option.text }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import colors from '#tailwind-config/theme/colors'
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
const primaryCookie = useCookie('primary', { path: '/', default: () => appConfig.ui.primary })
|
||||
const grayCookie = useCookie('gray', { path: '/', default: () => appConfig.ui.gray })
|
||||
|
||||
watch(primaryCookie, (primary) => {
|
||||
appConfig.ui.primary = primary
|
||||
}, { immediate: true })
|
||||
|
||||
watch(grayCookie, (gray) => {
|
||||
appConfig.ui.gray = gray
|
||||
}, { immediate: true })
|
||||
|
||||
// Computed
|
||||
|
||||
const primaryOptions = computed(() => useWithout(appConfig.ui.colors, 'primary').map(color => ({ value: color, text: color, hex: colors[color][colorMode.value === 'dark' ? 400 : 500] })))
|
||||
const primary = computed({
|
||||
get () {
|
||||
return primaryOptions.value.find(option => option.value === primaryCookie.value) || primaryOptions.value.find(option => option.value === 'green')
|
||||
},
|
||||
set (option) {
|
||||
primaryCookie.value = option.value
|
||||
}
|
||||
})
|
||||
|
||||
const grayOptions = computed(() => ['slate', 'cool', 'zinc', 'neutral', 'stone'].map(color => ({ value: color, text: color, hex: colors[color][colorMode.value === 'dark' ? 400 : 500] })))
|
||||
const gray = computed({
|
||||
get () {
|
||||
return grayOptions.value.find(option => option.value === grayCookie.value) || grayOptions.value.find(option => option.value === 'cool')
|
||||
},
|
||||
set (option) {
|
||||
grayCookie.value = option.value
|
||||
}
|
||||
})
|
||||
|
||||
// Hack for SSG
|
||||
const hexToRgb = (hex) => {
|
||||
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
||||
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
|
||||
hex = hex.replace(shorthandRegex, function (_, r, g, b) {
|
||||
return r + r + g + g + b + b
|
||||
})
|
||||
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
return result
|
||||
? `${parseInt(result[1], 16)} ${parseInt(result[2], 16)} ${parseInt(result[3], 16)}`
|
||||
: null
|
||||
}
|
||||
const root = computed(() => {
|
||||
return `:root {
|
||||
${Object.entries(colors[primary.value.value] || colors.green).map(([key, value]) => `--color-primary-${key}: ${hexToRgb(value)};`).join('\n')}
|
||||
${Object.entries(colors[gray.value.value] || colors.cool).map(([key, value]) => `--color-gray-${key}: ${hexToRgb(value)};`).join('\n')}
|
||||
}`
|
||||
})
|
||||
if (process.client) {
|
||||
watch(root, () => {
|
||||
window.localStorage.setItem('nuxt-ui-root', root.value)
|
||||
}, { immediate: true })
|
||||
}
|
||||
if (process.server) {
|
||||
useHead({
|
||||
script: [
|
||||
{
|
||||
innerHTML: `
|
||||
if (localStorage.getItem('nuxt-ui-root')) {
|
||||
document.querySelector('style#nuxt-ui-colors').innerHTML = localStorage.getItem('nuxt-ui-root')
|
||||
}`.replace(/\s+/g, ' '),
|
||||
type: 'text/javascript',
|
||||
tagPriority: -1
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
28
docs/components/content/ColorModeButton.vue
Normal file
28
docs/components/content/ColorModeButton.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<UButton
|
||||
:icon="isDark ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
aria-label="Theme"
|
||||
@click="isDark = !isDark"
|
||||
/>
|
||||
|
||||
<template #fallback>
|
||||
<div class="w-8 h-8" />
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const colorMode = useColorMode()
|
||||
|
||||
const isDark = computed({
|
||||
get () {
|
||||
return colorMode.value === 'dark'
|
||||
},
|
||||
set () {
|
||||
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
16
docs/components/content/examples/DatePickerExample.vue
Normal file
16
docs/components/content/examples/DatePickerExample.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<script setup>
|
||||
const date = ref(new Date())
|
||||
|
||||
const label = computed(() => date.value.toLocaleDateString('en-us', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric' })
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<UButton icon="i-heroicons-calendar-days-20-solid" :label="label" />
|
||||
|
||||
<template #panel="{ close }">
|
||||
<DatePicker v-model="date" @close="close" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
15
docs/components/content/prose/ProseH4.vue
Normal file
15
docs/components/content/prose/ProseH4.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{ id: string }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3 :id="id" class="scroll-mt-[145px] lg:scroll-mt-[96px]">
|
||||
<NuxtLink :href="`#${id}`" class="group">
|
||||
<div class="-ml-6 pr-2 py-2 inline-flex opacity-0 group-hover:opacity-100 transition-opacity absolute">
|
||||
<UIcon name="i-heroicons-hashtag-20-solid" class="w-4 h-4 text-primary-500 dark:text-primary-400" />
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
</NuxtLink>
|
||||
</h3>
|
||||
</template>
|
||||
@@ -1,13 +1,22 @@
|
||||
<script setup>
|
||||
const links = [{
|
||||
label: 'Introduction',
|
||||
to: '/getting-started'
|
||||
}, {
|
||||
label: 'Installation',
|
||||
to: '/getting-started/installation'
|
||||
}, {
|
||||
label: 'Vertical Navigation',
|
||||
to: '/navigation/vertical-navigation'
|
||||
label: 'Theming',
|
||||
to: '/getting-started/theming'
|
||||
}, {
|
||||
label: 'Command Palette',
|
||||
to: '/navigation/command-palette'
|
||||
label: 'Shortcuts',
|
||||
to: '/getting-started/shortcuts'
|
||||
}, {
|
||||
label: 'Examples',
|
||||
to: '/getting-started/examples'
|
||||
}, {
|
||||
label: 'Roadmap',
|
||||
to: '/getting-started/roadmap'
|
||||
}]
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,32 +1,15 @@
|
||||
<template>
|
||||
<aside class="hidden pb-8 overflow-y-auto lg:block lg:self-start lg:top-16 lg:max-h-[calc(100vh-64px)] lg:sticky lg:pr-8 lg:pl-[2px]">
|
||||
<aside class="hidden py-8 overflow-y-auto lg:block lg:self-start lg:top-16 lg:max-h-[calc(100vh-65px)] lg:sticky lg:pr-8 lg:pl-[2px]">
|
||||
<div class="relative">
|
||||
<div class="sticky top-0 pointer-events-none z-[1]">
|
||||
<!-- <div class="sticky top-0 pointer-events-none z-[1]">
|
||||
<div class="h-8 bg-white dark:bg-gray-900" />
|
||||
<div class="bg-white dark:bg-gray-900 relative pointer-events-auto">
|
||||
<UButton
|
||||
icon="i-heroicons-magnifying-glass-20-solid"
|
||||
class="w-full"
|
||||
color="gray"
|
||||
@click="isSearchModalOpen = true"
|
||||
>
|
||||
Search
|
||||
|
||||
<div class="hidden lg:flex items-center gap-0.5 ml-auto -my-1">
|
||||
<UKbd>{{ metaSymbol }}</UKbd>
|
||||
<UKbd>K</UKbd>
|
||||
</div>
|
||||
</UButton>
|
||||
<DocsSearchButton class="w-full" />
|
||||
</div>
|
||||
<div class="h-8 bg-gradient-to-b from-white dark:from-gray-900" />
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<DocsAsideLinks />
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { isSearchModalOpen } = useDocs()
|
||||
const { metaSymbol } = useShortcuts()
|
||||
</script>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="space-y-8">
|
||||
<div v-for="(group, index) in navigation" :key="index" class="space-y-3">
|
||||
<div class="text-sm font-semibold text-gray-900 dark:text-gray-200">
|
||||
<span class="truncate">{{ group.title }}</span>
|
||||
</div>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-gray-200 truncate leading-6">
|
||||
{{ group.title }}
|
||||
</p>
|
||||
|
||||
<UVerticalNavigation
|
||||
:links="mapContentLinks(group.children)"
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<template>
|
||||
<footer class="flex items-center justify-end gap-1.5">
|
||||
<footer class="flex items-center justify-between gap-1.5">
|
||||
<div class="flex items-baseline gap-1.5 text-sm text-center text-gray-500 dark:text-gray-400">
|
||||
Made by
|
||||
<NuxtLink to="https://nuxtlabs.com" aria-label="NuxtLabs">
|
||||
<LogoLabs class="text-primary-500 w-14 h-auto dark:text-primary-400" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<NuxtLink to="https://github.com/nuxtlabs/ui/releases" target="_blank">
|
||||
<UBadge label="v2.4.0" />
|
||||
</NuxtLink>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="page.description" class="mt-4 text-lg">
|
||||
<p v-if="page.description" class="mt-4 text-lg text-gray-500 dark:text-gray-400">
|
||||
{{ page.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NuxtLink :to="to" class="block px-5 py-8 border not-prose rounded-lg border-gray-200 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/25 group">
|
||||
<NuxtLink :to="to" class="block px-5 py-8 border not-prose rounded-lg border-gray-200 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 group">
|
||||
<div v-if="icon" class="inline-flex items-center rounded-full p-1.5 bg-gray-50 dark:bg-gray-800 group-hover:bg-primary-50 dark:group-hover:bg-primary-400/10 ring-1 ring-gray-300 dark:ring-gray-700 mb-4 group-hover:ring-primary-500/50 dark:group-hover:ring-primary-400/50">
|
||||
<UIcon :name="icon" class="w-5 h-5 text-gray-900 dark:text-gray-100 group-hover:text-primary-500 dark:group-hover:text-primary-400" />
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
ref="commandPaletteRef"
|
||||
:groups="groups"
|
||||
command-attribute="title"
|
||||
:close-button="{ icon: 'i-heroicons-x-mark-20-solid', color: 'gray', variant: 'ghost', size: 'sm', class: '-mr-1.5' }"
|
||||
:ui="{ input: { height: 'h-16 sm:h-12', icon: { size: 'h-5 w-5', padding: 'pl-11' } } }"
|
||||
:fuse="{
|
||||
fuseOptions: { ignoreLocation: true, includeMatches: true, threshold: 0, keys: ['title', 'description', 'children.children.value', 'children.children.children.value'] },
|
||||
resultLimit: 10
|
||||
|
||||
33
docs/components/docs/DocsSearchButton.vue
Normal file
33
docs/components/docs/DocsSearchButton.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<UButton
|
||||
color="white"
|
||||
variant="outline"
|
||||
icon="i-heroicons-magnifying-glass-20-solid"
|
||||
label="Search..."
|
||||
truncate
|
||||
:ui="{
|
||||
color: {
|
||||
white: {
|
||||
outline: 'ring-1 ring-inset ring-gray-200 dark:ring-gray-800 hover:ring-gray-300 dark:hover:ring-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 focus-visible:ring-2 focus-visible:ring-primary-500 dark:focus-visible:ring-primary-400'
|
||||
}
|
||||
}
|
||||
}"
|
||||
@click="isSearchModalOpen = true"
|
||||
>
|
||||
<template #trailing>
|
||||
<div class="hidden lg:flex items-center gap-0.5 ml-auto -my-1 flex-shrink-0">
|
||||
<UKbd class="!text-inherit">
|
||||
{{ metaSymbol }}
|
||||
</UKbd>
|
||||
<UKbd class="!text-inherit">
|
||||
K
|
||||
</UKbd>
|
||||
</div>
|
||||
</template>
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { isSearchModalOpen } = useDocs()
|
||||
const { metaSymbol } = useShortcuts()
|
||||
</script>
|
||||
Reference in New Issue
Block a user