mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
chore(Kbd): new component
This commit is contained in:
@@ -10,10 +10,10 @@ const users = [
|
||||
]
|
||||
|
||||
const actions = [
|
||||
{ id: 'new-file', label: 'Add new file', icon: 'i-heroicons-document-plus', click: () => alert('New file') },
|
||||
{ id: 'new-folder', label: 'Add new folder', icon: 'i-heroicons-folder-plus', click: () => alert('New folder') },
|
||||
{ id: 'hashtag', label: 'Add hashtag', icon: 'i-heroicons-hashtag', click: () => alert('Add hashtag') },
|
||||
{ id: 'label', label: 'Add label', icon: 'i-heroicons-tag', click: () => alert('Add label') }
|
||||
{ id: 'new-file', label: 'Add new file', icon: 'i-heroicons-document-plus', click: () => alert('New file'), shortcuts: ['⌘', 'N'] },
|
||||
{ id: 'new-folder', label: 'Add new folder', icon: 'i-heroicons-folder-plus', click: () => alert('New folder'), shortcuts: ['⌘', 'F'] },
|
||||
{ id: 'hashtag', label: 'Add hashtag', icon: 'i-heroicons-hashtag', click: () => alert('Add hashtag'), shortcuts: ['⌘', 'H'] },
|
||||
{ id: 'label', label: 'Add label', icon: 'i-heroicons-tag', click: () => alert('Add label'), shortcuts: ['⌘', 'L'] }
|
||||
]
|
||||
|
||||
const groups = computed(() => commandPaletteRef.value?.query
|
||||
|
||||
@@ -7,10 +7,12 @@ const items = [
|
||||
}
|
||||
}], [{
|
||||
label: 'Edit',
|
||||
icon: 'i-heroicons-pencil-square-20-solid'
|
||||
icon: 'i-heroicons-pencil-square-20-solid',
|
||||
shortcuts: ['E']
|
||||
}, {
|
||||
label: 'Duplicate',
|
||||
icon: 'i-heroicons-document-duplicate-20-solid'
|
||||
icon: 'i-heroicons-document-duplicate-20-solid',
|
||||
shortcuts: ['D']
|
||||
}], [{
|
||||
label: 'Archive',
|
||||
icon: 'i-heroicons-archive-box-20-solid'
|
||||
@@ -19,7 +21,8 @@ const items = [
|
||||
icon: 'i-heroicons-arrow-right-circle-20-solid'
|
||||
}], [{
|
||||
label: 'Delete',
|
||||
icon: 'i-heroicons-trash-20-solid'
|
||||
icon: 'i-heroicons-trash-20-solid',
|
||||
shortcuts: ['⌘', 'D']
|
||||
}]
|
||||
]
|
||||
</script>
|
||||
|
||||
10
docs/components/content/examples/KbdExample.vue
Normal file
10
docs/components/content/examples/KbdExample.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<script setup>
|
||||
const { metaSymbol } = useShortcuts()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<UKbd>{{ metaSymbol }}</UKbd>
|
||||
<UKbd>U</UKbd>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<UTooltip text="Tooltip">
|
||||
<UButton color="gray" label="Button" />
|
||||
<UTooltip text="Tooltip example" :shortcuts="['⌘', 'O']">
|
||||
<UButton color="gray" label="Hover me" />
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
>
|
||||
Search
|
||||
|
||||
<div class="hidden lg:flex items-center gap-1 ml-auto -my-1">
|
||||
<Shortcut value="meta" />
|
||||
<Shortcut value="K" />
|
||||
<div class="hidden lg:flex items-center gap-0.5 ml-auto -my-1">
|
||||
<UKbd>{{ metaSymbol }}</UKbd>
|
||||
<UKbd>K</UKbd>
|
||||
</div>
|
||||
</UButton>
|
||||
</div>
|
||||
@@ -30,4 +30,5 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
const { isSearchModalOpen } = useDocs()
|
||||
const { metaSymbol } = useShortcuts()
|
||||
</script>
|
||||
|
||||
@@ -22,10 +22,12 @@ const items = [
|
||||
}
|
||||
}], [{
|
||||
label: 'Edit',
|
||||
icon: 'i-heroicons-pencil-square-20-solid'
|
||||
icon: 'i-heroicons-pencil-square-20-solid',
|
||||
shortcuts: ['E']
|
||||
}, {
|
||||
label: 'Duplicate',
|
||||
icon: 'i-heroicons-document-duplicate-20-solid'
|
||||
icon: 'i-heroicons-document-duplicate-20-solid',
|
||||
shortcuts: ['D']
|
||||
}], [{
|
||||
label: 'Archive',
|
||||
icon: 'i-heroicons-archive-box-20-solid'
|
||||
@@ -34,7 +36,8 @@ const items = [
|
||||
icon: 'i-heroicons-arrow-right-circle-20-solid'
|
||||
}], [{
|
||||
label: 'Delete',
|
||||
icon: 'i-heroicons-trash-20-solid'
|
||||
icon: 'i-heroicons-trash-20-solid',
|
||||
shortcuts: ['⌘', 'D']
|
||||
}]
|
||||
]
|
||||
</script>
|
||||
|
||||
48
docs/content/2.elements/5.kbd.md
Normal file
48
docs/content/2.elements/5.kbd.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
github: true
|
||||
title: 'Keyboard Key'
|
||||
navigation:
|
||||
title: 'Kbd'
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
::component-example
|
||||
#default
|
||||
:kbd-example
|
||||
|
||||
#code
|
||||
```vue
|
||||
<script setup>
|
||||
const { metaSymbol } = useShortcuts()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<UKbd>{{ metaSymbol }}</UKbd>
|
||||
<UKbd>U</UKbd>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
### Size
|
||||
|
||||
Use the `size` prop to change the size of the Kbd.
|
||||
|
||||
::component-card
|
||||
---
|
||||
props:
|
||||
size: 'sm'
|
||||
---
|
||||
|
||||
U
|
||||
::
|
||||
|
||||
## Props
|
||||
|
||||
:component-props
|
||||
|
||||
## Preset
|
||||
|
||||
:component-preset
|
||||
@@ -118,10 +118,10 @@ const users = [
|
||||
]
|
||||
|
||||
const actions = [
|
||||
{ id: 'new-file', label: 'Add new file', icon: 'i-heroicons-document-plus', click: () => alert('New file') },
|
||||
{ id: 'new-folder', label: 'Add new folder', icon: 'i-heroicons-folder-plus', click: () => alert('New folder') },
|
||||
{ id: 'hashtag', label: 'Add hashtag', icon: 'i-heroicons-hashtag', click: () => alert('Add hashtag') },
|
||||
{ id: 'label', label: 'Add label', icon: 'i-heroicons-tag', click: () => alert('Add label') }
|
||||
{ id: 'new-file', label: 'Add new file', icon: 'i-heroicons-document-plus', click: () => alert('New file'), shortcuts: ['⌘', 'N'] },
|
||||
{ id: 'new-folder', label: 'Add new folder', icon: 'i-heroicons-folder-plus', click: () => alert('New folder'), shortcuts: ['⌘', 'F'] },
|
||||
{ id: 'hashtag', label: 'Add hashtag', icon: 'i-heroicons-hashtag', click: () => alert('Add hashtag'), shortcuts: ['⌘', 'H'] },
|
||||
{ id: 'label', label: 'Add label', icon: 'i-heroicons-tag', click: () => alert('Add label'), shortcuts: ['⌘', 'L'] }
|
||||
]
|
||||
|
||||
const groups = computed(() => commandPaletteRef.value?.query
|
||||
|
||||
@@ -10,8 +10,8 @@ github: true
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<UTooltip text="Tooltip">
|
||||
<UButton color="gray" label="Button" />
|
||||
<UTooltip text="Tooltip example" :shortcuts="['⌘', 'O']">
|
||||
<UButton color="gray" label="Hover me" />
|
||||
</UTooltip>
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -179,7 +179,7 @@ const dropdown = {
|
||||
base: 'flex-shrink-0',
|
||||
size: '3xs'
|
||||
},
|
||||
shortcuts: 'hidden md:inline-flex flex-shrink-0 text-xs font-semibold text-gray-500 dark:text-gray-400 ml-auto'
|
||||
shortcuts: 'hidden md:inline-flex flex-shrink-0 gap-0.5 ml-auto'
|
||||
},
|
||||
transition: {
|
||||
enterActiveClass: 'transition duration-100 ease-out',
|
||||
@@ -195,6 +195,23 @@ const dropdown = {
|
||||
}
|
||||
}
|
||||
|
||||
const kbd = {
|
||||
base: 'inline-flex items-center justify-center text-gray-900 dark:text-white',
|
||||
spacing: 'px-1',
|
||||
size: {
|
||||
xs: 'h-4 min-w-[16px] text-[10px]',
|
||||
sm: 'h-5 min-w-[20px] text-[11px]',
|
||||
md: 'h-6 min-w-[24px] text-[12px]'
|
||||
},
|
||||
rounded: 'rounded',
|
||||
font: 'font-medium font-sans',
|
||||
background: 'bg-gray-100 dark:bg-gray-800',
|
||||
ring: 'ring-1 ring-gray-300 dark:ring-gray-700 ring-inset',
|
||||
default: {
|
||||
size: 'sm'
|
||||
}
|
||||
}
|
||||
|
||||
// Forms
|
||||
|
||||
const input = {
|
||||
@@ -494,7 +511,7 @@ const commandPalette = {
|
||||
selected: {
|
||||
icon: 'h-4 w-4 text-gray-900 dark:text-white flex-shrink-0'
|
||||
},
|
||||
shortcuts: 'hidden md:inline-flex flex-shrink-0 text-xs font-semibold text-gray-500 dark:text-gray-400'
|
||||
shortcuts: 'hidden md:inline-flex flex-shrink-0 gap-0.5'
|
||||
},
|
||||
active: 'flex-shrink-0 text-gray-500 dark:text-gray-400',
|
||||
inactive: 'flex-shrink-0 text-gray-500 dark:text-gray-400'
|
||||
@@ -582,7 +599,7 @@ const tooltip = {
|
||||
rounded: 'rounded',
|
||||
ring: 'ring-1 ring-gray-200 dark:ring-gray-800',
|
||||
base: 'invisible lg:visible h-6 px-2 py-1 text-xs font-normal truncate',
|
||||
shortcuts: 'hidden md:inline-flex items-center justify-end flex-shrink-0 gap-0.5 ml-1',
|
||||
shortcuts: 'hidden md:inline-flex flex-shrink-0 gap-0.5',
|
||||
transition: {
|
||||
enterActiveClass: 'transition ease-out duration-200',
|
||||
enterFromClass: 'opacity-0 translate-y-1',
|
||||
@@ -688,6 +705,7 @@ export default {
|
||||
button,
|
||||
buttonGroup,
|
||||
dropdown,
|
||||
kbd,
|
||||
input,
|
||||
inputGroup,
|
||||
textarea,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<span class="truncate">{{ item.label }}</span>
|
||||
|
||||
<span v-if="item.shortcuts?.length" :class="ui.item.shortcuts">
|
||||
<kbd v-for="shortcut of item.shortcuts" :key="shortcut" class="font-sans">{{ shortcut }}</kbd>
|
||||
<UKbd v-for="shortcut of item.shortcuts" :key="shortcut">{{ shortcut }}</UKbd>
|
||||
</span>
|
||||
</slot>
|
||||
</Component>
|
||||
@@ -53,7 +53,8 @@ import { defineComponent, ref, computed, onMounted } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
import UAvatar from '../elements/Avatar.vue'
|
||||
import { classNames, omit } from '../../utils'
|
||||
import UKbd from '../elements/Kbd.vue'
|
||||
import { omit } from '../../utils'
|
||||
import { usePopper } from '../../composables/usePopper'
|
||||
import type { Avatar as AvatarType } from '../../types/avatar'
|
||||
import type { PopperOptions } from '../../types'
|
||||
@@ -73,7 +74,8 @@ export default defineComponent({
|
||||
MenuItems,
|
||||
MenuItem,
|
||||
UIcon,
|
||||
UAvatar
|
||||
UAvatar,
|
||||
UKbd
|
||||
},
|
||||
props: {
|
||||
items: {
|
||||
|
||||
44
src/runtime/components/elements/Kbd.vue
Normal file
44
src/runtime/components/elements/Kbd.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<kbd :class="[ui.base, ui.size[size], ui.spacing, ui.rounded, ui.font, ui.background, ui.ring]">
|
||||
<slot />
|
||||
</kbd>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import { useAppConfig } from '#imports'
|
||||
// TODO: Remove
|
||||
// @ts-expect-error
|
||||
import appConfig from '#build/app.config'
|
||||
|
||||
// const appConfig = useAppConfig()
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: () => appConfig.ui.kbd.default.size,
|
||||
validator (value: string) {
|
||||
return Object.keys(appConfig.ui.kbd.size).includes(value)
|
||||
}
|
||||
},
|
||||
ui: {
|
||||
type: Object as PropType<Partial<typeof appConfig.ui.kbd>>,
|
||||
default: () => appConfig.ui.kbd
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
// TODO: Remove
|
||||
const appConfig = useAppConfig()
|
||||
|
||||
const ui = computed<Partial<typeof appConfig.ui.kbd>>(() => defu({}, props.ui, appConfig.ui.kbd))
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
ui
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -45,7 +45,7 @@
|
||||
</slot>
|
||||
<slot v-else :name="`${group.key}-inactive`" :group="group" :command="command">
|
||||
<span v-if="command.shortcuts?.length" :class="ui.group.command.shortcuts">
|
||||
<kbd v-for="shortcut of command.shortcuts" :key="shortcut" class="font-sans">{{ shortcut }}</kbd>
|
||||
<UKbd v-for="shortcut of command.shortcuts" :key="shortcut">{{ shortcut }}</UKbd>
|
||||
</span>
|
||||
<span v-else-if="!command.disabled && group.inactive" :class="ui.group.inactive">{{ group.inactive }}</span>
|
||||
</slot>
|
||||
@@ -61,6 +61,7 @@ import type { PropType } from 'vue'
|
||||
import { ComboboxOption } from '@headlessui/vue'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
import UAvatar from '../elements/Avatar.vue'
|
||||
import UKbd from '../elements/Kbd.vue'
|
||||
import type { Group } from '../../types/command-palette'
|
||||
// TODO: Remove
|
||||
// @ts-expect-error
|
||||
@@ -72,7 +73,8 @@ export default defineComponent({
|
||||
components: {
|
||||
ComboboxOption,
|
||||
UIcon,
|
||||
UAvatar
|
||||
UAvatar,
|
||||
UKbd
|
||||
},
|
||||
props: {
|
||||
group: {
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
</slot>
|
||||
|
||||
<span v-if="shortcuts?.length" :class="ui.shortcuts">
|
||||
<span class="mr-1 text-gray-700 dark:text-gray-200">·</span>
|
||||
<kbd v-for="shortcut of shortcuts" :key="shortcut" class="flex items-center justify-center font-sans px-1 h-4 min-w-[16px] text-[10px] bg-gray-100 dark:bg-gray-800 rounded text-gray-900 dark:text-white">
|
||||
<span class="mx-1 text-gray-700 dark:text-gray-200">·</span>
|
||||
<UKbd v-for="shortcut of shortcuts" :key="shortcut" size="xs">
|
||||
{{ shortcut }}
|
||||
</kbd>
|
||||
</Ukbd>
|
||||
</span>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -27,6 +27,7 @@
|
||||
import { computed, ref, defineComponent } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import UKbd from '../elements/Kbd.vue'
|
||||
import { usePopper } from '../../composables/usePopper'
|
||||
import type { PopperOptions } from '../../types'
|
||||
import { useAppConfig } from '#imports'
|
||||
@@ -37,6 +38,9 @@ import appConfig from '#build/app.config'
|
||||
// const appConfig = useAppConfig()
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
UKbd
|
||||
},
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
|
||||
Reference in New Issue
Block a user