detail page port

This commit is contained in:
nicwands
2026-05-29 11:22:56 -04:00
parent b85d28c142
commit e22d75c50a
65 changed files with 7006 additions and 4044 deletions

View File

@@ -1,32 +1,165 @@
<template>
<component :is="tag" class="btn">
<svg-btn-outline />
<component
:class="[`btn p-xs size-${size}`, { secondary, number, hover }]"
:is="component"
:href="href"
:field="linkField"
>
<span class="text" v-if="linkField">
<span>{{ linkField.text }}</span>
<span>{{ linkField.text }}</span>
</span>
<span class="text" v-else-if="slots.default">
<span><slot /></span>
<span><slot /></span>
</span>
<slot />
<span v-if="loading" class="loading">
<svg-util-spinner />
</span>
</component>
</template>
<script setup>
import SvgBtnOutline from '@/components/svg/BtnOutline.vue'
import { useSlots, computed, resolveComponent } from 'vue'
import SvgUtilSpinner from '@/components/svg/util/Spinner.vue'
const props = defineProps({
tag: {
// Will render ADiv
href: [Object, String],
// Will render PrismicLink
linkField: Object,
tag: String,
size: {
type: String,
default: 'button',
default: () => 'small',
},
icon: {
type: String,
default: () => '',
},
secondary: {
type: Boolean,
default: () => false,
},
number: {
type: Boolean,
default: () => false,
},
loading: {
type: Boolean,
default: () => false,
},
hover: {
type: Boolean,
default: () => true,
},
})
const slots = useSlots()
const component = computed(() => {
if (props.tag) return props.tag
if (props.href) return 'a'
if (props.linkField) return resolveComponent('prismic-link')
return 'button'
})
</script>
<style lang="scss">
.btn {
text-transform: uppercase;
padding: desktop-vw(5px) desktop-vw(16px) desktop-vw(6px);
color: var(--grey-100);
display: inline-flex;
align-items: center;
justify-content: center;
padding: desktop-vw(5px) desktop-vw(20px);
border: 1px solid var(--theme-fg);
background: var(--theme-fg);
color: var(--theme-bg);
position: relative;
cursor: pointer;
transition:
color var(--td) var(--te),
background var(--td) var(--te);
@include text-flip(var(--td), var(--te));
&:hover {
color: var(--theme-accent);
@include mobile {
padding: mobile-vw(5px) mobile-vw(20px);
}
.text span {
display: block;
}
.loading {
position: absolute;
inset: 0;
background: inherit;
display: flex;
align-items: center;
svg {
width: 1em;
height: auto;
}
}
.icon {
margin-left: desktop-vw(6px);
width: desktop-vw(12px);
height: auto;
@include mobile {
margin-left: mobile-vw(6px);
width: mobile-vw(12px);
}
}
&.size-large {
font-size: desktop-vw(28px);
padding: desktop-vw(8.7px) desktop-vw(34.7px);
@include mobile {
font-size: mobile-vw(28px);
padding: mobile-vw(8.7px) mobile-vw(34.7px);
}
}
&.secondary {
background: var(--theme-bg);
color: var(--theme-fg);
}
&.number {
padding: desktop-vw(5px) desktop-vw(10px);
@include mobile {
padding: mobile-vw(5px) mobile-vw(10px);
}
}
&.hover {
&:hover,
&.active,
&.router-link-active,
&.router-link-exact-active {
color: var(--theme-fg);
background: var(--theme-bg);
&.secondary {
background: var(--theme-fg);
color: var(--theme-bg);
}
}
}
&:not(.hover) {
cursor: default;
}
&:disabled,
&.disabled {
opacity: 0.16;
pointer-events: none;
}
}
</style>