
Before this change, the filter button on the top right was positioned using absolute positioning and plenty of tricks, which were brittle and not really maintainable. Now, the buttons are positioned using flexbox, which should make this a lot more maintainable.
120 lines
2.3 KiB
Vue
120 lines
2.3 KiB
Vue
<template>
|
|
<BaseButton
|
|
class="button"
|
|
:class="[
|
|
variantClass,
|
|
{
|
|
'is-loading': loading,
|
|
'has-no-shadow': !shadow || variant === 'tertiary',
|
|
}
|
|
]"
|
|
:style="{
|
|
'--button-white-space': wrap ? 'break-spaces' : 'nowrap',
|
|
}"
|
|
>
|
|
<template v-if="icon">
|
|
<icon
|
|
v-if="showIconOnly"
|
|
:icon="icon"
|
|
:style="{'color': iconColor !== '' ? iconColor : undefined}"
|
|
/>
|
|
<span
|
|
v-else
|
|
class="icon is-small"
|
|
>
|
|
<icon
|
|
:icon="icon"
|
|
:style="{'color': iconColor !== '' ? iconColor : undefined}"
|
|
/>
|
|
</span>
|
|
</template>
|
|
<slot/>
|
|
</BaseButton>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
const BUTTON_TYPES_MAP = {
|
|
primary: 'is-primary',
|
|
secondary: 'is-outlined',
|
|
tertiary: 'is-text is-inverted underline-none',
|
|
} as const
|
|
|
|
export type ButtonTypes = keyof typeof BUTTON_TYPES_MAP
|
|
|
|
export default {name: 'XButton'}
|
|
</script>
|
|
|
|
<script setup lang="ts">
|
|
import {computed, useSlots} from 'vue'
|
|
import BaseButton, {type BaseButtonProps} from '@/components/base/BaseButton.vue'
|
|
import type {IconProp} from '@fortawesome/fontawesome-svg-core'
|
|
|
|
// extending the props of the BaseButton
|
|
export interface ButtonProps extends /* @vue-ignore */ BaseButtonProps {
|
|
variant?: ButtonTypes
|
|
icon?: IconProp
|
|
iconColor?: string
|
|
loading?: boolean
|
|
shadow?: boolean
|
|
wrap?: boolean
|
|
}
|
|
|
|
const {
|
|
variant = 'primary',
|
|
icon = '',
|
|
iconColor = '',
|
|
loading = false,
|
|
shadow = true,
|
|
wrap = true,
|
|
} = defineProps<ButtonProps>()
|
|
|
|
const variantClass = computed(() => BUTTON_TYPES_MAP[variant])
|
|
|
|
const slots = useSlots()
|
|
const showIconOnly = computed(() => icon !== '' && typeof slots.default === 'undefined')
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.button {
|
|
transition: all $transition;
|
|
border: 0;
|
|
text-transform: uppercase;
|
|
font-size: 0.85rem;
|
|
font-weight: bold;
|
|
height: auto;
|
|
min-height: $button-height;
|
|
box-shadow: var(--shadow-sm);
|
|
display: inline-flex;
|
|
white-space: var(--button-white-space);
|
|
line-height: 1;
|
|
|
|
&:hover {
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
&.fullheight {
|
|
padding-right: 7px;
|
|
height: 100%;
|
|
}
|
|
|
|
&.is-active,
|
|
&.is-focused,
|
|
&:active,
|
|
&:focus,
|
|
&:focus:not(:active) {
|
|
box-shadow: var(--shadow-xs) !important;
|
|
}
|
|
|
|
&.is-primary.is-outlined:hover {
|
|
color: var(--white);
|
|
}
|
|
}
|
|
|
|
.is-small {
|
|
border-radius: $radius;
|
|
}
|
|
|
|
.underline-none {
|
|
text-decoration: none !important;
|
|
}
|
|
</style> |