调整buttongroup和checkgroup布局

This commit is contained in:
fofolee 2025-02-12 15:09:42 +08:00
parent ed609b3fa9
commit 6e8a0c79e3
2 changed files with 75 additions and 20 deletions

View File

@ -7,15 +7,32 @@
>
<div class="button-group">
<div
v-for="opt in options"
v-for="opt in formattedOptions"
:key="opt.value"
:style="{
height: height,
flex: `1 0 calc(${100 / formattedOptions.length}% - ${
(4 * (formattedOptions.length - 1)) / formattedOptions.length
}px)`,
}"
:class="['button-item', { active: modelValue === opt.value }]"
:class="[
'button-item',
{
active: modelValue === opt.value,
disabled: opt.disabled,
},
]"
@click="$emit('update:modelValue', opt.value)"
>
{{ opt.label }}
<div class="q-mr-sm" v-if="opt.icon">
<q-img
:src="opt.icon"
width="24px"
v-if="opt.icon.includes('.png')"
/>
<q-icon :name="opt.icon" v-else />
</div>
<div>{{ opt.label }}</div>
</div>
</div>
</component>
@ -34,10 +51,6 @@ export default defineComponent({
modelValue: {
required: true,
},
height: {
type: String,
default: "26px",
},
options: {
type: Array,
required: true,
@ -54,8 +67,20 @@ export default defineComponent({
type: Boolean,
default: false,
},
height: {
type: String,
default: "32px",
},
},
emits: ["update:modelValue"],
computed: {
formattedOptions() {
return this.options.map((opt) => ({
...opt,
value: opt.value ?? opt.name,
}));
},
},
});
</script>
@ -64,13 +89,11 @@ export default defineComponent({
display: flex;
width: 100%;
flex-wrap: wrap;
gap: 6px;
border-radius: 6px;
gap: 4px;
}
.button-item {
flex: 1;
min-width: 80px;
min-width: fit-content;
display: inline-flex;
align-items: center;
justify-content: center;
@ -95,4 +118,11 @@ export default defineComponent({
background: var(--q-primary);
border-color: var(--q-primary);
}
.button-item.disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
filter: grayscale(1);
}
</style>

View File

@ -7,7 +7,7 @@
>
<div class="check-btn-group">
<q-btn
v-for="option in options"
v-for="option in formattedOptions"
:key="option.value"
:color="isSelected(option.value) ? 'primary' : 'grey-7'"
:flat="!isSelected(option.value)"
@ -18,15 +18,24 @@
{ 'check-btn--selected': isSelected(option.value) },
]"
:style="{
flex: `1 0 calc(${100 / options.length}% - ${
(4 * (options.length - 1)) / options.length
flex: `1 0 calc(${100 / formattedOptions.length}% - ${
(4 * (formattedOptions.length - 1)) / formattedOptions.length
}px)`,
height: height,
}"
@click="toggleOption(option.value)"
>
<template #default>
<div class="row items-center full-width">
<div class="check-btn-content">
<div class="check-btn-content row items-center">
<div class="q-mr-sm" v-if="option.icon">
<q-img
:src="option.icon"
width="24px"
v-if="option.icon.includes('.png')"
/>
<q-icon :name="option.icon" v-else />
</div>
<div class="check-btn-label">{{ option.label }}</div>
</div>
<q-icon
@ -61,8 +70,6 @@ export default defineComponent({
options: {
type: Array,
required: true,
validator: (options) =>
options.every((opt) => opt.label && opt.value !== undefined),
},
label: {
type: String,
@ -76,6 +83,26 @@ export default defineComponent({
type: Boolean,
default: false,
},
height: {
type: String,
default: "36px",
},
},
computed: {
formattedOptions() {
return this.options.map((opt) => {
if (typeof opt === "string") {
return {
label: opt,
value: opt,
};
}
return {
...opt,
value: opt.value ?? opt.name,
};
});
},
},
emits: ["update:model-value"],
methods: {
@ -107,10 +134,8 @@ export default defineComponent({
.check-btn {
min-width: fit-content !important;
max-width: 100% !important;
height: auto !important;
min-height: 32px;
font-size: 12px;
padding: 4px 8px;
padding: 0 8px;
border-radius: 4px !important;
transition: all 0.3s;
background-color: rgba(0, 0, 0, 0.03);