| 1 |
<template> |
| 2 |
<div> |
| 3 |
<el-link |
| 4 |
v-bind="linkAttrs" |
| 5 |
:underline="false" |
| 6 |
class="ivyforms-link" |
| 7 |
:class="`priority-${props.priority} size-${props.size} ${isPressed ? 'pressed' : ''} ${isUsed ? 'used' : ''}`" |
| 8 |
@click="handleClick" |
| 9 |
@mousedown="handleMouseDown" |
| 10 |
@mouseup="handleMouseUp" |
| 11 |
@mouseleave="handleMouseLeave" |
| 12 |
> |
| 13 |
<slot></slot> |
| 14 |
</el-link> |
| 15 |
</div> |
| 16 |
</template> |
| 17 |
|
| 18 |
<script setup lang="ts"> |
| 19 |
import { ref, computed } from 'vue' |
| 20 |
|
| 21 |
interface Props { |
| 22 |
href: string |
| 23 |
priority?: 'primary' | 'secondary' | 'amber' |
| 24 |
target?: '_blank' | '_self' |
| 25 |
rel?: 'noopener' | 'noreferrer' |
| 26 |
size?: 's' | 'd' |
| 27 |
onClick?: (event: Event) => void |
| 28 |
} |
| 29 |
|
| 30 |
const props = withDefaults(defineProps<Props>(), { |
| 31 |
priority: 'primary', |
| 32 |
target: '_blank', |
| 33 |
rel: 'noreferrer', |
| 34 |
size: 'd', |
| 35 |
href: '#', |
| 36 |
onClick: () => {}, |
| 37 |
}) |
| 38 |
|
| 39 |
const isPressed = ref(false) |
| 40 |
const isUsed = ref(false) |
| 41 |
|
| 42 |
// Computed properties for dynamic attributes |
| 43 |
const linkAttrs = computed(() => { |
| 44 |
return { |
| 45 |
href: props.href === '#' ? '' : props.href, // Prevent navigation if href is invalid |
| 46 |
target: props.target, |
| 47 |
rel: props.target === '_blank' ? props.rel : '', |
| 48 |
} |
| 49 |
}) |
| 50 |
|
| 51 |
// Handle click events |
| 52 |
const handleClick = (event: Event) => { |
| 53 |
if (props.href === '#' || !props.href) { |
| 54 |
event.preventDefault() // Prevent default navigation if href is invalid |
| 55 |
} else { |
| 56 |
isUsed.value = true // Mark as used after navigation |
| 57 |
} |
| 58 |
} |
| 59 |
|
| 60 |
// Handle mouse down event to detect pressed state |
| 61 |
const handleMouseDown = () => { |
| 62 |
isPressed.value = true |
| 63 |
} |
| 64 |
|
| 65 |
// Handle mouse up event to reset pressed state |
| 66 |
const handleMouseUp = () => { |
| 67 |
isPressed.value = false |
| 68 |
} |
| 69 |
|
| 70 |
// Handle mouse leave event to reset pressed state |
| 71 |
const handleMouseLeave = () => { |
| 72 |
isPressed.value = false |
| 73 |
} |
| 74 |
</script> |
| 75 |
<style lang="scss"> |
| 76 |
@use 'sass:list' as *; |
| 77 |
@use 'sass:meta' as *; |
| 78 |
// Radio |
| 79 |
.ivyforms-link { |
| 80 |
color: var(--map-base-dusk-symbol-2); |
| 81 |
text-align: center; |
| 82 |
|
| 83 |
font-family: Roboto; |
| 84 |
font-style: normal; |
| 85 |
font-weight: 500; |
| 86 |
|
| 87 |
&.size-s { |
| 88 |
font-size: 14px; |
| 89 |
line-height: 20px; |
| 90 |
} |
| 91 |
&.size-d { |
| 92 |
font-size: 16px; |
| 93 |
line-height: 22px; |
| 94 |
} |
| 95 |
|
| 96 |
&.el-link { |
| 97 |
border: none; |
| 98 |
color: var(--map-base-dusk-symbol-2); |
| 99 |
.el-link__inner { |
| 100 |
border: none; |
| 101 |
} |
| 102 |
} |
| 103 |
|
| 104 |
$priorities: ( |
| 105 |
'primary': ( |
| 106 |
var(--map-base-brand-symbol-0), |
| 107 |
var(--map-base-brand-symbol-1), |
| 108 |
), |
| 109 |
'secondary': ( |
| 110 |
var(--map-base-purple-symbol-0), |
| 111 |
var(--map-base-purple-symbol-1), |
| 112 |
), |
| 113 |
); |
| 114 |
|
| 115 |
// Function to process each priority value if is array |
| 116 |
@each $priority, $values in $priorities { |
| 117 |
&.priority-#{$priority} { |
| 118 |
&:hover { |
| 119 |
color: nth($values, 1); |
| 120 |
border: none; |
| 121 |
box-shadow: none; |
| 122 |
outline: none; |
| 123 |
} |
| 124 |
&.pressed { |
| 125 |
color: nth($values, 2); // For pressed state |
| 126 |
border: none; |
| 127 |
box-shadow: none; |
| 128 |
outline: none; |
| 129 |
} |
| 130 |
|
| 131 |
&.used { |
| 132 |
color: var(--map-base-dusk-symbol-0); // For used state |
| 133 |
border: none; |
| 134 |
box-shadow: none; |
| 135 |
outline: none; |
| 136 |
} |
| 137 |
} |
| 138 |
} |
| 139 |
} |
| 140 |
</style> |
| 141 |
|