Skip to content

Commit f336600

Browse files
authored
feat(Kbd): add color prop & soft variant (#4549)
1 parent 657ec22 commit f336600

15 files changed

Lines changed: 479 additions & 403 deletions

File tree

docs/content/3.components/kbd.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,27 @@ items:
6262
---
6363
::
6464

65+
### Color :badge{label="Soon" class="align-text-top"}
66+
67+
Use the `color` prop to change the color of the Kbd.
68+
69+
::component-code
70+
---
71+
props:
72+
color: neutral
73+
slots:
74+
default: K
75+
---
76+
::
77+
6578
### Variant
6679

6780
Use the `variant` prop to change the variant of the Kbd.
6881

6982
::component-code
7083
---
7184
props:
85+
color: neutral
7286
variant: solid
7387
slots:
7488
default: K

playground/app/pages/components/kbd.vue

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,16 @@ import theme from '#build/ui/kbd'
33
import { kbdKeysMap } from '@nuxt/ui/composables/useKbd.js'
44
55
const sizes = Object.keys(theme.variants.size) as Array<keyof typeof theme.variants.size>
6+
const variants = Object.keys(theme.variants.variant) as Array<keyof typeof theme.variants.variant>
7+
const colors = Object.keys(theme.variants.color) as Array<keyof typeof theme.variants.color>
68
79
const kbdKeys = Object.keys(kbdKeysMap)
810
</script>
911

1012
<template>
1113
<div class="flex flex-col gap-2">
12-
<div class="flex items-center gap-1">
13-
<UKbd value="meta" />
14-
</div>
15-
<div class="flex items-center gap-1">
16-
<UKbd value="meta" variant="subtle" />
17-
</div>
18-
<div class="flex items-center gap-1">
19-
<UKbd value="meta" variant="solid" />
14+
<div v-for="color in colors" :key="color" class="flex items-center gap-1 ms-[-22px]">
15+
<UKbd v-for="variant in variants" :key="`${color}-${variant}`" value="meta" :variant="variant" :color="color" />
2016
</div>
2117
<div class="flex items-center gap-1 ms-[-220px]">
2218
<UKbd v-for="(kdbKey, index) in kbdKeys" :key="index" :value="kdbKey" />

src/runtime/components/Kbd.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export interface KbdProps {
1313
*/
1414
as?: any
1515
value?: KbdKey | string
16+
/**
17+
* @defaultValue 'neutral'
18+
*/
19+
color?: Kbd['variants']['color']
1620
/**
1721
* @defaultValue 'outline'
1822
*/
@@ -48,7 +52,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.kbd || {}) }
4852
</script>
4953

5054
<template>
51-
<Primitive :as="as" :class="ui({ variant, size, class: props.class })">
55+
<Primitive :as="as" :class="ui({ class: props.class, color: props.color, variant: props.variant, size: props.size })">
5256
<slot>
5357
{{ getKbdKey(value) }}
5458
</slot>

src/theme/kbd.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,60 @@
1-
export default {
1+
import type { ModuleOptions } from '../module'
2+
3+
export default (options: Required<ModuleOptions>) => ({
24
base: 'inline-flex items-center justify-center px-1 rounded-sm font-medium font-sans',
35
variants: {
6+
color: {
7+
...Object.fromEntries((options.theme.colors || []).map((color: string) => [color, ''])),
8+
neutral: ''
9+
},
410
variant: {
5-
solid: 'bg-inverted text-inverted',
6-
outline: 'bg-default text-highlighted ring ring-inset ring-accented',
7-
subtle: 'bg-elevated text-default ring ring-inset ring-accented'
11+
solid: '',
12+
outline: '',
13+
soft: '',
14+
subtle: ''
815
},
916
size: {
1017
sm: 'h-4 min-w-[16px] text-[10px]',
1118
md: 'h-5 min-w-[20px] text-[11px]',
1219
lg: 'h-6 min-w-[24px] text-[12px]'
1320
}
1421
},
22+
compoundVariants: [...(options.theme.colors || []).map((color: string) => ({
23+
color,
24+
variant: 'solid',
25+
class: `text-inverted bg-${color}`
26+
})), ...(options.theme.colors || []).map((color: string) => ({
27+
color,
28+
variant: 'outline',
29+
class: `ring ring-inset ring-${color}/50 text-${color}`
30+
})), ...(options.theme.colors || []).map((color: string) => ({
31+
color,
32+
variant: 'soft',
33+
class: `text-${color} bg-${color}/10`
34+
})), ...(options.theme.colors || []).map((color: string) => ({
35+
color,
36+
variant: 'subtle',
37+
class: `text-${color} ring ring-inset ring-${color}/25 bg-${color}/10`
38+
})), {
39+
color: 'neutral',
40+
variant: 'solid',
41+
class: 'text-inverted bg-inverted'
42+
}, {
43+
color: 'neutral',
44+
variant: 'outline',
45+
class: 'ring ring-inset ring-accented text-default bg-default'
46+
}, {
47+
color: 'neutral',
48+
variant: 'soft',
49+
class: 'text-default bg-elevated'
50+
}, {
51+
color: 'neutral',
52+
variant: 'subtle',
53+
class: 'ring ring-inset ring-accented text-default bg-elevated'
54+
}],
1555
defaultVariants: {
1656
variant: 'outline',
57+
color: 'neutral',
1758
size: 'md'
1859
}
19-
}
60+
})

test/components/Kbd.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ describe('Kbd', () => {
1212
// Props
1313
['with value', { props: { value: 'K' } }],
1414
...sizes.map((size: string) => [`with size ${size}`, { props: { value: 'K', size } }]),
15-
...variants.map((variant: string) => [`with variant ${variant}`, { props: { value: 'K', variant } }]),
15+
...variants.map((variant: string) => [`with primary variant ${variant}`, { props: { value: 'K', variant } }]),
16+
...variants.map((variant: string) => [`with neutral variant ${variant}`, { props: { value: 'K', variant, color: 'neutral' } }]),
1617
['with as', { props: { value: 'K', as: 'span' } }],
1718
['with class', { props: { value: 'K', class: 'font-bold' } }],
1819
// Slots

test/components/__snapshots__/CommandPalette-vue.spec.ts.snap

Lines changed: 85 additions & 85 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)