Files
chad/new-client/src/shared/components/ui/Button.vue

167 lines
2.9 KiB
Vue

<template>
<button
:class="[
bem.b(),
bem.exp(!!type, bem.m(`type_${type!}`)),
bem.exp(!!size, bem.m(`size_${size!}`)),
bem.is('icon-only', iconOnly),
bem.is('loading', loading),
bem.is('disabled', disabled),
bem.is('full', full),
]"
:disabled="disabled"
:type="nativeType"
>
<!-- <ChadSpinner v-if="loading" class="chad-button__spinner" /> -->
<!-- <template v-else> -->
<Component :is="icon" v-if="icon" :class="bem.e('icon')" />
<span v-if="$slots.default">
<slot />
</span>
<!-- </template> -->
</button>
</template>
<script setup lang="ts">
import type { Component } from 'vue'
import useBem from '@shared/composables/use-bem.ts'
import { computed, useSlots } from 'vue'
defineOptions({
name: 'ChadButton',
})
const props = withDefaults(
defineProps<ChadButtonProps>(),
{
nativeType: 'button',
},
)
export interface ChadButtonProps {
loading?: boolean
disabled?: boolean
type?: 'secondary' | 'danger'
nativeType?: 'button' | 'submit'
icon?: Component
full?: boolean
size?: 'sm' | 'lg'
}
const slots = useSlots()
const bem = useBem('chad-button')
const iconOnly = computed(() => {
return !slots.default && props.icon
})
</script>
<style lang="scss">
.chad-button {
$self: &;
@include font-display-14;
flex-shrink: 0;
border: none;
color: var(--ink);
padding: 0 var(--space-3);
height: 36px;
background-color: var(--yellow);
font-weight: 700;
text-align: center;
cursor: pointer;
outline: var(--border-w) solid var(--ink);
outline-offset: calc(var(--border-w) * -1);
&.is-full:not(.is-icon-only) {
width: 100%;
}
&.is-icon-only {
padding: 0;
aspect-ratio: 1;
}
&:not(:disabled) {
&:hover,
&:focus {
background-color: var(--yellow-deep);
}
&:active {
background-color: var(--ink);
color: var(--yellow);
}
}
&--size_sm {
@include font-body-bold;
height: 28px;
outline-width: 1px;
outline-offset: -1px;
}
&--size_lg {
height: 44px;
}
&--type_secondary {
background-color: var(--paper);
&:not(:disabled) {
&:hover,
&:focus {
background-color: var(--grey-2);
}
&:active {
background-color: var(--yellow);
color: var(--ink);
}
}
}
&--type_danger {
outline-color: var(--red);
background-color: var(--paper);
color: var(--red);
&:not(:disabled) {
&:hover,
&:focus,
&:active {
background-color: var(--red);
color: var(--white);
}
}
}
&:disabled {
cursor: not-allowed;
opacity: 0.6;
}
&.is-loading {
--stripe-width: 44px;
@include diagonal-stripes;
pointer-events: none;
}
&__icon {
&:not(:last-child) {
margin-right: var(--space-1);
}
#{$self}--size_sm & {
width: 16px;
}
}
}
</style>