@veritree/ui 0.89.5 → 0.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,53 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<!-- :href="href" -->
|
|
3
2
|
<component
|
|
4
3
|
:is="tag"
|
|
5
4
|
:to="to"
|
|
6
5
|
:href="href || to"
|
|
7
6
|
:type="type"
|
|
8
7
|
:disabled="isDisabled"
|
|
9
|
-
:class="
|
|
10
|
-
// default styles
|
|
11
|
-
headless ? 'button' : isIcon ? null : 'button-base',
|
|
12
|
-
// variant styles
|
|
13
|
-
headless
|
|
14
|
-
? `button--${variant}`
|
|
15
|
-
: isPrimary
|
|
16
|
-
? 'button--primary'
|
|
17
|
-
: isSecondary
|
|
18
|
-
? isGhost
|
|
19
|
-
? 'border-gray-500 text-gray-100 hover:bg-white hover:text-gray-700'
|
|
20
|
-
: 'button--secondary'
|
|
21
|
-
: isTertiary
|
|
22
|
-
? 'button--tertiary'
|
|
23
|
-
: isDark
|
|
24
|
-
? 'button--dark'
|
|
25
|
-
: isIcon
|
|
26
|
-
? 'button--icon'
|
|
27
|
-
: null,
|
|
28
|
-
// sizes styles
|
|
29
|
-
headless
|
|
30
|
-
? `button--${size}`
|
|
31
|
-
: isLarge
|
|
32
|
-
? isIcon
|
|
33
|
-
? 'h-8 w-8'
|
|
34
|
-
: 'button--large'
|
|
35
|
-
: isSmall
|
|
36
|
-
? isIcon
|
|
37
|
-
? 'h-6 w-6 p-1'
|
|
38
|
-
: 'button--small'
|
|
39
|
-
: null,
|
|
40
|
-
isDisabled ? (isIcon ? '[&_svg]:text-gray-400' : null) : null,
|
|
41
|
-
]"
|
|
8
|
+
:class="buttonClasses"
|
|
42
9
|
v-on="$listeners"
|
|
43
10
|
>
|
|
44
11
|
<VTSpinner v-if="busy" class="absolute inset-0 m-auto" />
|
|
45
|
-
<span
|
|
46
|
-
:class="[
|
|
47
|
-
headless ? null : 'mx-auto inline-flex items-center gap-2 self-center',
|
|
48
|
-
headless && busy ? 'button--busy' : busy ? 'invisible' : null,
|
|
49
|
-
]"
|
|
50
|
-
>
|
|
12
|
+
<span :class="spanClasses">
|
|
51
13
|
<!-- @slot Use this slot for the button content -->
|
|
52
14
|
<slot></slot>
|
|
53
15
|
</span>
|
|
@@ -78,6 +40,11 @@ export default {
|
|
|
78
40
|
variant: {
|
|
79
41
|
type: String,
|
|
80
42
|
default: 'primary',
|
|
43
|
+
validator(value) {
|
|
44
|
+
return ['primary', 'secondary', 'tertiary', 'dark', 'icon'].includes(
|
|
45
|
+
value,
|
|
46
|
+
);
|
|
47
|
+
},
|
|
81
48
|
},
|
|
82
49
|
|
|
83
50
|
/**
|
|
@@ -90,6 +57,9 @@ export default {
|
|
|
90
57
|
size: {
|
|
91
58
|
type: String,
|
|
92
59
|
default: 'large',
|
|
60
|
+
validator(value) {
|
|
61
|
+
return ['small', 'large'].includes(value);
|
|
62
|
+
},
|
|
93
63
|
},
|
|
94
64
|
|
|
95
65
|
/**
|
|
@@ -156,37 +126,99 @@ export default {
|
|
|
156
126
|
|
|
157
127
|
appearance: {
|
|
158
128
|
type: String,
|
|
159
|
-
default: 'normal',
|
|
129
|
+
default: 'normal',
|
|
130
|
+
validator(value) {
|
|
131
|
+
return ['normal', 'ghost'].includes(value);
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
version: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: '1',
|
|
160
138
|
},
|
|
161
139
|
},
|
|
162
140
|
|
|
163
141
|
computed: {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
},
|
|
142
|
+
buttonClasses() {
|
|
143
|
+
const classes = [];
|
|
167
144
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
145
|
+
if (this.headless) {
|
|
146
|
+
// Headless mode - use semantic classes
|
|
147
|
+
classes.push('button');
|
|
148
|
+
classes.push(`button--${this.variant}`);
|
|
149
|
+
classes.push(`button--${this.size}`);
|
|
150
|
+
} else {
|
|
151
|
+
// Default mode - use component styles
|
|
171
152
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
153
|
+
// Default styles
|
|
154
|
+
if (!this.isIcon) {
|
|
155
|
+
classes.push('button-base');
|
|
156
|
+
}
|
|
175
157
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
158
|
+
// Variant styles
|
|
159
|
+
if (this.variant === 'primary') {
|
|
160
|
+
classes.push('button--primary');
|
|
161
|
+
}
|
|
179
162
|
|
|
180
|
-
|
|
181
|
-
|
|
163
|
+
if (this.variant === 'secondary') {
|
|
164
|
+
classes.push('button--secondary');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (this.variant === 'tertiary') {
|
|
168
|
+
classes.push('button--tertiary');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (this.variant === 'dark') {
|
|
172
|
+
classes.push('button--dark');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (this.isIcon) {
|
|
176
|
+
classes.push('button--icon');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Ghost appearance can be applied to any variant
|
|
180
|
+
if (this.isGhost) {
|
|
181
|
+
classes.push('button--ghost');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Size styles
|
|
185
|
+
if (this.size === 'large') {
|
|
186
|
+
classes.push(this.isIcon ? 'h-8 w-8' : 'button--large');
|
|
187
|
+
} else if (this.size === 'small') {
|
|
188
|
+
classes.push(this.isIcon ? 'h-6 w-6 p-1' : 'button--small');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (this.version && this.version !== '1') {
|
|
192
|
+
classes.push(`button--version-${this.version}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Disabled state (applies to both headless and non-headless)
|
|
197
|
+
if (this.isDisabled && this.isIcon) {
|
|
198
|
+
classes.push('[&_svg]:text-gray-400');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return classes.filter(Boolean);
|
|
182
202
|
},
|
|
183
203
|
|
|
184
|
-
|
|
185
|
-
|
|
204
|
+
spanClasses() {
|
|
205
|
+
const classes = [];
|
|
206
|
+
|
|
207
|
+
if (!this.headless) {
|
|
208
|
+
classes.push('mx-auto inline-flex items-center gap-2 self-center');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (this.headless && this.busy) {
|
|
212
|
+
classes.push('button--busy');
|
|
213
|
+
} else if (this.busy) {
|
|
214
|
+
classes.push('invisible');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return classes.filter(Boolean);
|
|
186
218
|
},
|
|
187
219
|
|
|
188
|
-
|
|
189
|
-
return this.
|
|
220
|
+
isIcon() {
|
|
221
|
+
return this.variant === 'icon';
|
|
190
222
|
},
|
|
191
223
|
|
|
192
224
|
isDisabled() {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<component
|
|
3
|
+
:is="as"
|
|
4
|
+
:class="iconClasses"
|
|
5
|
+
:aria-expanded="as === 'button' ? expanded : undefined"
|
|
6
|
+
@click.stop="onClick"
|
|
7
|
+
@keydown.enter="onClick"
|
|
8
|
+
@keydown.space.prevent="onClick"
|
|
7
9
|
>
|
|
8
10
|
<slot><IconChevronDown /></slot>
|
|
9
|
-
</
|
|
11
|
+
</component>
|
|
10
12
|
</template>
|
|
11
13
|
|
|
12
14
|
<script>
|
|
@@ -20,12 +22,41 @@ export default {
|
|
|
20
22
|
type: Boolean,
|
|
21
23
|
default: false,
|
|
22
24
|
},
|
|
25
|
+
as: {
|
|
26
|
+
type: String,
|
|
27
|
+
default: 'span',
|
|
28
|
+
validator(value) {
|
|
29
|
+
return ['span', 'button', 'div', 'a'].includes(value);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
23
32
|
},
|
|
24
33
|
|
|
25
34
|
computed: {
|
|
35
|
+
iconClasses() {
|
|
36
|
+
const classes = [];
|
|
37
|
+
|
|
38
|
+
if (this.headless) {
|
|
39
|
+
classes.push('disclosure-icon');
|
|
40
|
+
} else {
|
|
41
|
+
classes.push('shrink-0 transition-all');
|
|
42
|
+
classes.push(this.expanded ? 'rotate-180' : 'rotate-0');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return classes.filter(Boolean);
|
|
46
|
+
},
|
|
47
|
+
|
|
26
48
|
expanded() {
|
|
27
49
|
return this.apiDetails().visible;
|
|
28
50
|
},
|
|
29
51
|
},
|
|
52
|
+
|
|
53
|
+
methods: {
|
|
54
|
+
onClick() {
|
|
55
|
+
// Only handle click if rendered as a button
|
|
56
|
+
if (this.as === 'button') {
|
|
57
|
+
this.apiDetails().setVisible(!this.expanded);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
},
|
|
30
61
|
};
|
|
31
62
|
</script>
|