feat(ui): add SwitchGroup component and revamp habitat appearance form

Introduce SwitchGroup component for multiple choice toggles
Replace TagsSelect with SwitchGroup for time and weather in HabitatEdit
Restructure appearance row layout for better responsiveness
This commit is contained in:
2026-04-30 17:27:26 +08:00
parent 45e0276158
commit 5e2d918b37
3 changed files with 240 additions and 28 deletions

View File

@@ -0,0 +1,60 @@
<script setup lang="ts">
export type SwitchGroupOption = {
value: string;
label: string;
};
const props = defineProps<{
id: string;
label: string;
modelValue: string[];
options: SwitchGroupOption[];
}>();
const emit = defineEmits<{
'update:modelValue': [value: string[]];
}>();
function optionId(index: number) {
return `${props.id}-${index}`;
}
function isSelected(value: string) {
return props.modelValue.includes(value);
}
function updateOption(value: string, event: Event) {
if (!(event.target instanceof HTMLInputElement)) return;
const { checked } = event.target;
if (checked) {
emit('update:modelValue', isSelected(value) ? props.modelValue : [...props.modelValue, value]);
return;
}
emit(
'update:modelValue',
props.modelValue.filter((item) => item !== value)
);
}
</script>
<template>
<fieldset class="switch-group">
<legend>{{ label }}</legend>
<div class="switch-group__options">
<label v-for="(option, index) in options" :key="option.value" class="switch-control switch-control--stacked">
<span class="switch-control__label">{{ option.label }}</span>
<input
:id="optionId(index)"
type="checkbox"
:checked="isSelected(option.value)"
:value="option.value"
@change="updateOption(option.value, $event)"
/>
<span class="switch-track" aria-hidden="true"></span>
</label>
</div>
</fieldset>
</template>