this repo has no description
at main 2.5 kB view raw
1<script setup lang="ts"> 2import { computed } from "vue"; 3 4const props = defineProps<{ 5 variant?: "default" | "accent" | "danger" | "ghost"; 6 size?: "sm" | "md" | "lg"; 7 disabled?: boolean; 8 type?: "button" | "submit" | "reset"; 9 url?: string; 10}>(); 11 12const emit = defineEmits<{ 13 click: [event: MouseEvent]; 14}>(); 15 16const urlIsExternal = computed(() => props.url?.startsWith("http")); 17</script> 18 19<template> 20 <Component 21 :is="url ? urlIsExternal ? 'a' : 'router-link' : 'button'" 22 :href="url" 23 :to="url && !urlIsExternal ? url : undefined" 24 :class="[ 25 'app-button', 26 `variant-${variant || 'default'}`, 27 `size-${size || 'md'}`, 28 { disabled } 29 ]" 30 :disabled="disabled" 31 :type="type || 'button'" 32 @click="emit('click', $event)" 33 > 34 <slot></slot> 35 </Component> 36</template> 37 38<style lang="scss" scoped> 39.app-button { 40 font-family: inherit; 41 border-radius: 0.375rem; 42 font-weight: 500; 43 display: inline-flex; 44 align-items: center; 45 justify-content: center; 46 transition: all 0.2s ease; 47 cursor: pointer; 48 border: 1px solid transparent; 49 50 &.variant-default { 51 background-color: hsl(var(--surface0)); 52 color: hsl(var(--text)); 53 54 &:hover:not(:disabled) { 55 background-color: hsl(var(--surface1)); 56 } 57 58 &:active:not(:disabled) { 59 background-color: hsl(var(--surface2)); 60 } 61 } 62 63 &.variant-accent { 64 background-color: hsl(var(--accent)); 65 color: hsl(var(--text-on-accent)); 66 67 &:hover:not(:disabled) { 68 opacity: 0.9; 69 } 70 71 &:active:not(:disabled) { 72 opacity: 0.8; 73 } 74 } 75 76 &.variant-danger { 77 background-color: hsl(var(--red)); 78 color: hsl(var(--crust)); 79 80 &:hover:not(:disabled) { 81 opacity: 0.9; 82 } 83 84 &:active:not(:disabled) { 85 opacity: 0.8; 86 } 87 } 88 89 &.variant-ghost { 90 background-color: transparent; 91 color: hsl(var(--text)); 92 93 &:hover:not(:disabled) { 94 background-color: hsla(var(--overlay0) / 0.2); 95 } 96 97 &:active:not(:disabled) { 98 background-color: hsla(var(--overlay0) / 0.3); 99 } 100 } 101 102 &:focus-visible { 103 outline: 2px solid hsl(var(--accent)); 104 outline-offset: 1px; 105 } 106 107 &:disabled { 108 opacity: 0.5; 109 cursor: not-allowed; 110 } 111 112 &.size-sm { 113 padding: 0.25rem 0.5rem; 114 font-size: 0.875rem; 115 } 116 117 &.size-md { 118 padding: 0.5rem 1rem; 119 font-size: 1rem; 120 } 121 122 &.size-lg { 123 padding: 0.75rem 1.5rem; 124 font-size: 1.125rem; 125 } 126} 127 128a { 129 text-decoration: none; 130} 131 132</style>