-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Expand file tree
/
Copy pathsba-button.vue
More file actions
152 lines (133 loc) · 3.21 KB
/
sba-button.vue
File metadata and controls
152 lines (133 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<template>
<component
:is="as"
class="btn items-center"
v-bind="componentAttrs"
@click="handleClick"
>
<slot />
</component>
</template>
<script setup>
import classNames from 'classnames';
import { computed, useAttrs } from 'vue';
const props = defineProps({
title: {
type: String,
default: '',
},
as: {
type: String,
default: 'button',
validator(value) {
return ['a', 'button'].includes(value);
},
},
href: {
type: String,
default: null,
},
size: {
type: String,
default: 'sm',
validator(value) {
return ['2xs', 'xs', 'sm', 'base'].includes(value);
},
},
disabled: {
type: Boolean,
default: false,
},
primary: {
type: Boolean,
default: false,
},
});
const attrs = useAttrs();
const cssClasses = computed(() => {
return {
'px-1 py-0 text-xs': props.size === '2xs',
'px-2 py-2 text-xs': props.size === 'xs',
'px-3 py-2': props.size === 'sm',
'px-4 py-3': props.size === 'base',
'px-5 py-2.5': props.size === '',
// Types
'is-primary': props.primary === true,
};
});
const componentAttrs = computed(() => {
const common = {
...attrs,
title: props.title,
class: classNames(attrs.class, cssClasses.value),
};
if (props.as === 'a') {
return {
...common,
href: props.href,
};
}
if (props.as === 'button') {
return {
...common,
disabled: props.disabled === true,
type: props.type,
};
}
return {};
});
const emit = defineEmits(['click']);
const handleClick = (event) => {
if (props.as === 'button') {
emit('click', event);
}
if (props.as === 'a') {
event.stopPropagation();
}
};
</script>
<style scoped>
.btn {
@apply rounded-l rounded-r font-medium text-sm text-center text-black border-gray-300 border bg-white;
@apply focus:ring-2 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500;
@apply hover:bg-gray-100;
}
.btn:disabled {
@apply text-gray-500 cursor-not-allowed bg-gray-100 hover:bg-gray-100;
}
.btn.is-danger {
@apply text-white bg-red-600 hover:bg-red-700 focus:ring-red-300;
}
.btn.is-warning {
@apply focus:outline-none text-gray-700 bg-yellow-400 hover:bg-yellow-500 focus:ring-yellow-300 font-medium text-sm;
}
.btn.is-info {
@apply text-white bg-blue-700 hover:bg-blue-800 focus:ring-blue-300 font-medium text-sm focus:outline-none;
}
.btn.is-success {
@apply text-white bg-green-700 hover:bg-green-800 focus:ring-green-300 font-medium text-sm focus:outline-none;
}
.btn.is-light {
@apply text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-gray-200 font-medium text-sm;
&.is-active {
@apply bg-gray-300;
}
}
.btn.is-extra-light {
@apply text-white bg-gray-500 hover:bg-gray-400 focus:outline-none focus:ring-gray-300 font-medium text-sm;
&.is-active {
@apply bg-gray-400;
}
}
.btn.is-black {
@apply text-white bg-gray-800 hover:bg-gray-900 focus:outline-none focus:ring-gray-300 font-medium text-sm;
}
.btn.is-primary {
@apply text-white bg-blue-600 hover:bg-blue-700 focus:ring-blue-300;
}
@supports (-moz-appearance: none) {
.backdrop-filter.bg-opacity-40 {
--tw-bg-opacity: 1 !important;
}
}
</style>