diff --git a/src/renderer/src/components/Selector.tsx b/src/renderer/src/components/Selector.tsx index 1889b01d28..a08ff9af1f 100644 --- a/src/renderer/src/components/Selector.tsx +++ b/src/renderer/src/components/Selector.tsx @@ -3,13 +3,23 @@ import { Check, ChevronsUpDown } from 'lucide-react' import { ReactNode, useMemo, useState } from 'react' import styled, { createGlobalStyle, css } from 'styled-components' +interface SelectorOption { + label: string | ReactNode + value: V + type?: 'group' + options?: SelectorOption[] + disabled?: boolean +} + interface SelectorProps { - options: { label: string | ReactNode; value: V }[] + options: SelectorOption[] value?: V placeholder?: string placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight' | 'top' | 'bottom' /** 字体大小 */ size?: number + /** 是否禁用 */ + disabled?: boolean onChange: (value: V) => void } @@ -19,27 +29,47 @@ const Selector = ({ onChange = () => {}, placement = 'bottomRight', size = 13, - placeholder + placeholder = '待选择', + disabled = false }: SelectorProps) => { const [open, setOpen] = useState(false) const label = useMemo(() => { if (value) { - return options?.find((option) => option.value === value)?.label + const findLabel = (opts: SelectorOption[]): string | ReactNode | undefined => { + for (const opt of opts) { + if (opt.value === value) { + return opt.label + } + if (opt.options) { + const found = findLabel(opt.options) + if (found) return found + } + } + return undefined + } + return findLabel(options) || placeholder } return placeholder }, [options, value, placeholder]) const items = useMemo(() => { - return options.map((option) => ({ + const mapOption = (option: SelectorOption) => ({ key: option.value, label: option.label, - extra: {option.value === value && } - })) + extra: {option.value === value && }, + disabled: option.disabled, + type: option.type || (option.options ? 'group' : undefined), + children: option.options?.map(mapOption) + }) + + return options.map(mapOption) }, [options, value]) function onClick(e: { key: string }) { - onChange(e.key as V) + if (!disabled) { + onChange(e.key as V) + } } return ( @@ -55,11 +85,11 @@ const Selector = ({ -