Files
video-gen/video-gen-admin/node_modules/@rc-component/select/es/SelectInput/index.js
T
2026-05-25 17:08:18 +08:00

217 lines
7.2 KiB
JavaScript

function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import * as React from 'react';
import Affix from "./Affix";
import SelectContent from "./Content";
import SelectInputContext from "./context";
import useBaseProps from "../hooks/useBaseProps";
import { omit, useEvent } from '@rc-component/util';
import KeyCode from "@rc-component/util/es/KeyCode";
import { isValidateOpenKey } from "../utils/keyUtil";
import { clsx } from 'clsx';
import { getDOM } from "@rc-component/util/es/Dom/findDOMNode";
import { composeRef } from "@rc-component/util/es/ref";
import pickAttrs from "@rc-component/util/es/pickAttrs";
const DEFAULT_OMIT_PROPS = ['value', 'onChange', 'removeIcon', 'placeholder', 'maxTagCount', 'maxTagTextLength', 'maxTagPlaceholder', 'choiceTransitionName', 'onInputKeyDown', 'onPopupScroll', 'tabIndex', 'activeValue', 'onSelectorRemove', 'focused'];
export default /*#__PURE__*/React.forwardRef(function SelectInput(props, ref) {
const {
// Style
prefixCls,
className,
style,
// UI
prefix,
suffix,
clearIcon,
children,
// Data
multiple,
displayValues,
placeholder,
mode,
// Search
searchValue,
onSearch,
onSearchSubmit,
onInputBlur,
// Input
maxLength,
autoFocus,
// Events
onMouseDown,
onClearMouseDown,
onInputKeyDown,
onSelectorRemove,
// Token handling
tokenWithEnter,
// Components
components,
...restProps
} = props;
const {
triggerOpen,
toggleOpen,
showSearch,
disabled,
loading,
classNames,
styles
} = useBaseProps();
const rootRef = React.useRef(null);
const inputRef = React.useRef(null);
// Handle keyboard events similar to original Selector
const onInternalInputKeyDown = useEvent(event => {
const {
which
} = event;
// Compatible with multiple lines in TextArea
const isTextAreaElement = inputRef.current instanceof HTMLTextAreaElement;
// Prevent default behavior for up/down arrows when dropdown is open
if (!isTextAreaElement && triggerOpen && (which === KeyCode.UP || which === KeyCode.DOWN)) {
event.preventDefault();
}
// Call the original onInputKeyDown callback
if (onInputKeyDown) {
onInputKeyDown(event);
}
// Move within the text box for TextArea
if (isTextAreaElement && !triggerOpen && ~[KeyCode.UP, KeyCode.DOWN, KeyCode.LEFT, KeyCode.RIGHT].indexOf(which)) {
return;
}
// Open dropdown when a valid open key is pressed
const isModifier = event.ctrlKey || event.altKey || event.metaKey;
if (!isModifier && isValidateOpenKey(which)) {
toggleOpen(true);
}
});
// ====================== Refs ======================
React.useImperativeHandle(ref, () => {
return {
focus: options => {
// Focus the inner input if available, otherwise fall back to root div.
(inputRef.current || rootRef.current).focus?.(options);
},
blur: () => {
(inputRef.current || rootRef.current).blur?.();
},
// Use getDOM to handle nested nativeElement structure (e.g., when RootComponent is antd Input)
nativeElement: getDOM(rootRef.current)
};
});
// ====================== Open ======================
const onInternalMouseDown = useEvent(event => {
if (!disabled) {
const inputDOM = getDOM(inputRef.current);
// https://github.com/ant-design/ant-design/issues/56002
// Tell `useSelectTriggerControl` to ignore this event
// When icon is dynamic render, the parentNode will miss
// so we need to mark the event directly
event.nativeEvent._ori_target = inputDOM;
const isClickOnInput = inputDOM === event.target || inputDOM?.contains(event.target);
if (inputDOM && !isClickOnInput) {
event.preventDefault();
}
// Check if we should prevent closing when clicking on selector
// Don't close if: open && not multiple && (combobox mode || showSearch)
const shouldPreventCloseOnSingle = triggerOpen && !multiple && (mode === 'combobox' || showSearch);
// Don't close if: open && multiple && click on input
const shouldPreventCloseOnMultipleInput = triggerOpen && multiple && isClickOnInput;
const shouldPreventClose = shouldPreventCloseOnSingle || shouldPreventCloseOnMultipleInput;
if (!event.nativeEvent._select_lazy) {
inputRef.current?.focus();
// Only toggle open if we should not prevent close
if (!shouldPreventClose) {
toggleOpen();
}
} else if (triggerOpen) {
// Lazy should also close when click clear icon
toggleOpen(false);
}
}
onMouseDown?.(event);
});
// =================== Components ===================
const {
root: RootComponent
} = components;
// ===================== Render =====================
const domProps = omit(restProps, DEFAULT_OMIT_PROPS);
const ariaProps = pickAttrs(domProps, {
aria: true
});
const ariaKeys = Object.keys(ariaProps);
// Create context value with wrapped callbacks
const contextValue = {
...props,
onInputKeyDown: onInternalInputKeyDown
};
if (RootComponent) {
const originProps = RootComponent.props || {};
const mergedProps = {
...originProps,
...domProps
};
Object.keys(originProps).forEach(key => {
const originVal = originProps[key];
const domVal = domProps[key];
if (typeof originVal === 'function' && typeof domVal === 'function') {
mergedProps[key] = (...args) => {
domVal(...args);
originVal(...args);
};
}
});
if ( /*#__PURE__*/React.isValidElement(RootComponent)) {
return /*#__PURE__*/React.cloneElement(RootComponent, {
...mergedProps,
ref: composeRef(RootComponent.ref, rootRef)
});
}
return /*#__PURE__*/React.createElement(RootComponent, _extends({}, mergedProps, {
ref: rootRef
}));
}
return /*#__PURE__*/React.createElement(SelectInputContext.Provider, {
value: contextValue
}, /*#__PURE__*/React.createElement("div", _extends({}, omit(domProps, ariaKeys), {
// Style
ref: rootRef,
className: className,
style: style
// Mouse Events
,
onMouseDown: onInternalMouseDown
}), /*#__PURE__*/React.createElement(Affix, {
className: clsx(`${prefixCls}-prefix`, classNames?.prefix),
style: styles?.prefix
}, prefix), /*#__PURE__*/React.createElement(SelectContent, {
ref: inputRef
}), /*#__PURE__*/React.createElement(Affix, {
className: clsx(`${prefixCls}-suffix`, {
[`${prefixCls}-suffix-loading`]: loading
}, classNames?.suffix),
style: styles?.suffix
}, suffix), clearIcon && /*#__PURE__*/React.createElement(Affix, {
className: clsx(`${prefixCls}-clear`, classNames?.clear),
style: styles?.clear,
onMouseDown: e => {
// Mark to tell not trigger open or focus
e.nativeEvent._select_lazy = true;
onClearMouseDown?.(e);
}
}, clearIcon), children));
});