mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-30 19:57:55 +01:00
Merge branch 'main' of https://github.com/benjamincanac/nuxt-ui3 into dev
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
primary: 'green',
|
||||
primary: 'sky',
|
||||
gray: 'cool'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,23 +1,50 @@
|
||||
<template>
|
||||
<UContainer class="min-h-screen flex items-center">
|
||||
<UCard class="flex-1" :ui="{ background: 'bg-gray-50 dark:bg-gray-800/50', ring: 'ring-1 ring-gray-300 dark:ring-gray-700', divide: 'divide-y divide-gray-300 dark:divide-gray-700', header: { base: 'font-bold' } }">
|
||||
<template #header>
|
||||
Welcome to the playground!
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { splitByCase, upperFirst } from 'scule'
|
||||
|
||||
<p class="text-gray-500 dark:text-gray-400">
|
||||
Try your components here!
|
||||
</p>
|
||||
</UCard>
|
||||
</UContainer>
|
||||
</template>
|
||||
useHead({
|
||||
bodyAttrs: {
|
||||
class: 'antialiased font-sans text-gray-900 dark:text-white bg-white dark:bg-gray-900'
|
||||
}
|
||||
})
|
||||
|
||||
<script setup>
|
||||
const components = [
|
||||
'accordion',
|
||||
'avatar',
|
||||
'badge',
|
||||
'button',
|
||||
'card',
|
||||
'checkbox',
|
||||
'chip',
|
||||
'collapsible',
|
||||
'form',
|
||||
'form-field',
|
||||
'input',
|
||||
'kbd',
|
||||
'link',
|
||||
'modal',
|
||||
'navigation-menu',
|
||||
'popover',
|
||||
'skeleton',
|
||||
'slideover',
|
||||
'switch',
|
||||
'tabs',
|
||||
'textarea',
|
||||
'tooltip'
|
||||
]
|
||||
|
||||
function upperName (name: string) {
|
||||
return splitByCase(name).map(p => upperFirst(p)).join('')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
@apply antialiased font-sans text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-900;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<UProvider>
|
||||
<UContainer class="min-h-screen flex flex-col gap-4 items-center justify-center overflow-y-auto">
|
||||
<UNavigationMenu :links="components.map(component => ({ label: upperName(component), to: `/${component}` }))" class="border-b border-gray-200 dark:border-gray-800 overflow-x-auto" />
|
||||
|
||||
<div class="flex-1 flex flex-col justify-center pb-12">
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</UContainer>
|
||||
</UProvider>
|
||||
</template>
|
||||
|
||||
65
playground/components/FormNestedExample.vue
Normal file
65
playground/components/FormNestedExample.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent } from '#ui/types/form'
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().min(2),
|
||||
password: z.string().min(8)
|
||||
})
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const nestedSchema = z.object({
|
||||
phone: z.string().length(10)
|
||||
})
|
||||
|
||||
type NestedSchema = z.output<typeof nestedSchema>
|
||||
|
||||
const state = reactive<Partial<Schema & { nested: Partial<NestedSchema> }>>({
|
||||
nested: {}
|
||||
})
|
||||
|
||||
const checked = ref(false)
|
||||
|
||||
function onSubmit (event: FormSubmitEvent<Schema>) {
|
||||
console.log('Success', event.data)
|
||||
}
|
||||
|
||||
function onError (event: any) {
|
||||
console.log('Error', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm
|
||||
:state="state"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
@submit="(event) => onSubmit(event)"
|
||||
@error="(event) => onError(event)"
|
||||
>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<div>
|
||||
<UCheckbox v-model="checked" name="check" label="Check me" @change="state.nested = {}" />
|
||||
</div>
|
||||
|
||||
<UForm v-if="checked && state.nested" :state="state.nested" :schema="nestedSchema">
|
||||
<UFormField label="Phone" name="phone">
|
||||
<UInput v-model="state.nested.phone" />
|
||||
</UFormField>
|
||||
</UForm>
|
||||
|
||||
<div>
|
||||
<UButton color="gray" type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</template>
|
||||
85
playground/components/FormNestedListExample.vue
Normal file
85
playground/components/FormNestedListExample.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent } from '#ui/types/form'
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().min(2),
|
||||
password: z.string().min(8)
|
||||
})
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const itemSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
price: z.string().min(1)
|
||||
})
|
||||
|
||||
type ItemSchema = z.output<typeof itemSchema>
|
||||
|
||||
const state = reactive<Partial<Schema & { items: Partial<ItemSchema>[] }>>({})
|
||||
|
||||
function addItem () {
|
||||
if (!state.items) {
|
||||
state.items = []
|
||||
}
|
||||
state.items.push({})
|
||||
}
|
||||
|
||||
function removeItem () {
|
||||
if (state.items) {
|
||||
state.items.pop()
|
||||
}
|
||||
}
|
||||
const formItemRef = ref()
|
||||
|
||||
function onSubmit (event: FormSubmitEvent<Schema>) {
|
||||
console.log('Success', event.data)
|
||||
}
|
||||
|
||||
function onError (event: any) {
|
||||
console.log('Error', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm
|
||||
ref="formItemRef"
|
||||
:state="state"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
@submit="onSubmit"
|
||||
@error="onError"
|
||||
>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<UForm v-for="item, count in state.items" :key="count" :state="item" :schema="itemSchema" class="flex gap-2">
|
||||
<UFormField label="Name" name="name">
|
||||
<UInput v-model="item.name" />
|
||||
</UFormField>
|
||||
<UFormField label="Price" name="price">
|
||||
<UInput v-model="item.price" />
|
||||
</UFormField>
|
||||
</UForm>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<UButton color="black" @click="addItem()">
|
||||
Add Item
|
||||
</UButton>
|
||||
|
||||
<UButton color="black" variant="ghost" @click="removeItem()">
|
||||
Remove Item
|
||||
</UButton>
|
||||
</div>
|
||||
<div>
|
||||
<UButton color="gray" type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</template>
|
||||
21
playground/components/Placeholder.vue
Normal file
21
playground/components/Placeholder.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden rounded border border-dashed border-gray-400 dark:border-gray-500 opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-gray-900/10 dark:stroke-white/10" fill="none">
|
||||
<defs>
|
||||
<pattern
|
||||
id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
|
||||
x="0"
|
||||
y="0"
|
||||
width="10"
|
||||
height="10"
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<path d="M-3 13 15-5M-5 5l18-18M-1 21 17 3" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect stroke="none" fill="url(#pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e)" width="100%" height="100%" />
|
||||
</svg>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +1,7 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
modules: [
|
||||
'../src/module'
|
||||
]
|
||||
modules: ['../src/module'],
|
||||
ui: {
|
||||
colors: ['primary', 'red']
|
||||
}
|
||||
})
|
||||
|
||||
16
playground/package.json
Normal file
16
playground/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "nuxt-ui-playground",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "nuxi dev",
|
||||
"build": "nuxi build",
|
||||
"generate": "nuxi generate"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/ui": "latest",
|
||||
"nuxt": "latest",
|
||||
"vue": "latest",
|
||||
"vue-router": "latest"
|
||||
}
|
||||
}
|
||||
35
playground/pages/accordion.vue
Normal file
35
playground/pages/accordion.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Getting Started',
|
||||
icon: 'i-heroicons-information-circle',
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}, {
|
||||
label: 'Installation',
|
||||
icon: 'i-heroicons-arrow-down-tray',
|
||||
disabled: true,
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}, {
|
||||
label: 'Theming',
|
||||
icon: 'i-heroicons-eye-dropper',
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}, {
|
||||
label: 'Layouts',
|
||||
icon: 'i-heroicons-rectangle-group',
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}, {
|
||||
label: 'Components',
|
||||
icon: 'i-heroicons-square-3-stack-3d',
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}, {
|
||||
label: 'Utilities',
|
||||
slot: 'toto',
|
||||
icon: 'i-heroicons-wrench-screwdriver',
|
||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate.'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCard :ui="{ body: 'p-0 sm:p-0' }">
|
||||
<UAccordion :items="items" class="w-96" :ui="{ trigger: 'px-3.5', content: 'px-3.5' }" />
|
||||
</UCard>
|
||||
</template>
|
||||
22
playground/pages/avatar.vue
Normal file
22
playground/pages/avatar.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/avatar'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<UAvatar v-for="size in sizes" :key="size" src="https://avatars.githubusercontent.com/u/739984?v=4" alt="Benjamin Canac" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<UAvatar v-for="size in sizes" :key="size" icon="i-heroicons-photo" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<UAvatar v-for="size in sizes" :key="size" alt="Benjamin Canac" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<UAvatar v-for="size in sizes" :key="size" :text="size" :size="(size as any)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
33
playground/pages/badge.vue
Normal file
33
playground/pages/badge.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/badge'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<UBadge class="font-bold">
|
||||
Badge
|
||||
</UBadge>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UBadge label="Badge" />
|
||||
<UBadge label="Badge" variant="outline" />
|
||||
<UBadge label="Badge" variant="soft" />
|
||||
<UBadge label="Badge" variant="subtle" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UBadge label="Badge" color="white" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UBadge label="Badge" color="gray" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UBadge label="Badge" color="black" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-56px]">
|
||||
<UBadge v-for="size in sizes" :key="size" label="Badge" :size="(size as any)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
88
playground/pages/button.vue
Normal file
88
playground/pages/button.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/button'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton class="font-bold">
|
||||
Button
|
||||
</UButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton disabled>
|
||||
Disabled
|
||||
</UButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton loading>
|
||||
Loading
|
||||
</UButton>
|
||||
|
||||
<UButton loading leading-icon="i-heroicons-rocket-launch">
|
||||
Loading
|
||||
</UButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton loading trailing>
|
||||
Loading
|
||||
</UButton>
|
||||
|
||||
<UButton loading trailing-icon="i-heroicons-paper-airplane">
|
||||
Loading
|
||||
</UButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton truncate class="w-16">
|
||||
Truncate
|
||||
</UButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" variant="outline" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" variant="soft" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" variant="ghost" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" variant="link" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="white" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="white" variant="ghost" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="gray" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="gray" variant="ghost" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="gray" variant="link" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="black" />
|
||||
<UButton icon="i-heroicons-rocket-launch" label="Button" color="black" variant="link" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-129px]">
|
||||
<UButton v-for="size in sizes" :key="size" label="Button" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-171px]">
|
||||
<UButton v-for="size in sizes" :key="size" icon="i-heroicons-rocket-launch" label="Button" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-159px]">
|
||||
<UButton
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
icon="i-heroicons-rocket-launch"
|
||||
label="Square"
|
||||
square
|
||||
:size="(size as any)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-67px]">
|
||||
<UButton v-for="size in sizes" :key="size" icon="i-heroicons-rocket-launch" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-rocket-launch" trailing-icon="i-heroicons-chevron-down-20-solid" label="Block" loading block />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UButton icon="i-heroicons-cloud-arrow-down" label="Button" class="group" :ui="{ leadingIcon: 'group-hover:animate-pulse' }" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
15
playground/pages/card.vue
Normal file
15
playground/pages/card.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<UCard class="w-96">
|
||||
<template #header>
|
||||
<Placeholder class="h-8" />
|
||||
</template>
|
||||
|
||||
<Placeholder class="h-32" />
|
||||
|
||||
<template #footer>
|
||||
<Placeholder class="h-8" />
|
||||
</template>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
25
playground/pages/checkbox.vue
Normal file
25
playground/pages/checkbox.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/checkbox'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="flex flex-col gap-4 ml-[-272px]">
|
||||
<UCheckbox label="Normal" />
|
||||
<UCheckbox label="Checked" :model-value="true" />
|
||||
<UCheckbox label="Indeterminate" indeterminate />
|
||||
<UCheckbox label="Default checked" default-checked />
|
||||
<UCheckbox label="Required" required />
|
||||
<UCheckbox label="Disabled" disabled />
|
||||
<UCheckbox label="Custom icon" color="red" icon="i-heroicons-heart-solid" :model-value="true" />
|
||||
</div>
|
||||
<div class="flex items-center gap-4 ml-[-156px]">
|
||||
<UCheckbox v-for="size in sizes" :key="size" label="Check me" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<UCheckbox v-for="size in sizes" :key="size" label="Check me" description="This is a description" :size="(size as any)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
38
playground/pages/chip.vue
Normal file
38
playground/pages/chip.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/chip'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
const positions = Object.keys(theme.variants.position)
|
||||
|
||||
const items = [{
|
||||
name: 'messages',
|
||||
icon: 'i-heroicons-chat-bubble-oval-left',
|
||||
count: 3
|
||||
}, {
|
||||
name: 'notifications',
|
||||
icon: 'i-heroicons-bell',
|
||||
count: 0
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<UChip v-for="position in positions" :key="position" :position="(position as any)">
|
||||
<UButton icon="i-heroicons-inbox" color="gray" />
|
||||
</UChip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UChip v-for="{ name, icon, count } in items" :key="name" :text="count" :show="count > 0" size="lg">
|
||||
<UButton :icon="icon" color="gray" />
|
||||
</UChip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 ml-[-84px]">
|
||||
<UChip v-for="size in sizes" :key="size" :size="(size as any)" inset text="1">
|
||||
<UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" :size="(size as any)" />
|
||||
</UChip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
16
playground/pages/collapsible.vue
Normal file
16
playground/pages/collapsible.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<UCollapsible class="space-y-2 w-48">
|
||||
<UButton
|
||||
class="group"
|
||||
trailing-icon="i-heroicons-chevron-right-20-solid"
|
||||
color="gray"
|
||||
label="Open"
|
||||
block
|
||||
:ui="{ trailingIcon: 'group-data-[state=open]:rotate-90 transition-transform duration-200' }"
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<Placeholder class="h-24 w-full" />
|
||||
</template>
|
||||
</UCollapsible>
|
||||
</template>
|
||||
49
playground/pages/form-field.vue
Normal file
49
playground/pages/form-field.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/formField'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
const feedbacks = [
|
||||
{ description: 'This is a description' },
|
||||
{ error: 'This is an error' },
|
||||
{ hint: 'This is a hint' },
|
||||
{ help: 'Help! I need somebody!' },
|
||||
{ required: true }
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="flex flex-col gap-4 ml-[-258px]">
|
||||
<div v-for="(feedback, count) in feedbacks" :key="count" class="flex items-center">
|
||||
<UFormField v-bind="feedback" label="Email" name="email">
|
||||
<UInput placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<UFormField
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
:size="(size as any)"
|
||||
label="Email"
|
||||
name="email"
|
||||
>
|
||||
<UInput placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<UFormField
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
:size="(size as any)"
|
||||
label="Email"
|
||||
description="This is a description"
|
||||
name="email"
|
||||
>
|
||||
<UInput placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
121
playground/pages/form.vue
Normal file
121
playground/pages/form.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { Form, FormSubmitEvent } from '#ui/types/form'
|
||||
|
||||
type User = {
|
||||
email: string
|
||||
password: string
|
||||
tos: boolean
|
||||
}
|
||||
|
||||
const state = reactive<Partial<User>>({})
|
||||
const state2 = reactive<Partial<User>>({})
|
||||
const state3 = reactive<Partial<User>>({})
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
tos: z.literal(true)
|
||||
})
|
||||
|
||||
const disabledForm = ref<Form<User>>()
|
||||
|
||||
function onSubmit (event: FormSubmitEvent<User>) {
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex gap-4">
|
||||
<UForm
|
||||
:state="state"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
@submit="(event) => onSubmit(event)"
|
||||
>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="tos">
|
||||
<UCheckbox v-model="state.tos" label="I accept the terms and conditions" />
|
||||
</UFormField>
|
||||
|
||||
<div>
|
||||
<UButton color="gray" type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
|
||||
<UForm
|
||||
:state="state2"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
:validate-on-input-delay="2000"
|
||||
@submit="(event) => onSubmit(event)"
|
||||
>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state2.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField
|
||||
label="Password"
|
||||
name="password"
|
||||
:validate-on-input-delay="50"
|
||||
eager-validation
|
||||
>
|
||||
<UInput v-model="state2.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<div>
|
||||
<UButton color="gray" type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
|
||||
<UForm
|
||||
ref="disabledForm"
|
||||
:state="state3"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
disabled
|
||||
@submit="(event) => onSubmit(event)"
|
||||
>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state3.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField
|
||||
label="Password"
|
||||
name="password"
|
||||
:validate-on-input-delay="50"
|
||||
eager-validation
|
||||
>
|
||||
<UInput v-model="state3.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="tos">
|
||||
<UCheckbox v-model="state3.tos" label="I accept the terms and conditions" />
|
||||
</UFormField>
|
||||
|
||||
<div>
|
||||
<UButton color="gray" type="submit" :disabled="disabledForm?.disabled">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-4">
|
||||
<FormNestedExample />
|
||||
<FormNestedListExample />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
3
playground/pages/index.vue
Normal file
3
playground/pages/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
51
playground/pages/input.vue
Normal file
51
playground/pages/input.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/input'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="flex flex-col gap-4 ml-[-120px]">
|
||||
<UInput placeholder="Search..." autofocus />
|
||||
<UInput placeholder="Search..." color="gray" />
|
||||
<UInput placeholder="Search..." color="primary" />
|
||||
<UInput placeholder="Search..." disabled />
|
||||
<UInput placeholder="Search..." type="number" />
|
||||
<UInput icon="i-heroicons-folder" placeholder="Search..." type="file" />
|
||||
<UInput icon="i-heroicons-calendar" placeholder="Search..." type="date" />
|
||||
<UInput icon="i-heroicons-lock-closed" placeholder="Search..." type="password" value="password" />
|
||||
<UInput loading placeholder="Search..." />
|
||||
<UInput loading leading-icon="i-heroicons-magnifying-glass" placeholder="Search..." />
|
||||
<UInput loading trailing placeholder="Search..." />
|
||||
<UInput loading trailing-icon="i-heroicons-magnifying-glass" placeholder="Search..." />
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<UInput
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
placeholder="Search..."
|
||||
:size="(size as any)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<UInput
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
placeholder="Search..."
|
||||
:size="(size as any)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<UInput
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
trailing
|
||||
placeholder="Search..."
|
||||
:size="(size as any)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
6
playground/pages/kbd.vue
Normal file
6
playground/pages/kbd.vue
Normal file
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div class="flex items-center gap-1">
|
||||
<UKbd value="⌘" />
|
||||
<UKbd value="K" />
|
||||
</div>
|
||||
</template>
|
||||
55
playground/pages/link.vue
Normal file
55
playground/pages/link.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex flex-col items-start gap-2 text-sm">
|
||||
<ULink raw>
|
||||
Button raw
|
||||
</ULink>
|
||||
|
||||
<ULink active>
|
||||
Button active
|
||||
</ULink>
|
||||
<ULink active class="font-medium" active-class="text-gray-900 dark:text-white">
|
||||
Button active with class
|
||||
</ULink>
|
||||
<ULink active disabled>
|
||||
Button active disabled
|
||||
</ULink>
|
||||
|
||||
<ULink>
|
||||
Button inactive
|
||||
</ULink>
|
||||
<ULink class="font-medium" inactive-class="hover:text-primary-500 dark:hover:text-primary-400">
|
||||
Button inactive with class
|
||||
</ULink>
|
||||
<ULink disabled>
|
||||
Button inactive disabled
|
||||
</ULink>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-start gap-2 text-sm">
|
||||
<ULink to="/link" raw>
|
||||
Link raw
|
||||
</ULink>
|
||||
|
||||
<ULink to="/link">
|
||||
Link active
|
||||
</ULink>
|
||||
<ULink to="/link" class="font-medium" active-class="text-gray-900 dark:text-white">
|
||||
Link active with class
|
||||
</ULink>
|
||||
<ULink to="/link" disabled>
|
||||
Link active disabled
|
||||
</ULink>
|
||||
|
||||
<ULink to="/button">
|
||||
Link inactive
|
||||
</ULink>
|
||||
<ULink to="/button" class="font-medium" inactive-class="hover:text-primary-500 dark:hover:text-primary-400">
|
||||
Link inactive with class
|
||||
</ULink>
|
||||
<ULink to="/button" disabled>
|
||||
Link inactive disabled
|
||||
</ULink>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
53
playground/pages/modal.vue
Normal file
53
playground/pages/modal.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<UModal title="First modal">
|
||||
<UButton color="white" label="Open with nested" />
|
||||
|
||||
<template #footer>
|
||||
<UModal title="Second modal">
|
||||
<UButton label="Open second" />
|
||||
</UModal>
|
||||
</template>
|
||||
</UModal>
|
||||
|
||||
<UModal v-model:open="open" title="Modal with v-model" description="This can be useful to control the state of the modal yourself." />
|
||||
|
||||
<UButton label="Open with v-model" color="gray" @click="open = true" />
|
||||
|
||||
<UModal title="Modal without overlay" description="This modal has `overlay: false` prop." :overlay="false">
|
||||
<UButton label="Open without overlay" color="white" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal without modal & overlay" description="This modal has `modal: false` and `overlay: false` to interact with outside content." :overlay="false" :modal="false">
|
||||
<UButton label="Open without modal" color="gray" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal without transition" description="This modal has `transition: false` prop." :transition="false">
|
||||
<UButton label="Open without transition" color="white" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal without portal" description="This modal has `portal: false` prop." :portal="false">
|
||||
<UButton label="Open without portal" color="gray" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal fullscreen" description="This modal has `fullscreen: true` prop." fullscreen>
|
||||
<UButton label="Open fullscreen" color="white" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal prevent close" description="This modal has `prevent-close: true` prop so it won't close when clicking outside." prevent-close>
|
||||
<UButton label="Open unclosable" color="gray" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal without close button" description="This modal has `close: null` prop." :close="null">
|
||||
<UButton label="Open without close button" color="white" />
|
||||
</UModal>
|
||||
|
||||
<UModal title="Modal with custom close button" description="The `close` prop inherits from the Button props." :close="{ color: 'primary', variant: 'solid', size: 'xs' }" :ui="{ close: 'top-3.5 rounded-full' }">
|
||||
<UButton label="Open with custom close button" color="gray" />
|
||||
</UModal>
|
||||
</div>
|
||||
</template>
|
||||
43
playground/pages/navigation-menu.vue
Normal file
43
playground/pages/navigation-menu.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
const links = [
|
||||
[{
|
||||
label: 'Profile',
|
||||
active: true,
|
||||
avatar: {
|
||||
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
|
||||
},
|
||||
badge: 100,
|
||||
click () {
|
||||
console.log('Profile clicked')
|
||||
}
|
||||
}, {
|
||||
label: 'Modal',
|
||||
icon: 'i-heroicons-home',
|
||||
to: '/modal'
|
||||
}, {
|
||||
label: 'NavigationMenu',
|
||||
icon: 'i-heroicons-chart-bar',
|
||||
to: '/navigation-menu'
|
||||
}, {
|
||||
label: 'Popover',
|
||||
icon: 'i-heroicons-command-line',
|
||||
to: '/popover'
|
||||
}], [{
|
||||
label: 'Examples',
|
||||
icon: 'i-heroicons-light-bulb',
|
||||
to: 'https://ui.nuxt.com',
|
||||
target: '_blank'
|
||||
}, {
|
||||
label: 'Help',
|
||||
icon: 'i-heroicons-question-mark-circle'
|
||||
}]
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-12 w-4xl">
|
||||
<UNavigationMenu :links="links" class="border-b border-gray-200 dark:border-gray-800" />
|
||||
|
||||
<UNavigationMenu :links="links" orientation="vertical" class="w-48" />
|
||||
</div>
|
||||
</template>
|
||||
64
playground/pages/popover.vue
Normal file
64
playground/pages/popover.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
function send () {
|
||||
loading.value = true
|
||||
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
open.value = false
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-center">
|
||||
<UPopover v-model:open="open" arrow>
|
||||
<UButton label="Click me" color="white" />
|
||||
|
||||
<template #content>
|
||||
<div class="flex justify-center gap-2 p-4 w-48">
|
||||
<UButton label="Close" color="gray" @click="open = false" />
|
||||
<UButton label="Send" color="black" trailing-icon="i-heroicons-paper-airplane" :loading="loading" @click="send" />
|
||||
</div>
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
<div class="mt-24">
|
||||
<UPopover mode="hover" :content="{ side: 'top' }">
|
||||
<UButton label="Hover me top" color="white" />
|
||||
|
||||
<template #content>
|
||||
<div class="w-48 h-16" />
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
<div class="flex items-center gap-2 my-2">
|
||||
<UPopover mode="hover" :content="{ side: 'left' }">
|
||||
<UButton label="Hover me left" color="white" />
|
||||
|
||||
<template #content>
|
||||
<div class="w-48 h-16" />
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
<UPopover mode="hover" :content="{ side: 'right' }">
|
||||
<UButton label="Hover me right" color="white" />
|
||||
|
||||
<template #content>
|
||||
<div class="w-48 h-16" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</div>
|
||||
|
||||
<UPopover mode="hover">
|
||||
<UButton label="Hover me bottom" color="white" />
|
||||
|
||||
<template #content>
|
||||
<div class="w-48 h-16" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
10
playground/pages/skeleton.vue
Normal file
10
playground/pages/skeleton.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div class="flex items-center gap-4">
|
||||
<USkeleton class="h-12 w-12 rounded-full" />
|
||||
|
||||
<div class="space-y-2">
|
||||
<USkeleton class="h-4 w-[250px]" />
|
||||
<USkeleton class="h-4 w-[200px]" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
109
playground/pages/slideover.vue
Normal file
109
playground/pages/slideover.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<USlideover title="First slideover">
|
||||
<UButton color="white" label="Open with nested" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<USlideover title="Second slideover">
|
||||
<UButton label="Open second" />
|
||||
</USlideover>
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover on left side" description="This slideover has `side: 'left'` prop." side="left">
|
||||
<UButton label="Open on left" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover on top side" description="This slideover has `side: 'top'` prop." side="top">
|
||||
<UButton label="Open on top" color="white" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-48 w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover on bottom side" description="This slideover has `side: 'bottom'` prop." side="bottom">
|
||||
<UButton label="Open on bottom" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-48 w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover v-model:open="open" title="Slideover with v-model" description="This can be useful to control the state of the slideover yourself.">
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<UButton label="Open with v-model" color="white" @click="open = true" />
|
||||
|
||||
<USlideover title="Slideover without overlay" description="This slideover has `overlay: false` prop." :overlay="false">
|
||||
<UButton label="Open without overlay" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover without modal & overlay" description="This slideover has `modal: false` and `overlay: false` to interact with outside content." :overlay="false" :modal="false">
|
||||
<UButton label="Open without modal" color="white" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover without transition" description="This slideover has `transition: false` prop." :transition="false">
|
||||
<UButton label="Open without transition" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover without portal" description="This slideover has `portal: false` prop." :portal="false">
|
||||
<UButton label="Open without portal" color="white" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover prevent close" description="This slideover has `prevent-close: true` prop so it won't close when clicking outside." prevent-close>
|
||||
<UButton label="Open unclosable" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover without close button" description="This slideover has `close: null` prop." :close="null">
|
||||
<UButton label="Open without close button" color="white" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
|
||||
<USlideover title="Slideover with custom close button" description="The `close` prop inherits from the Button props." :close="{ color: 'primary', variant: 'solid', size: 'xs' }" :ui="{ close: 'top-3.5 rounded-full' }">
|
||||
<UButton label="Open with custom close button" color="gray" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-full w-full" />
|
||||
</template>
|
||||
</USlideover>
|
||||
</div>
|
||||
</template>
|
||||
41
playground/pages/switch.vue
Normal file
41
playground/pages/switch.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/switch'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
const checked = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div>
|
||||
<USwitch v-model:checked="checked" />
|
||||
</div>
|
||||
<div>
|
||||
<USwitch v-model:checked="checked" disabled />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-64px]">
|
||||
<USwitch v-for="size in sizes" :key="size" v-model:checked="checked" :size="(size as any)" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-64px]">
|
||||
<USwitch
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
v-model:checked="checked"
|
||||
:size="(size as any)"
|
||||
unchecked-icon="i-heroicons-x-mark-20-solid"
|
||||
checked-icon="i-heroicons-check-20-solid"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-[-64px]">
|
||||
<USwitch
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
v-model:checked="checked"
|
||||
:size="(size as any)"
|
||||
unchecked-icon="i-heroicons-x-mark-20-solid"
|
||||
checked-icon="i-heroicons-check-20-solid"
|
||||
loading
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
16
playground/pages/tabs.vue
Normal file
16
playground/pages/tabs.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Tab1',
|
||||
content: 'This is the content shown for Tab1'
|
||||
}, {
|
||||
label: 'Tab2',
|
||||
content: 'And, this is the content for Tab2'
|
||||
}, {
|
||||
label: 'Tab3',
|
||||
content: 'Finally, this is the content for Tab3'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTabs :items="items" />
|
||||
</template>
|
||||
36
playground/pages/textarea.vue
Normal file
36
playground/pages/textarea.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import theme from '#build/ui/textarea'
|
||||
|
||||
const sizes = Object.keys(theme.variants.size)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="flex gap-4">
|
||||
<UTextarea />
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<UTextarea placeholder="Search..." autofocus />
|
||||
<UTextarea placeholder="Search..." color="gray" />
|
||||
<UTextarea placeholder="Search..." color="primary" />
|
||||
<UTextarea placeholder="Search..." disabled />
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<UTextarea
|
||||
v-for="size in sizes"
|
||||
:key="size"
|
||||
placeholder="Search..."
|
||||
:size="(size as any)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<UTextarea autofocus />
|
||||
<UTextarea autofocus :autofocus-delay="500" />
|
||||
<UTextarea autoresize />
|
||||
<UTextarea autoresize :maxrows="5" :rows="1" />
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<UTextarea variant="none" placeholder="You can't see me" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
21
playground/pages/tooltip.vue
Normal file
21
playground/pages/tooltip.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<UTooltip text="Top" :shortcuts="['⌘', 'T']" :content="{ side: 'top' }" arrow>
|
||||
<UAvatar text="T" />
|
||||
</UTooltip>
|
||||
|
||||
<div class="flex items-center gap-2 ml-[-20px]">
|
||||
<UTooltip text="Left" :shortcuts="['⌘', 'L']" :content="{ side: 'left' }" arrow>
|
||||
<UAvatar text="L" />
|
||||
</UTooltip>
|
||||
|
||||
<UTooltip text="Right" :shortcuts="['⌘', 'R']" :content="{ side: 'right' }" arrow>
|
||||
<UAvatar text="R" />
|
||||
</UTooltip>
|
||||
</div>
|
||||
|
||||
<UTooltip text="Bottom" :shortcuts="['⌘', 'B']" arrow>
|
||||
<UAvatar text="B" />
|
||||
</UTooltip>
|
||||
</div>
|
||||
</template>
|
||||
BIN
playground/public/favicon.ico
Normal file
BIN
playground/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Reference in New Issue
Block a user