Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/BaseSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { getSeparatedContent, isValidCount } from '../utils/valueUtil';
import SelectContext from '../SelectContext';
import type { SelectContextProps } from '../SelectContext';
import Polite from './Polite';
import { SemanticName } from '../Select';

export type {
DisplayInfoType,
Expand Down Expand Up @@ -131,6 +132,8 @@ export type BaseSelectPropsWithoutPrivate = Omit<BaseSelectProps, keyof BaseSele
export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttributes {
className?: string;
style?: React.CSSProperties;
classNames?: Partial<Record<SemanticName, string>>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BaseSelect 里不应该反向引用 Select 的定义,因为 TreeSelect 和 Cascader 里是没有这个的。BaseSelect 应该只有 'prefix' | 'suffix' | 'input',然后 Select 里拓展出来

styles?: Partial<Record<SemanticName, React.CSSProperties>>;
title?: string;
showSearch?: boolean;
tagRender?: (props: CustomTagProps) => React.ReactElement;
Expand Down Expand Up @@ -291,6 +294,9 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
onKeyDown,
onMouseDown,

classNames: selectClassNames,
styles,

// Rest Props
...restProps
} = props;
Expand Down Expand Up @@ -720,9 +726,10 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
if (showSuffixIcon) {
arrowNode = (
<TransBtn
className={classNames(`${prefixCls}-arrow`, {
className={classNames(`${prefixCls}-arrow`, selectClassNames?.suffix, {
[`${prefixCls}-arrow-loading`]: loading,
})}
style={styles?.suffix}
customizeIcon={suffixIcon}
customizeIconProps={{
loading,
Expand Down Expand Up @@ -812,6 +819,8 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
) : (
<Selector
{...props}
prefixClassName={selectClassNames?.prefix}
prefixStyle={styles?.prefix}
domRef={selectorDomRef}
prefixCls={prefixCls}
inputElement={customizeInputElement}
Expand Down
3 changes: 3 additions & 0 deletions src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export type SelectHandler<ValueType, OptionType extends BaseOptionType = Default

type ArrayElementType<T> = T extends (infer E)[] ? E : T;

export type SemanticName = 'prefix' | 'suffix';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉有点少,结构上应该是和 Mentions 差不多:

  • root
  • prefix
  • suffix
  • input
  • popup
  • list
  • item
  • tag (多选时的展示内容,这个名字不一定好)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ps: 这个搞了 TreeSelect 和 Cascade 除了 option list 应该都是共用的

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tag 或许可以用 selection, 我先用 tag 好了,等后面在讨论一下,对应修改。先写具体逻辑。
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实有 tagRender 或许可以不提供这个,不然还得去改 rc-overflow
image
目前做到这样子好像够用了。
image

export interface SelectProps<ValueType = any, OptionType extends BaseOptionType = DefaultOptionType>
extends BaseSelectPropsWithoutPrivate {
prefixCls?: string;
Expand Down Expand Up @@ -157,6 +158,8 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
defaultValue?: ValueType | null;
maxCount?: number;
onChange?: (value: ValueType, option?: OptionType | OptionType[]) => void;
classNames?: Partial<Record<SemanticName, string>>;
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
}

function isRawValue(value: DraftValueType): value is RawValueType {
Expand Down
11 changes: 10 additions & 1 deletion src/Selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import useLock from '../hooks/useLock';
import { isValidateOpenKey } from '../utils/keyUtil';
import MultipleSelector from './MultipleSelector';
import SingleSelector from './SingleSelector';
import classNames from 'classnames';

export interface InnerSelectorProps {
prefixCls: string;
Expand Down Expand Up @@ -54,6 +55,8 @@ export interface RefSelectorProps {
}

export interface SelectorProps {
prefixClassName: string;
prefixStyle: React.CSSProperties;
id: string;
prefixCls: string;
showSearch?: boolean;
Expand Down Expand Up @@ -107,6 +110,8 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
const compositionStatusRef = useRef<boolean>(false);

const {
prefixClassName,
prefixStyle,
prefixCls,
open,
mode,
Expand Down Expand Up @@ -290,7 +295,11 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
onClick={onClick}
onMouseDown={onMouseDown}
>
{prefix && <div className={`${prefixCls}-prefix`}>{prefix}</div>}
{prefix && (
<div className={classNames(`${prefixCls}-prefix`, prefixClassName)} style={prefixStyle}>
{prefix}
</div>
)}
{selectNode}
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions src/TransBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { RenderNode } from './BaseSelect';

export interface TransBtnProps {
className: string;
style?: React.CSSProperties;
customizeIcon: RenderNode;
customizeIconProps?: any;
onMouseDown?: React.MouseEventHandler<HTMLSpanElement>;
Expand All @@ -12,7 +13,8 @@ export interface TransBtnProps {
}

const TransBtn: React.FC<TransBtnProps> = (props) => {
const { className, customizeIcon, customizeIconProps, children, onMouseDown, onClick } = props;
const { className, style, customizeIcon, customizeIconProps, children, onMouseDown, onClick } =
props;

const icon =
typeof customizeIcon === 'function' ? customizeIcon(customizeIconProps) : customizeIcon;
Expand All @@ -24,7 +26,7 @@ const TransBtn: React.FC<TransBtnProps> = (props) => {
event.preventDefault();
onMouseDown?.(event);
}}
style={{ userSelect: 'none', WebkitUserSelect: 'none' }}
style={{ userSelect: 'none', WebkitUserSelect: 'none', ...style }}
unselectable="on"
onClick={onClick}
aria-hidden
Expand Down
31 changes: 31 additions & 0 deletions tests/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2417,4 +2417,35 @@ describe('Select.Basic', () => {
expect(onBlur).toHaveBeenCalledTimes(2);
expect(inputElem.value).toEqual('bb');
});
it('support classnames and styles', () => {
const customClassNames = {
prefix: 'cutsom-prefix',
suffix: 'custom-suffix',
};
const customStyle = {
prefix: { color: 'red' },
suffix: { color: 'green' },
};
const { container } = render(
<Select
open
classNames={customClassNames}
styles={customStyle}
suffixIcon={<div>arrow</div>}
prefix="Foobar"
value={['bamboo']}
mode="multiple"
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
]}
/>,
);
const prefix = container.querySelector('.rc-select-prefix');
const suffix = container.querySelector('.rc-select-arrow');
expect(prefix).toHaveClass('cutsom-prefix');
expect(prefix).toHaveStyle('color: red');
expect(suffix).toHaveClass('custom-suffix');
expect(suffix).toHaveStyle('color: green');
});
});
Loading