From b5636646c99045cb8b02dbf231827c7693b75255 Mon Sep 17 00:00:00 2001 From: Teo Date: Thu, 12 Jun 2025 12:03:04 +0800 Subject: [PATCH] refactor(Selector): enhance Selector component with option grouping, disabled state handling, and improved label retrieval logic --- src/renderer/src/components/Selector.tsx | 79 ++++++++++++++----- .../src/pages/paintings/AihubmixPage.tsx | 2 + .../src/pages/paintings/DmxapiPage.tsx | 7 +- .../src/pages/paintings/SiliconPage.tsx | 1 + .../src/pages/paintings/TokenFluxPage.tsx | 1 + .../pages/paintings/components/Artboard.tsx | 4 +- 6 files changed, 70 insertions(+), 24 deletions(-) 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 = ({ -