1
This commit is contained in:
@@ -19,7 +19,7 @@ const props = withDefaults(
|
|||||||
:data-size="size"
|
:data-size="size"
|
||||||
:class="
|
:class="
|
||||||
cn(
|
cn(
|
||||||
'ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col transition-all duration-200',
|
'border-border/70 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl border py-4 text-sm has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col transition-all duration-200',
|
||||||
props.class,
|
props.class,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectRootEmits, SelectRootProps } from "reka-ui";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { SelectRoot } from "reka-ui";
|
||||||
|
import { fromSelectUpdateValue, toSelectValue } from "./utils";
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<SelectRootProps>(), {
|
||||||
|
modelValue: undefined,
|
||||||
|
defaultValue: undefined,
|
||||||
|
open: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits<SelectRootEmits>();
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "modelValue", "defaultValue");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectRoot
|
||||||
|
v-bind="delegatedProps"
|
||||||
|
:model-value="toSelectValue(modelValue)"
|
||||||
|
:default-value="toSelectValue(defaultValue)"
|
||||||
|
@update:model-value="(value) => emits('update:modelValue', fromSelectUpdateValue(value))"
|
||||||
|
@update:open="(value) => emits('update:open', value)"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</SelectRoot>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectContentEmits, SelectContentProps } from "reka-ui";
|
||||||
|
import type { HTMLAttributes } from "vue";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { SelectContent, SelectPortal, SelectViewport, useForwardPropsEmits } from "reka-ui";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
inheritAttrs: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<SelectContentProps & { class?: HTMLAttributes["class"] }>(),
|
||||||
|
{
|
||||||
|
position: "popper",
|
||||||
|
sideOffset: 4,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const emits = defineEmits<SelectContentEmits>();
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectPortal>
|
||||||
|
<SelectContent
|
||||||
|
data-slot="select-content"
|
||||||
|
v-bind="{ ...$attrs, ...forwarded }"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground relative z-50 max-h-(--reka-select-content-available-height) min-w-32 origin-(--reka-select-content-transform-origin) overflow-hidden rounded-md border shadow-md ring-1',
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<SelectViewport
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'p-1',
|
||||||
|
position === 'popper' &&
|
||||||
|
'h-(--reka-select-trigger-height) w-full min-w-(--reka-select-trigger-width)',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</SelectViewport>
|
||||||
|
</SelectContent>
|
||||||
|
</SelectPortal>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectItemEmits, SelectItemProps } from "reka-ui";
|
||||||
|
import type { HTMLAttributes } from "vue";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { Check } from "lucide-vue-next";
|
||||||
|
import { SelectItem, SelectItemIndicator, SelectItemText, useForwardPropsEmits } from "reka-ui";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { toSelectItemValue } from "./utils";
|
||||||
|
|
||||||
|
const props = defineProps<SelectItemProps & { class?: HTMLAttributes["class"] }>();
|
||||||
|
const emits = defineEmits<SelectItemEmits>();
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "value");
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectItem
|
||||||
|
data-slot="select-item"
|
||||||
|
v-bind="forwarded"
|
||||||
|
:value="toSelectItemValue(value)"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none',
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<span class="absolute right-2 flex size-3.5 items-center justify-center">
|
||||||
|
<SelectItemIndicator>
|
||||||
|
<Check class="size-4" />
|
||||||
|
</SelectItemIndicator>
|
||||||
|
</span>
|
||||||
|
<SelectItemText>
|
||||||
|
<slot />
|
||||||
|
</SelectItemText>
|
||||||
|
</SelectItem>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectLabelProps } from "reka-ui";
|
||||||
|
import type { HTMLAttributes } from "vue";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { SelectLabel, useForwardProps } from "reka-ui";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const props = defineProps<SelectLabelProps & { class?: HTMLAttributes["class"] }>();
|
||||||
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
const forwardedProps = useForwardProps(delegatedProps);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectLabel
|
||||||
|
data-slot="select-label"
|
||||||
|
v-bind="forwardedProps"
|
||||||
|
:class="cn('px-2 py-1.5 text-sm font-medium', props.class)"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</SelectLabel>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectSeparatorProps } from "reka-ui";
|
||||||
|
import type { HTMLAttributes } from "vue";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { SelectSeparator, useForwardProps } from "reka-ui";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes["class"] }>();
|
||||||
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
const forwardedProps = useForwardProps(delegatedProps);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectSeparator
|
||||||
|
data-slot="select-separator"
|
||||||
|
v-bind="forwardedProps"
|
||||||
|
:class="cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectTriggerProps } from "reka-ui";
|
||||||
|
import type { HTMLAttributes } from "vue";
|
||||||
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
|
import { ChevronDown } from "lucide-vue-next";
|
||||||
|
import { SelectIcon, SelectTrigger, useForwardProps } from "reka-ui";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const props = defineProps<SelectTriggerProps & { class?: HTMLAttributes["class"] }>();
|
||||||
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
const forwardedProps = useForwardProps(delegatedProps);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectTrigger
|
||||||
|
data-slot="select-trigger"
|
||||||
|
v-bind="forwardedProps"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'border-input bg-background text-foreground ring-offset-background placeholder:text-muted-foreground focus:ring-ring/50 flex h-9 w-full min-w-0 items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus:ring-3 disabled:cursor-not-allowed disabled:opacity-50 data-placeholder:text-muted-foreground [&>span]:truncate [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
<SelectIcon as-child>
|
||||||
|
<ChevronDown class="size-4 opacity-50" />
|
||||||
|
</SelectIcon>
|
||||||
|
</SelectTrigger>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SelectValueProps } from "reka-ui";
|
||||||
|
import { SelectValue } from "reka-ui";
|
||||||
|
|
||||||
|
const props = defineProps<SelectValueProps>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SelectValue v-bind="props">
|
||||||
|
<slot />
|
||||||
|
</SelectValue>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export { default as Select } from "./Select.vue";
|
||||||
|
export { default as SelectContent } from "./SelectContent.vue";
|
||||||
|
export { default as SelectItem } from "./SelectItem.vue";
|
||||||
|
export { default as SelectLabel } from "./SelectLabel.vue";
|
||||||
|
export { default as SelectSeparator } from "./SelectSeparator.vue";
|
||||||
|
export { default as SelectTrigger } from "./SelectTrigger.vue";
|
||||||
|
export { default as SelectValue } from "./SelectValue.vue";
|
||||||
|
export { SelectGroup } from "reka-ui";
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import type { AcceptableValue } from "reka-ui";
|
||||||
|
|
||||||
|
const EMPTY_VALUE = "__dcalc_select_empty__";
|
||||||
|
|
||||||
|
export type SelectModelValue = AcceptableValue | AcceptableValue[] | undefined;
|
||||||
|
|
||||||
|
export function toSelectValue(value: SelectModelValue): SelectModelValue {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map((item) => toSelectValue(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value === "" ? EMPTY_VALUE : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toSelectItemValue(value: AcceptableValue): AcceptableValue {
|
||||||
|
return value === "" ? EMPTY_VALUE : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromSelectValue(value: SelectModelValue): SelectModelValue {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map((item) => fromSelectValue(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value === EMPTY_VALUE ? "" : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromSelectUpdateValue(value: AcceptableValue): AcceptableValue {
|
||||||
|
return value === EMPTY_VALUE ? "" : value;
|
||||||
|
}
|
||||||
@@ -21,6 +21,13 @@ import {
|
|||||||
SheetTitle,
|
SheetTitle,
|
||||||
SheetTrigger,
|
SheetTrigger,
|
||||||
} from "@/components/ui/sheet";
|
} from "@/components/ui/sheet";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import Tabs from "@/components/ui/tabs/Tabs.vue";
|
import Tabs from "@/components/ui/tabs/Tabs.vue";
|
||||||
import TabsList from "@/components/ui/tabs/TabsList.vue";
|
import TabsList from "@/components/ui/tabs/TabsList.vue";
|
||||||
import TabsTrigger from "@/components/ui/tabs/TabsTrigger.vue";
|
import TabsTrigger from "@/components/ui/tabs/TabsTrigger.vue";
|
||||||
@@ -916,22 +923,23 @@ const setTriggerOption = (id: number, value: string) => {
|
|||||||
class="grid gap-1 text-sm"
|
class="grid gap-1 text-sm"
|
||||||
>
|
>
|
||||||
<span class="text-muted-foreground">{{ option.name }}</span>
|
<span class="text-muted-foreground">{{ option.name }}</span>
|
||||||
<select
|
<Select
|
||||||
class="h-9 rounded-md border border-input bg-background px-2"
|
:model-value="String(configStore.config.options[option.id.toString()] ?? 0)"
|
||||||
:value="String(configStore.config.options[option.id.toString()] ?? 0)"
|
@update:model-value="(value) => setTriggerOption(option.id, String(value))"
|
||||||
@change="
|
|
||||||
(event) =>
|
|
||||||
setTriggerOption(option.id, (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option
|
<SelectTrigger class="h-9">
|
||||||
v-for="(item, index) in option.options"
|
<SelectValue />
|
||||||
:key="`${option.id}-${index}`"
|
</SelectTrigger>
|
||||||
:value="String(index)"
|
<SelectContent>
|
||||||
>
|
<SelectItem
|
||||||
{{ item }}
|
v-for="(item, index) in option.options"
|
||||||
</option>
|
:key="`${option.id}-${index}`"
|
||||||
</select>
|
:value="String(index)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
|
|||||||
@@ -5,6 +5,13 @@ import { useConfigStore, useInfoStore } from "@/stores";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionContent,
|
AccordionContent,
|
||||||
@@ -697,21 +704,20 @@ const resetAllForge = () => {
|
|||||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-4">
|
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-4">
|
||||||
<label v-if="canUpgradeEquip(part)" class="space-y-1">
|
<label v-if="canUpgradeEquip(part)" class="space-y-1">
|
||||||
<span class="text-muted-foreground">强化类型</span>
|
<span class="text-muted-foreground">强化类型</span>
|
||||||
<select
|
<Select
|
||||||
class="h-8 w-full rounded-md border border-input bg-background px-2"
|
:model-value="String(equipCfg(part).reinforceType)"
|
||||||
:value="String(equipCfg(part).reinforceType)"
|
@update:model-value="
|
||||||
@change="
|
(value) => setEquipNumberField(part, 'reinforceType', String(value))
|
||||||
(event) =>
|
|
||||||
setEquipNumberField(
|
|
||||||
part,
|
|
||||||
'reinforceType',
|
|
||||||
(event.target as HTMLSelectElement).value,
|
|
||||||
)
|
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<option value="0">强化</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option value="1">增幅</option>
|
<SelectValue />
|
||||||
</select>
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="0">强化</SelectItem>
|
||||||
|
<SelectItem value="1">增幅</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label v-if="canUpgradeEquip(part)" class="space-y-1">
|
<label v-if="canUpgradeEquip(part)" class="space-y-1">
|
||||||
@@ -758,22 +764,24 @@ const resetAllForge = () => {
|
|||||||
|
|
||||||
<label v-if="equipEnchantOptions(part).length" class="space-y-1 sm:col-span-2">
|
<label v-if="equipEnchantOptions(part).length" class="space-y-1 sm:col-span-2">
|
||||||
<span class="text-muted-foreground">附魔</span>
|
<span class="text-muted-foreground">附魔</span>
|
||||||
<select
|
<Select
|
||||||
class="h-8 w-full min-w-0 rounded-md border border-input bg-background px-2"
|
:model-value="equipCfg(part).enchant"
|
||||||
:value="equipCfg(part).enchant"
|
@update:model-value="(value) => setEquipEnchant(part, String(value))"
|
||||||
@change="
|
|
||||||
(event) => setEquipEnchant(part, (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">无</option>
|
<SelectTrigger class="h-8 min-w-0 text-xs">
|
||||||
<option
|
<SelectValue />
|
||||||
v-for="item in equipEnchantOptions(part)"
|
</SelectTrigger>
|
||||||
:key="item.id"
|
<SelectContent>
|
||||||
:value="String(item.id)"
|
<SelectItem value="">无</SelectItem>
|
||||||
>
|
<SelectItem
|
||||||
{{ item.detail }}
|
v-for="item in equipEnchantOptions(part)"
|
||||||
</option>
|
:key="item.id"
|
||||||
</select>
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
{{ item.detail }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label v-if="canSetSecret(part)" class="space-y-1">
|
<label v-if="canSetSecret(part)" class="space-y-1">
|
||||||
@@ -864,12 +872,16 @@ const resetAllForge = () => {
|
|||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">部位</div>
|
<div class="text-muted-foreground">部位</div>
|
||||||
<select
|
<Select v-model="avatarPart">
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
<SelectTrigger class="h-8 text-xs">
|
||||||
v-model="avatarPart"
|
<SelectValue />
|
||||||
>
|
</SelectTrigger>
|
||||||
<option v-for="part in avatarParts" :key="part" :value="part">{{ part }}</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem v-for="part in avatarParts" :key="part" :value="part">
|
||||||
|
{{ part }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -877,94 +889,116 @@ const resetAllForge = () => {
|
|||||||
class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center"
|
class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center"
|
||||||
>
|
>
|
||||||
<div class="text-muted-foreground">附魔</div>
|
<div class="text-muted-foreground">附魔</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="avatarCfg(avatarPart).enchant"
|
||||||
:value="avatarCfg(avatarPart).enchant"
|
@update:model-value="(value) => setAvatarField('enchant', String(value))"
|
||||||
@change="
|
|
||||||
(event) => setAvatarField('enchant', (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">无</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option
|
<SelectValue />
|
||||||
v-for="item in avatarEnchantOptions"
|
</SelectTrigger>
|
||||||
:key="item.id"
|
<SelectContent>
|
||||||
:value="String(item.id)"
|
<SelectItem value="">无</SelectItem>
|
||||||
>
|
<SelectItem
|
||||||
{{ item.detail }}
|
v-for="item in avatarEnchantOptions"
|
||||||
</option>
|
:key="item.id"
|
||||||
</select>
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
{{ item.detail }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">品级</div>
|
<div class="text-muted-foreground">品级</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="avatarCfg(avatarPart).id"
|
||||||
:value="avatarCfg(avatarPart).id"
|
@update:model-value="(value) => setAvatarField('id', String(value))"
|
||||||
@change="
|
|
||||||
(event) => setAvatarField('id', (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">未选择</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option v-for="item in avatarSuitOptions" :key="item.id" :value="String(item.id)">
|
<SelectValue />
|
||||||
{{ item.suit || item.rarity || item.name }}
|
</SelectTrigger>
|
||||||
</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem value="">未选择</SelectItem>
|
||||||
|
<SelectItem
|
||||||
|
v-for="item in avatarSuitOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
{{ item.suit || item.rarity || item.name }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">属性</div>
|
<div class="text-muted-foreground">属性</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="avatarCfg(avatarPart).option"
|
||||||
:value="avatarCfg(avatarPart).option"
|
@update:model-value="(value) => setAvatarField('option', String(value))"
|
||||||
@change="
|
|
||||||
(event) => setAvatarField('option', (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="0">无</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option
|
<SelectValue />
|
||||||
v-for="opt in avatarSuitOptions.find(
|
</SelectTrigger>
|
||||||
(x) => String(x.id) === avatarCfg(avatarPart).id,
|
<SelectContent>
|
||||||
)?.options || []"
|
<SelectItem value="0">无</SelectItem>
|
||||||
:key="opt"
|
<SelectItem
|
||||||
:value="opt"
|
v-for="opt in avatarSuitOptions.find(
|
||||||
>
|
(x) => String(x.id) === avatarCfg(avatarPart).id,
|
||||||
{{ opt }}
|
)?.options || []"
|
||||||
</option>
|
:key="opt"
|
||||||
</select>
|
:value="opt"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">徽章一</div>
|
<div class="text-muted-foreground">徽章一</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="avatarCfg(avatarPart).emblem_0"
|
||||||
:value="avatarCfg(avatarPart).emblem_0"
|
@update:model-value="(value) => setAvatarField('emblem_0', String(value))"
|
||||||
@change="
|
|
||||||
(event) => setAvatarField('emblem_0', (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">无</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option v-for="item in avatarEmblemOptions" :key="item.id" :value="String(item.id)">
|
<SelectValue />
|
||||||
[{{ item.rarity }}] {{ item.value }}
|
</SelectTrigger>
|
||||||
</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem value="">无</SelectItem>
|
||||||
|
<SelectItem
|
||||||
|
v-for="item in avatarEmblemOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
[{{ item.rarity }}] {{ item.value }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">徽章二</div>
|
<div class="text-muted-foreground">徽章二</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="avatarCfg(avatarPart).emblem_1"
|
||||||
:value="avatarCfg(avatarPart).emblem_1"
|
@update:model-value="(value) => setAvatarField('emblem_1', String(value))"
|
||||||
@change="
|
|
||||||
(event) => setAvatarField('emblem_1', (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">无</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option v-for="item in avatarEmblemOptions" :key="item.id" :value="String(item.id)">
|
<SelectValue />
|
||||||
[{{ item.rarity }}] {{ item.value }}
|
</SelectTrigger>
|
||||||
</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem value="">无</SelectItem>
|
||||||
|
<SelectItem
|
||||||
|
v-for="item in avatarEmblemOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
[{{ item.rarity }}] {{ item.value }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
@@ -999,14 +1033,16 @@ const resetAllForge = () => {
|
|||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
<div class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center">
|
||||||
<div class="text-muted-foreground">槽位类型</div>
|
<div class="text-muted-foreground">槽位类型</div>
|
||||||
<select
|
<Select v-model="emblemPart">
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
<SelectTrigger class="h-8 text-xs">
|
||||||
v-model="emblemPart"
|
<SelectValue />
|
||||||
>
|
</SelectTrigger>
|
||||||
<option v-for="part in infoStore.emblemParts" :key="part" :value="part">
|
<SelectContent>
|
||||||
{{ part }}
|
<SelectItem v-for="part in infoStore.emblemParts" :key="part" :value="part">
|
||||||
</option>
|
{{ part }}
|
||||||
</select>
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -1014,15 +1050,23 @@ const resetAllForge = () => {
|
|||||||
class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center"
|
class="grid grid-cols-1 gap-2 md:grid-cols-[7rem_1fr] md:items-center"
|
||||||
>
|
>
|
||||||
<div class="text-muted-foreground">等级</div>
|
<div class="text-muted-foreground">等级</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 rounded-md border border-input bg-background px-2"
|
:model-value="String(emblemCfg.lv ?? 0)"
|
||||||
:value="String(emblemCfg.lv ?? 0)"
|
@update:model-value="(value) => setEmblemLv(String(value))"
|
||||||
@change="(event) => setEmblemLv((event.target as HTMLSelectElement).value)"
|
|
||||||
>
|
>
|
||||||
<option v-for="(label, index) in emblemLevels" :key="label" :value="String(index)">
|
<SelectTrigger class="h-8 text-xs">
|
||||||
{{ label }}
|
<SelectValue />
|
||||||
</option>
|
</SelectTrigger>
|
||||||
</select>
|
<SelectContent>
|
||||||
|
<SelectItem
|
||||||
|
v-for="(label, index) in emblemLevels"
|
||||||
|
:key="label"
|
||||||
|
:value="String(index)"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@@ -1035,18 +1079,24 @@ const resetAllForge = () => {
|
|||||||
class="space-y-1"
|
class="space-y-1"
|
||||||
>
|
>
|
||||||
<div class="text-xs text-muted-foreground">槽位 {{ index }}</div>
|
<div class="text-xs text-muted-foreground">槽位 {{ index }}</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 w-full rounded-md border border-input bg-background px-2"
|
:model-value="emblemCfg.items[index - 1] || ''"
|
||||||
:value="emblemCfg.items[index - 1] || ''"
|
@update:model-value="(value) => setEmblemItem(index - 1, String(value))"
|
||||||
@change="
|
|
||||||
(event) => setEmblemItem(index - 1, (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option value="">无</option>
|
<SelectTrigger class="h-8 text-xs">
|
||||||
<option v-for="item in emblemOptions" :key="item.id" :value="String(item.id)">
|
<SelectValue />
|
||||||
[{{ item.rarity }}] {{ item.value }}
|
</SelectTrigger>
|
||||||
</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem value="">无</SelectItem>
|
||||||
|
<SelectItem
|
||||||
|
v-for="item in emblemOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
[{{ item.rarity }}] {{ item.value }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1077,31 +1127,43 @@ const resetAllForge = () => {
|
|||||||
class="grid grid-cols-1 gap-2 rounded-md border p-2 md:grid-cols-[6rem_1fr_12rem] md:items-center md:p-3"
|
class="grid grid-cols-1 gap-2 rounded-md border p-2 md:grid-cols-[6rem_1fr_12rem] md:items-center md:p-3"
|
||||||
>
|
>
|
||||||
<div class="font-medium">槽位 {{ Number(key) + 1 }}</div>
|
<div class="font-medium">槽位 {{ Number(key) + 1 }}</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 min-w-0 rounded-md border border-input bg-background px-2"
|
:model-value="String(ensureJade(key).id)"
|
||||||
:value="String(ensureJade(key).id)"
|
@update:model-value="(value) => setJadeId(key, String(value))"
|
||||||
@change="(event) => setJadeId(key, (event.target as HTMLSelectElement).value)"
|
|
||||||
>
|
>
|
||||||
<option value="-1">无</option>
|
<SelectTrigger class="h-8 min-w-0 text-xs">
|
||||||
<option v-for="item in infoStore.jades" :key="item.id" :value="String(item.id)">
|
<SelectValue />
|
||||||
{{ item.name }}
|
</SelectTrigger>
|
||||||
</option>
|
<SelectContent>
|
||||||
</select>
|
<SelectItem value="-1">无</SelectItem>
|
||||||
<select
|
<SelectItem
|
||||||
class="h-8 min-w-0 rounded-md border border-input bg-background px-2"
|
v-for="item in infoStore.jades"
|
||||||
:value="String(ensureJade(key).value)"
|
:key="item.id"
|
||||||
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Select
|
||||||
|
:model-value="String(ensureJade(key).value)"
|
||||||
:disabled="ensureJade(key).id < 0"
|
:disabled="ensureJade(key).id < 0"
|
||||||
@change="(event) => setJadeValue(key, (event.target as HTMLSelectElement).value)"
|
@update:model-value="(value) => setJadeValue(key, String(value))"
|
||||||
>
|
>
|
||||||
<option value="0">无</option>
|
<SelectTrigger class="h-8 min-w-0 text-xs">
|
||||||
<option
|
<SelectValue />
|
||||||
v-for="item in jadeValueOptions(ensureJade(key).id)"
|
</SelectTrigger>
|
||||||
:key="item.id"
|
<SelectContent>
|
||||||
:value="String(item.id)"
|
<SelectItem value="0">无</SelectItem>
|
||||||
>
|
<SelectItem
|
||||||
{{ item.value }}
|
v-for="item in jadeValueOptions(ensureJade(key).id)"
|
||||||
</option>
|
:key="item.id"
|
||||||
</select>
|
:value="String(item.id)"
|
||||||
|
>
|
||||||
|
{{ item.value }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
@@ -1131,21 +1193,23 @@ const resetAllForge = () => {
|
|||||||
class="grid grid-cols-1 gap-2 rounded-md border p-2 sm:grid-cols-[6rem_1fr] sm:items-center sm:p-3"
|
class="grid grid-cols-1 gap-2 rounded-md border p-2 sm:grid-cols-[6rem_1fr] sm:items-center sm:p-3"
|
||||||
>
|
>
|
||||||
<div class="font-medium">{{ field.label }}</div>
|
<div class="font-medium">{{ field.label }}</div>
|
||||||
<select
|
<Select
|
||||||
class="h-8 min-w-0 rounded-md border border-input bg-background px-2"
|
:model-value="sundryValue(field.key, field.defaultValue)"
|
||||||
:value="sundryValue(field.key, field.defaultValue)"
|
@update:model-value="(value) => setSundryValue(field.key, String(value))"
|
||||||
@change="
|
|
||||||
(event) => setSundryValue(field.key, (event.target as HTMLSelectElement).value)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<option
|
<SelectTrigger class="h-8 min-w-0 text-xs">
|
||||||
v-for="item in sundryOptions(field.key)"
|
<SelectValue />
|
||||||
:key="`${field.key}-${item.value}`"
|
</SelectTrigger>
|
||||||
:value="String(item.value)"
|
<SelectContent>
|
||||||
>
|
<SelectItem
|
||||||
{{ item.name }}
|
v-for="item in sundryOptions(field.key)"
|
||||||
</option>
|
:key="`${field.key}-${item.value}`"
|
||||||
</select>
|
:value="String(item.value)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user