2025-04-26 18:09:58 -07:00
|
|
|
<template>
|
2025-08-14 21:48:38 +01:00
|
|
|
<div class="smart-clickable" :class="{ 'smart-clickable--has-clickable': !!$slots.clickable }">
|
|
|
|
|
<slot name="clickable" />
|
2026-02-07 12:05:59 -08:00
|
|
|
<div
|
|
|
|
|
v-bind="$attrs"
|
|
|
|
|
class="smart-clickable__contents"
|
|
|
|
|
:class="{
|
|
|
|
|
'pointer-events-none': !!$slots.clickable,
|
|
|
|
|
}"
|
|
|
|
|
>
|
2025-08-14 21:48:38 +01:00
|
|
|
<slot />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-04-26 18:09:58 -07:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
defineOptions({
|
2025-08-14 21:48:38 +01:00
|
|
|
inheritAttrs: false,
|
2025-04-26 18:09:58 -07:00
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
.smart-clickable {
|
2025-08-14 21:48:38 +01:00
|
|
|
display: grid;
|
|
|
|
|
|
|
|
|
|
> * {
|
|
|
|
|
grid-area: 1 / 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.smart-clickable__contents {
|
|
|
|
|
// Utility classes for contents
|
|
|
|
|
:deep(.smart-clickable\:allow-pointer-events) {
|
|
|
|
|
pointer-events: all;
|
|
|
|
|
}
|
2026-02-08 17:59:00 -07:00
|
|
|
|
|
|
|
|
:deep(.ease-brightness) {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transition: opacity 0.125s ease-out;
|
|
|
|
|
}
|
2025-08-14 21:48:38 +01:00
|
|
|
}
|
2025-04-26 18:09:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only apply effects when a clickable is present
|
|
|
|
|
.smart-clickable.smart-clickable--has-clickable {
|
2025-08-14 21:48:38 +01:00
|
|
|
// Setup base styles for contents
|
|
|
|
|
.smart-clickable__contents {
|
|
|
|
|
transition: scale 0.125s ease-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When clickable is being hovered or focus-visible, give contents an effect
|
2026-02-07 11:18:59 -08:00
|
|
|
:first-child:hover + .smart-clickable__contents,
|
2026-05-11 15:39:09 -06:00
|
|
|
:first-child:focus-visible + .smart-clickable__contents,
|
|
|
|
|
.smart-clickable__contents:hover,
|
|
|
|
|
.smart-clickable__contents:focus-within {
|
2025-08-14 21:48:38 +01:00
|
|
|
// Utility classes for contents
|
|
|
|
|
:deep(.smart-clickable\:underline-on-hover) {
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
}
|
|
|
|
|
:deep(.smart-clickable\:highlight-on-hover) {
|
|
|
|
|
filter: brightness(var(--hover-brightness, 1.25));
|
|
|
|
|
}
|
2026-02-08 17:01:23 -08:00
|
|
|
:deep(.smart-clickable\:surface-4-on-hover) {
|
|
|
|
|
@apply bg-surface-4;
|
|
|
|
|
}
|
|
|
|
|
:deep(.smart-clickable\:surface-5-on-hover) {
|
|
|
|
|
@apply bg-surface-5;
|
|
|
|
|
}
|
2026-02-08 17:59:00 -07:00
|
|
|
:deep(.ease-brightness) {
|
|
|
|
|
opacity: 0.85;
|
|
|
|
|
transition: opacity 0.125s ease-out;
|
|
|
|
|
}
|
2025-08-14 21:48:38 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-07 11:18:59 -08:00
|
|
|
:first-child:focus-visible + .smart-clickable__contents {
|
|
|
|
|
// Utility classes for contents
|
|
|
|
|
:deep(.smart-clickable\:outline-on-focus) {
|
|
|
|
|
outline: 0.25rem solid var(--color-focus-ring);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 21:48:38 +01:00
|
|
|
// When clickable is being clicked, give contents an effect
|
2026-02-07 11:18:59 -08:00
|
|
|
:first-child:active + .smart-clickable__contents {
|
2025-08-14 21:48:38 +01:00
|
|
|
scale: 0.97;
|
|
|
|
|
}
|
2025-04-26 18:09:58 -07:00
|
|
|
}
|
|
|
|
|
</style>
|