|
| 1 | +<template> |
| 2 | + <template v-if="href || type === 'link'"> |
| 3 | + <a |
| 4 | + :href="href" |
| 5 | + class="flex gap-3 w-fit cursor-pointer group" |
| 6 | + :class="type === 'link' ? underlineHover : 'no-underline'" |
| 7 | + :target="target" |
| 8 | + @click="handleClick" |
| 9 | + > |
| 10 | + <Button |
| 11 | + :label="label" |
| 12 | + :size="size" |
| 13 | + :icon="icon" |
| 14 | + :class="buttonClasses" |
| 15 | + :pt="{ |
| 16 | + icon: { |
| 17 | + class: iconClasses |
| 18 | + }, |
| 19 | + label: { |
| 20 | + class: labelClasses |
| 21 | + } |
| 22 | + }" |
| 23 | + /> |
| 24 | + |
| 25 | + <span v-if="type === 'link'"> |
| 26 | + <svg |
| 27 | + width="10" |
| 28 | + height="10" |
| 29 | + :class="[ |
| 30 | + 'group-hover:translate-x-[.1rem] -translate-x-[.1rem] transition-transform relative', |
| 31 | + target === '_blank' |
| 32 | + ? 'translate-y-0 group-hover:translate-y-[-50%] top-[20%]' |
| 33 | + : 'rotate-45 -translate-y-1/2 top-1/2' |
| 34 | + ]" |
| 35 | + viewBox="0 0 10 10" |
| 36 | + fill="none" |
| 37 | + xmlns="http://www.w3.org/2000/svg" |
| 38 | + > |
| 39 | + <path |
| 40 | + d="M7.32201 8.20812L7.31425 4.45914C7.31425 4.39704 7.29873 4.35047 7.26768 4.31943C7.22111 4.27285 7.15642 4.29096 7.07363 4.37376L3.40226 8.04512C3.20046 8.24693 2.96243 8.35043 2.68817 8.3556C2.41392 8.35043 2.17071 8.24176 1.95856 8.0296C1.76192 7.83297 1.6636 7.59494 1.6636 7.31551C1.6636 7.03608 1.76192 6.79805 1.95856 6.60142L5.58335 2.97662C5.66614 2.89383 5.68684 2.83173 5.64545 2.79034C5.6144 2.75929 5.56783 2.74376 5.50573 2.74376L1.78003 2.74376C1.51095 2.74376 1.2781 2.64545 1.08146 2.44881C0.88483 2.25218 0.7891 2.00639 0.794275 1.71144C0.804624 1.41131 0.910703 1.16034 1.11251 0.958533C1.30397 0.767074 1.53941 0.671344 1.81884 0.671344L8.16806 0.671344C8.49923 0.619598 8.79677 0.725677 9.06067 0.989581C9.27283 1.20174 9.37891 1.44753 9.37891 1.72696L9.38667 8.20812C9.38667 8.4772 9.278 8.72041 9.06067 8.93774C8.84851 9.1499 8.6079 9.25598 8.33882 9.25598C8.06974 9.24563 7.82912 9.13437 7.61696 8.92222C7.42033 8.72558 7.32201 8.48755 7.32201 8.20812Z" |
| 41 | + fill="#FE601F" |
| 42 | + /> |
| 43 | + </svg> |
| 44 | + </span> |
| 45 | + </a> |
| 46 | + </template> |
| 47 | + <template v-else> |
| 48 | + <Button |
| 49 | + :label="label" |
| 50 | + :size="size" |
| 51 | + :icon="icon" |
| 52 | + @click="handleClick" |
| 53 | + :class="buttonClasses" |
| 54 | + :pt="{ |
| 55 | + icon: { |
| 56 | + class: iconClasses |
| 57 | + }, |
| 58 | + label: { |
| 59 | + class: labelClasses |
| 60 | + } |
| 61 | + }" |
| 62 | + /> |
| 63 | + </template> |
| 64 | +</template> |
| 65 | + |
| 66 | +<script setup> |
| 67 | + import Button from 'primevue/button' |
| 68 | + import { computed } from 'vue' |
| 69 | + // import { getAnalytics } from '@azion/tracker' |
| 70 | +
|
| 71 | + const emit = defineEmits(['click']) |
| 72 | +
|
| 73 | + const props = defineProps({ |
| 74 | + label: String, |
| 75 | + size: { |
| 76 | + type: String, |
| 77 | + options: ['small', 'large'], |
| 78 | + default: 'large' |
| 79 | + }, |
| 80 | + type: { |
| 81 | + type: String, |
| 82 | + options: ['primary', 'secondary', 'link'], |
| 83 | + default: 'secondary' |
| 84 | + }, |
| 85 | + href: String, |
| 86 | + icon: String, |
| 87 | + target: { |
| 88 | + type: String, |
| 89 | + default: '_self', |
| 90 | + options: ['_blank', '_self'] |
| 91 | + }, |
| 92 | + location: { |
| 93 | + required: false, |
| 94 | + type: String, |
| 95 | + default: 'cta' |
| 96 | + } |
| 97 | + }) |
| 98 | +
|
| 99 | + const underlineHover = computed(() => { |
| 100 | + const underlineBase = |
| 101 | + "relative after:duration-150 hover:after:w-full group-hover:after:w-full after:left-0 after:w-0 after:h-[1px] after:transition-all after:content-[\'\'] after:absolute after:-bottom-[.1rem]" |
| 102 | +
|
| 103 | + return `${underlineBase} after:bg-neutral-200` |
| 104 | + }) |
| 105 | +
|
| 106 | + const buttonClasses = computed(() => { |
| 107 | + const focusOverride = |
| 108 | + 'focus:outline-none focus:ring-0 focus:shadow-none focus-visible:outline-none focus-visible:ring-0 focus-visible:shadow-none' |
| 109 | +
|
| 110 | + const styles = { |
| 111 | + // Primary: estilo light (fundo claro) |
| 112 | + primary: `h-fit group px-3 py-3 border-1 border-neutral-100 bg-neutral-100 text-neutral-900 duration-300 transition rounded-md hover:bg-orange-500 hover:border-orange-500 hover:text-neutral-900 ${focusOverride}`, |
| 113 | +
|
| 114 | + // Secondary: estilo dark (fundo escuro) |
| 115 | + secondary: `h-fit group px-3 py-3 bg-neutral-900 text-neutral-100 duration-300 transition rounded-md active:bg-neutral-900 border-1 border-neutral-800 hover:bg-neutral-950 hover:text-orange-500 ${focusOverride}`, |
| 116 | +
|
| 117 | + // Link: estilo neutro |
| 118 | + link: `w-fit px-0 py-0 !leading-[.75rem] bg-transparent border-none text-neutral-200 ${focusOverride}` |
| 119 | + } |
| 120 | +
|
| 121 | + return styles[props.type] |
| 122 | + }) |
| 123 | +
|
| 124 | + const iconClasses = computed(() => { |
| 125 | + const baseClasses = '!text-[.75rem] duration-300 transition flex items-center mr-2' |
| 126 | +
|
| 127 | + const styles = { |
| 128 | + // Primary: estilo light |
| 129 | + primary: `h-fit ${baseClasses} text-neutral-900 group-hover:text-white`, |
| 130 | +
|
| 131 | + // Secondary: estilo dark |
| 132 | + secondary: `h-fit ${baseClasses} text-neutral-100 group-hover:text-neutral-100`, |
| 133 | +
|
| 134 | + // Link |
| 135 | + link: `${baseClasses} text-orange-600 hover:text-orange-600 leading-1` |
| 136 | + } |
| 137 | +
|
| 138 | + return styles[props.type] |
| 139 | + }) |
| 140 | +
|
| 141 | + const labelClasses = computed(() => { |
| 142 | + const leading = props.size === 'large' ? 'text-sm leading-[1.5rem]' : 'leading-[1rem]' |
| 143 | +
|
| 144 | + const fontSize = props.size === 'small' ? 'text-xs' : '' |
| 145 | +
|
| 146 | + const styles = { |
| 147 | + primary: `font-proto-mono ${leading} whitespace-nowrap`, |
| 148 | + secondary: `font-proto-mono ${leading} whitespace-nowrap`, |
| 149 | + link: `font-proto-mono ${leading} ${fontSize} after:bg-neutral-900 whitespace-nowrap` |
| 150 | + } |
| 151 | +
|
| 152 | + return styles[props.type] |
| 153 | + }) |
| 154 | +
|
| 155 | + const handleClick = (event) => { |
| 156 | + emit('click', event) |
| 157 | + } |
| 158 | +</script> |
0 commit comments