import { useEffect, useState, type ReactNode } from 'react'; import { Button, Input, Space, Tag, Typography } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import type { HuyaCollabShop } from '../api/modules'; const { Text } = Typography; type ShopOption = Pick; /** * 店铺选择器:**一个店铺一个独立按钮**(中间留白),不做下拉。 * * - 选中那个按钮变主题蓝(primary),没选的是白底描边,一眼看得出选的是谁; * - `allowClear` 为真时多一个「不填 / 全部」按钮(筛选里传"全部"), * 店铺必填的地方传 `false` 把空值这条路堵掉; * - `allowCustom`:点「+ 新店」直接输新名字,选中即用(后端会自动登记进字典); * - `includeInactive`:停用的店铺也列出来(筛选/详情里要能看到历史值); * - 当前值不在字典里(老数据/刚自定义的名字)也会显示成一个按钮,不会被吞掉。 */ export default function HuyaCollabShopPicker({ value, shops, disabled, includeInactive = false, allowCustom = true, allowClear = true, clearLabel = '不填', size = 'small', onChange, }: { value?: string | null; shops: ShopOption[]; disabled?: boolean; includeInactive?: boolean; allowCustom?: boolean; /** 是否给一个「清空」按钮:店铺必填的地方传 false,别让人点出个空值 */ allowClear?: boolean; clearLabel?: string; /** 按钮尺寸:列表单元格 / 筛选条用小号,新建弹窗用大号(更好点) */ size?: 'small' | 'middle' | 'large'; /** 放进 Form.Item 时由 antd 注入;单独用时自己传 */ onChange?: (value: string) => void; }) { const [customOpen, setCustomOpen] = useState(false); const [customName, setCustomName] = useState(''); useEffect(() => { if (!customOpen) setCustomName(''); }, [customOpen]); const current = value ?? ''; const visible = shops.filter((shop) => includeInactive || shop.is_active); const options: { value: string; label: ReactNode }[] = visible.map((shop) => ({ value: shop.name, label: ( {shop.name} {!shop.is_active && 停用} ), })); if (current && !visible.some((shop) => shop.name === current)) { // 老数据 / 刚自定义的:照样给个可点的按钮,不然界面上看不出选中了啥 options.unshift({ value: current, label: current }); } const submitCustom = () => { const name = customName.trim(); if (!name) { setCustomOpen(false); return; } onChange?.(name); setCustomOpen(false); }; return ( {/* 一个店铺一个独立按钮,中间留白(原来是连成一排的分段控件,太小不好点) */} {options.map((option) => ( ))} {allowClear && ( )} {allowCustom && !disabled && !customOpen && ( )} {customOpen && ( setCustomName(event.target.value)} onPressEnter={submitCustom} onBlur={submitCustom} onKeyDown={(event) => { if (event.key === 'Escape') { setCustomName(''); setCustomOpen(false); } }} /> )} ); }