diff --git a/src/BaseSelect/index.tsx b/src/BaseSelect/index.tsx index f2935015..f093559a 100644 --- a/src/BaseSelect/index.tsx +++ b/src/BaseSelect/index.tsx @@ -28,7 +28,16 @@ import SelectInput from '../SelectInput'; import type { ComponentsConfig } from '../hooks/useComponents'; import useComponents from '../hooks/useComponents'; -export type BaseSelectSemanticName = 'prefix' | 'suffix' | 'input' | 'clear'; +export type BaseSelectSemanticName = + | 'prefix' + | 'suffix' + | 'input' + | 'clear' + | 'placeholder' + | 'content' + | 'item' + | 'itemContent' + | 'itemRemove'; /** * ZombieJ: diff --git a/src/SelectInput/Content/MultipleContent.tsx b/src/SelectInput/Content/MultipleContent.tsx index 55497cc3..d49b5acf 100644 --- a/src/SelectInput/Content/MultipleContent.tsx +++ b/src/SelectInput/Content/MultipleContent.tsx @@ -42,6 +42,8 @@ export default React.forwardRef(function M maxTagPlaceholder: maxTagPlaceholderFromContext, maxTagTextLength, maxTagCount, + classNames, + styles, } = useBaseProps(); const selectionItemPrefixCls = `${prefixCls}-selection-item`; @@ -85,14 +87,25 @@ export default React.forwardRef(function M ) => ( - {content} + + {content} + {closable && ( (function M return ( : null} data={displayValues} renderItem={renderItem} diff --git a/src/SelectInput/Content/Placeholder.tsx b/src/SelectInput/Content/Placeholder.tsx index 6a1befd8..fec17d9e 100644 --- a/src/SelectInput/Content/Placeholder.tsx +++ b/src/SelectInput/Content/Placeholder.tsx @@ -1,5 +1,7 @@ import * as React from 'react'; +import { clsx } from 'clsx'; import { useSelectInputContext } from '../context'; +import useBaseProps from '../../hooks/useBaseProps'; export interface PlaceholderProps { show?: boolean; @@ -7,6 +9,7 @@ export interface PlaceholderProps { export default function Placeholder(props: PlaceholderProps) { const { prefixCls, placeholder, displayValues } = useSelectInputContext(); + const { classNames, styles } = useBaseProps(); const { show = true } = props; if (displayValues.length) { @@ -15,9 +18,10 @@ export default function Placeholder(props: PlaceholderProps) { return (
{placeholder} diff --git a/src/SelectInput/Content/SingleContent.tsx b/src/SelectInput/Content/SingleContent.tsx index 7ac0173b..47978e26 100644 --- a/src/SelectInput/Content/SingleContent.tsx +++ b/src/SelectInput/Content/SingleContent.tsx @@ -12,7 +12,7 @@ const SingleContent = React.forwardRef( ({ inputProps }, ref) => { const { prefixCls, searchValue, activeValue, displayValues, maxLength, mode } = useSelectInputContext(); - const { triggerOpen, title: rootTitle, showSearch } = useBaseProps(); + const { triggerOpen, title: rootTitle, showSearch, classNames, styles } = useBaseProps(); const selectContext = React.useContext(SelectContext); const [inputChanged, setInputChanged] = React.useState(false); @@ -71,7 +71,7 @@ const SingleContent = React.forwardRef( }, [combobox, activeValue]); return ( -
+
{displayValue ? (
{displayValue.label}
) : ( diff --git a/tests/BaseSelect.test.tsx b/tests/BaseSelect.test.tsx index 444d2872..d107743d 100644 --- a/tests/BaseSelect.test.tsx +++ b/tests/BaseSelect.test.tsx @@ -1,4 +1,4 @@ -import type { OptionListProps, RefOptionListProps } from '@/OptionList'; +import type { OptionListProps, RefOptionListProps } from '../src/OptionList'; import { fireEvent, render } from '@testing-library/react'; import { forwardRef, act } from 'react'; import BaseSelect from '../src/BaseSelect'; diff --git a/tests/semantic.test.tsx b/tests/semantic.test.tsx new file mode 100644 index 00000000..f3a1b39e --- /dev/null +++ b/tests/semantic.test.tsx @@ -0,0 +1,162 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import Select from '../src'; + +describe('Select Semantic Styles', () => { + const defaultProps = { + prefixCls: 'rc-select', + displayValues: [], + emptyOptions: true, + id: 'test', + onDisplayValuesChange: () => {}, + onSearch: () => {}, + searchValue: '', + }; + + it('should apply semantic classNames correctly', () => { + const classNames = { + prefix: 'custom-prefix', + suffix: 'custom-suffix', + input: 'custom-input', + clear: 'custom-clear', + placeholder: 'custom-placeholder', + content: 'custom-content', + item: 'custom-item', + itemContent: 'custom-item-content', + itemRemove: 'custom-item-remove', + }; + + const { container } = render( + Prefix} + suffix={Suffix} + />, + ); + + // Test prefix style + expect(container.querySelector('.rc-select-prefix')).toHaveStyle({ color: 'red' }); + + // Test suffix style + expect(container.querySelector('.rc-select-suffix')).toHaveStyle({ color: 'blue' }); + + // Test input style + expect(container.querySelector('.rc-select-input')).toHaveStyle({ fontSize: '16px' }); + + // Test content style + expect(container.querySelector('.rc-select-content')).toHaveStyle({ padding: '4px' }); + + // Test placeholder style + expect(container.querySelector('.rc-select-placeholder')).toHaveStyle({ opacity: 0.6 }); + }); + + it('should apply item semantic styles in multiple mode', () => { + const classNames = { + item: 'custom-item', + itemContent: 'custom-item-content', + itemRemove: 'custom-item-remove', + }; + + const styles = { + item: { margin: '2px' }, + itemContent: { fontWeight: 'bold' }, + itemRemove: { background: 'transparent' }, + }; + + const displayValues = [ + { key: '1', label: 'Option 1', value: '1' }, + { key: '2', label: 'Option 2', value: '2' }, + ]; + + const { container } = render( + , + ); + + // Test clear icon className and style + const clearIcon = container.querySelector('.rc-select-clear'); + expect(clearIcon).toHaveClass('custom-clear'); + expect(clearIcon).toHaveStyle({ cursor: 'pointer' }); + }); +});