forked from npmx-dev/npmx.dev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBase.vue
More file actions
76 lines (70 loc) · 2.42 KB
/
Base.vue
File metadata and controls
76 lines (70 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<script setup lang="ts">
import { ClientOnly } from '#components'
import type { IconClass } from '~/types'
const props = withDefaults(
defineProps<{
disabled?: boolean
/** @default "button" */
type?: 'button' | 'submit'
/** @default "secondary" */
variant?: 'primary' | 'secondary'
/** @default "medium" */
size?: 'small' | 'medium'
/** Keyboard shortcut hint */
ariaKeyshortcuts?: string
/** Forces the button to occupy the entire width of its container. */
block?: boolean
classicon?: IconClass
}>(),
{
type: 'button',
variant: 'secondary',
size: 'medium',
},
)
const el = useTemplateRef('el')
const keyboardShortcutsEnabled = computed(() => import.meta.client && useKeyboardShortcuts().value)
defineExpose({
focus: () => el.value?.focus(),
getBoundingClientRect: () => el.value?.getBoundingClientRect(),
})
</script>
<template>
<button
ref="el"
class="group gap-x-1 items-center justify-center font-mono border border-border rounded-md transition-all duration-200 disabled:(opacity-40 cursor-not-allowed border-transparent)"
:class="{
'inline-flex': !block,
'flex': block,
'text-sm px-4 py-2': size === 'medium',
'text-xs px-2 py-0.5': size === 'small',
'bg-transparent text-fg hover:enabled:(bg-fg/10) focus-visible:enabled:(bg-fg/10) aria-pressed:(bg-fg/10 border-fg/20 hover:enabled:(bg-fg/20 text-fg/50))':
variant === 'secondary',
'text-bg bg-fg hover:enabled:(bg-fg/50) focus-visible:enabled:(bg-fg/50) aria-pressed:(bg-fg text-bg border-fg hover:enabled:(text-bg/50))':
variant === 'primary',
}"
:type="props.type"
:disabled="
/**
* Unfortunately Vue _sometimes_ doesn't handle `disabled` correct,
* resulting in an invalid `disabled=false` attribute in the final HTML.
*
* This fixes this.
*/
disabled ? true : undefined
"
:aria-keyshortcuts="keyboardShortcutsEnabled ? ariaKeyshortcuts : undefined"
>
<span v-if="classicon" class="size-[1em]" :class="classicon" aria-hidden="true" />
<slot />
<ClientOnly>
<kbd
v-if="keyboardShortcutsEnabled && ariaKeyshortcuts"
class="ms-2 inline-flex items-center justify-center w-4 h-4 text-xs text-fg bg-bg-muted border border-border rounded no-underline"
aria-hidden="true"
>
{{ ariaKeyshortcuts }}
</kbd>
</ClientOnly>
</button>
</template>