mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 11:11:53 +00:00
fix: wrapper deleted
This commit is contained in:
@@ -200,8 +200,8 @@ export const MultipleSelectors: Story = {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 bg-gray-50 dark-theme:bg-zinc-800 rounded">
|
<div class="p-4 bg-gray-50 dark-theme:bg-zinc-800 rounded">
|
||||||
<h4 class="font-medium mb-2">Current Selection:</h4>
|
<h4 class="font-medium mt-0">Current Selection:</h4>
|
||||||
<div class="space-y-1 text-sm">
|
<div class="flex flex-col text-sm">
|
||||||
<p>Frameworks: {{ selectedFrameworks.length > 0 ? selectedFrameworks.map(s => s.name).join(', ') : 'None' }}</p>
|
<p>Frameworks: {{ selectedFrameworks.length > 0 ? selectedFrameworks.map(s => s.name).join(', ') : 'None' }}</p>
|
||||||
<p>Projects: {{ selectedProjects.length > 0 ? selectedProjects.map(s => s.name).join(', ') : 'None' }}</p>
|
<p>Projects: {{ selectedProjects.length > 0 ? selectedProjects.map(s => s.name).join(', ') : 'None' }}</p>
|
||||||
<p>Tags: {{ selectedTags.length > 0 ? selectedTags.map(s => s.name).join(', ') : 'None' }}</p>
|
<p>Tags: {{ selectedTags.length > 0 ? selectedTags.map(s => s.name).join(', ') : 'None' }}</p>
|
||||||
|
|||||||
@@ -1,96 +1,92 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative inline-block">
|
<MultiSelect
|
||||||
<MultiSelect
|
v-model="selectedItems"
|
||||||
v-model="selectedItems"
|
:options="options"
|
||||||
:options="options"
|
option-label="name"
|
||||||
option-label="name"
|
unstyled
|
||||||
unstyled
|
:placeholder="label"
|
||||||
:placeholder="label"
|
:max-selected-labels="0"
|
||||||
:max-selected-labels="0"
|
:pt="pt"
|
||||||
:pt="pt"
|
>
|
||||||
|
<template
|
||||||
|
v-if="showSearchBox || showSelectedCount || showClearButton"
|
||||||
|
#header
|
||||||
>
|
>
|
||||||
<template
|
<div class="p-2 flex flex-col pb-0">
|
||||||
v-if="showSearchBox || showSelectedCount || showClearButton"
|
<SearchBox
|
||||||
#header
|
v-if="showSearchBox"
|
||||||
>
|
v-model="searchQuery"
|
||||||
<div class="p-2 flex flex-col pb-0">
|
:class="showSelectedCount || showClearButton ? 'mb-2' : ''"
|
||||||
<SearchBox
|
:has-border="true"
|
||||||
v-if="showSearchBox"
|
:place-holder="searchPlaceholder"
|
||||||
v-model="searchQuery"
|
/>
|
||||||
:class="showSelectedCount || showClearButton ? 'mb-2' : ''"
|
<div
|
||||||
:has-border="true"
|
v-if="showSelectedCount || showClearButton"
|
||||||
:place-holder="searchPlaceholder"
|
class="mt-2 flex items-center justify-between"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="showSelectedCount"
|
||||||
|
class="text-sm text-neutral-400 dark-theme:text-zinc-500 px-1"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
selectedCount > 0
|
||||||
|
? $t('g.itemsSelected', { selectedCount })
|
||||||
|
: $t('g.itemSelected', { selectedCount })
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
<TextButton
|
||||||
|
v-if="showClearButton"
|
||||||
|
:label="$t('g.clearAll')"
|
||||||
|
type="transparent"
|
||||||
|
size="fit-content"
|
||||||
|
class="text-sm !text-blue-500 !dark-theme:text-blue-600"
|
||||||
|
@click.stop="selectedItems = []"
|
||||||
/>
|
/>
|
||||||
<div
|
|
||||||
v-if="showSelectedCount || showClearButton"
|
|
||||||
class="mt-2 flex items-center justify-between"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
v-if="showSelectedCount"
|
|
||||||
class="text-sm text-neutral-400 dark-theme:text-zinc-500 px-1"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
selectedCount > 0
|
|
||||||
? $t('g.itemsSelected', { selectedCount })
|
|
||||||
: $t('g.itemSelected', { selectedCount })
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<TextButton
|
|
||||||
v-if="showClearButton"
|
|
||||||
:label="$t('g.clearAll')"
|
|
||||||
type="transparent"
|
|
||||||
size="fit-content"
|
|
||||||
class="text-sm !text-blue-500 !dark-theme:text-blue-600"
|
|
||||||
@click.stop="selectedItems = []"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="mt-4 h-px bg-zinc-200 dark-theme:bg-zinc-700"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="mt-4 h-px bg-zinc-200 dark-theme:bg-zinc-700"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Trigger value (keep text scale identical) -->
|
<!-- Trigger value (keep text scale identical) -->
|
||||||
<template #value>
|
<template #value>
|
||||||
<span class="text-sm text-zinc-700 dark-theme:text-gray-200">
|
<span class="text-sm text-zinc-700 dark-theme:text-gray-200">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
<span
|
||||||
|
v-if="selectedCount > 0"
|
||||||
|
class="pointer-events-none absolute -right-2 -top-2 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-blue-400 dark-theme:bg-blue-500 text-xs font-semibold text-white"
|
||||||
|
>
|
||||||
|
{{ selectedCount }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Chevron size identical to current -->
|
<!-- Chevron size identical to current -->
|
||||||
<template #dropdownicon>
|
<template #dropdownicon>
|
||||||
<i-lucide:chevron-down class="text-lg text-neutral-400" />
|
<i-lucide:chevron-down class="text-lg text-neutral-400" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Custom option row: square checkbox + label (unchanged layout/colors) -->
|
<!-- Custom option row: square checkbox + label (unchanged layout/colors) -->
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div
|
<div
|
||||||
class="flex h-4 w-4 p-0.5 flex-shrink-0 items-center justify-center rounded border-[3px] transition-all duration-200"
|
class="flex h-4 w-4 p-0.5 flex-shrink-0 items-center justify-center rounded border-[3px] transition-all duration-200"
|
||||||
:class="
|
:class="
|
||||||
slotProps.selected
|
slotProps.selected
|
||||||
? 'border-blue-400 bg-blue-400 dark-theme:border-blue-500 dark-theme:bg-blue-500'
|
? 'border-blue-400 bg-blue-400 dark-theme:border-blue-500 dark-theme:bg-blue-500'
|
||||||
: 'border-neutral-300 dark-theme:border-zinc-600 bg-neutral-100 dark-theme:bg-zinc-700'
|
: 'border-neutral-300 dark-theme:border-zinc-600 bg-neutral-100 dark-theme:bg-zinc-700'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<i-lucide:check
|
<i-lucide:check
|
||||||
v-if="slotProps.selected"
|
v-if="slotProps.selected"
|
||||||
class="text-xs text-bold text-white"
|
class="text-xs text-bold text-white"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<Button class="border-none outline-none bg-transparent" unstyled>{{
|
|
||||||
slotProps.option.name
|
|
||||||
}}</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<Button class="border-none outline-none bg-transparent" unstyled>{{
|
||||||
</MultiSelect>
|
slotProps.option.name
|
||||||
|
}}</Button>
|
||||||
<!-- Selected count badge -->
|
</div>
|
||||||
<div
|
</template>
|
||||||
v-if="selectedCount > 0"
|
</MultiSelect>
|
||||||
class="pointer-events-none absolute -right-2 -top-2 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-blue-400 dark-theme:bg-blue-500 text-xs font-semibold text-white"
|
|
||||||
>
|
|
||||||
{{ selectedCount }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -138,7 +134,7 @@ const selectedCount = computed(() => selectedItems.value.length)
|
|||||||
const pt = computed(() => ({
|
const pt = computed(() => ({
|
||||||
root: ({ props }: MultiSelectPassThroughMethodOptions) => ({
|
root: ({ props }: MultiSelectPassThroughMethodOptions) => ({
|
||||||
class: [
|
class: [
|
||||||
'relative inline-flex cursor-pointer select-none w-full',
|
'relative inline-flex cursor-pointer select-none',
|
||||||
'rounded-lg bg-white dark-theme:bg-zinc-800 text-neutral dark-theme:text-white',
|
'rounded-lg bg-white dark-theme:bg-zinc-800 text-neutral dark-theme:text-white',
|
||||||
'transition-all duration-200 ease-in-out',
|
'transition-all duration-200 ease-in-out',
|
||||||
'border-[2.5px] border-solid',
|
'border-[2.5px] border-solid',
|
||||||
|
|||||||
@@ -1,49 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative inline-flex items-center">
|
<Select
|
||||||
<Select
|
v-model="selectedItem"
|
||||||
v-model="selectedItem"
|
:options="options"
|
||||||
:options="options"
|
option-label="name"
|
||||||
option-label="name"
|
option-value="value"
|
||||||
option-value="value"
|
unstyled
|
||||||
unstyled
|
:placeholder="label"
|
||||||
:placeholder="label"
|
:pt="pt"
|
||||||
:pt="pt"
|
>
|
||||||
>
|
<!-- Trigger value -->
|
||||||
<!-- Trigger value -->
|
<template #value="slotProps">
|
||||||
<template #value="slotProps">
|
<div class="flex items-center gap-2 text-sm">
|
||||||
<div class="flex items-center gap-2 text-sm">
|
<slot name="icon" />
|
||||||
<slot name="icon" />
|
<span
|
||||||
<span
|
v-if="slotProps.value !== null && slotProps.value !== undefined"
|
||||||
v-if="slotProps.value !== null && slotProps.value !== undefined"
|
class="text-zinc-700 dark-theme:text-gray-200"
|
||||||
class="text-zinc-700 dark-theme:text-gray-200"
|
>
|
||||||
>
|
{{ getLabel(slotProps.value) }}
|
||||||
{{ getLabel(slotProps.value) }}
|
</span>
|
||||||
</span>
|
<span v-else class="text-zinc-700 dark-theme:text-gray-200">
|
||||||
<span v-else class="text-zinc-700 dark-theme:text-gray-200">
|
{{ label }}
|
||||||
{{ label }}
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Trigger caret -->
|
<!-- Trigger caret -->
|
||||||
<template #dropdownicon>
|
<template #dropdownicon>
|
||||||
<i-lucide:chevron-down
|
<i-lucide:chevron-down
|
||||||
class="text-base text-neutral-400 dark-theme:text-gray-300"
|
class="text-base text-neutral-400 dark-theme:text-gray-300"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Option row -->
|
||||||
|
<template #option="{ option, selected }">
|
||||||
|
<div class="flex items-center justify-between gap-3 w-full">
|
||||||
|
<span class="truncate">{{ option.name }}</span>
|
||||||
|
<i-lucide:check
|
||||||
|
v-if="selected"
|
||||||
|
class="text-neutral-900 dark-theme:text-white"
|
||||||
/>
|
/>
|
||||||
</template>
|
</div>
|
||||||
|
</template>
|
||||||
<!-- Option row -->
|
</Select>
|
||||||
<template #option="{ option, selected }">
|
|
||||||
<div class="flex items-center justify-between gap-3 w-full">
|
|
||||||
<span class="truncate">{{ option.name }}</span>
|
|
||||||
<i-lucide:check
|
|
||||||
v-if="selected"
|
|
||||||
class="text-neutral-900 dark-theme:text-white"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -77,7 +75,7 @@ const pt = computed(() => ({
|
|||||||
}: SelectPassThroughMethodOptions<{ name: string; value: string }>) => ({
|
}: SelectPassThroughMethodOptions<{ name: string; value: string }>) => ({
|
||||||
class: [
|
class: [
|
||||||
// container
|
// container
|
||||||
'relative inline-flex w-full cursor-pointer select-none items-center',
|
'relative inline-flex cursor-pointer select-none items-center',
|
||||||
// trigger surface
|
// trigger surface
|
||||||
'rounded-md',
|
'rounded-md',
|
||||||
'bg-transparent text-neutral dark-theme:text-white',
|
'bg-transparent text-neutral dark-theme:text-white',
|
||||||
|
|||||||
Reference in New Issue
Block a user