Files
hfb_sys/frontend/src/features/seller/views/components/OptionChips.vue
T

100 lines
1.9 KiB
Vue

<script setup lang="ts">
const props = withDefaults(
defineProps<{
options: Array<string | number>
modelValue?: string | number
activeValues?: Array<string | number>
disabledValues?: Array<string | number>
keyPrefix?: string
compact?: boolean
suffix?: string
}>(),
{
modelValue: undefined,
activeValues: () => [],
disabledValues: () => [],
keyPrefix: '',
compact: false,
suffix: '',
}
)
const emit = defineEmits<{
'update:modelValue': [value: string | number]
select: [value: string | number]
}>()
function isActive(value: string | number) {
return props.activeValues.includes(value) || props.modelValue === value
}
function isDisabled(value: string | number) {
return props.disabledValues.includes(value)
}
function selectValue(value: string | number) {
if (isDisabled(value)) return
emit('update:modelValue', value)
emit('select', value)
}
</script>
<template>
<div class="chip-group" :class="{ compact }">
<button
v-for="option in options"
:key="`${keyPrefix}${option}`"
type="button"
class="chip"
:class="{ active: isActive(option), disabled: isDisabled(option) }"
:disabled="isDisabled(option)"
@click="selectValue(option)"
>
{{ option }}{{ suffix }}
</button>
</div>
</template>
<style scoped>
.chip-group {
display: flex;
flex-wrap: wrap;
gap: 7px;
min-width: 0;
}
.chip-group.compact {
align-items: center;
min-height: 32px;
}
.chip {
min-height: 30px;
padding: 0 12px;
border: 1px solid #d6dce5;
border-radius: 15px;
background: #fff;
color: #596474;
font-size: 12px;
font-weight: 800;
cursor: pointer;
transition:
border-color 0.16s ease,
background 0.16s ease,
color 0.16s ease;
}
.chip.active {
border-color: #ff6a00;
background: #ff6a00;
color: #fff;
}
.chip.disabled {
border-color: #e5e7eb;
background: #f3f4f6;
color: #a8b0bd;
cursor: not-allowed;
}
</style>