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

403 lines
14 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _clsx = require("clsx");
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
var _useMemo = _interopRequireDefault(require("@rc-component/util/lib/hooks/useMemo"));
var _omit = _interopRequireDefault(require("@rc-component/util/lib/omit"));
var _pickAttrs = _interopRequireDefault(require("@rc-component/util/lib/pickAttrs"));
var _virtualList = _interopRequireDefault(require("@rc-component/virtual-list"));
var _react = _interopRequireWildcard(require("react"));
var React = _react;
var _SelectContext = _interopRequireDefault(require("./SelectContext"));
var _TransBtn = _interopRequireDefault(require("./TransBtn"));
var _useBaseProps = _interopRequireDefault(require("./hooks/useBaseProps"));
var _platformUtil = require("./utils/platformUtil");
var _valueUtil = require("./utils/valueUtil");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
// export interface OptionListProps<OptionsType extends object[]> {
function isTitleType(content) {
return typeof content === 'string' || typeof content === 'number';
}
/**
* Using virtual list of option display.
* Will fallback to dom if use customize render.
*/
const OptionList = (_, ref) => {
const {
prefixCls,
id,
open,
multiple,
mode,
searchValue,
toggleOpen,
notFoundContent,
onPopupScroll,
showScrollBar,
lockOptions
} = (0, _useBaseProps.default)();
const {
maxCount,
flattenOptions,
onActiveValue,
defaultActiveFirstOption,
onSelect,
menuItemSelectedIcon,
rawValues,
fieldNames,
virtual,
direction,
listHeight,
listItemHeight,
optionRender,
classNames: contextClassNames,
styles: contextStyles
} = React.useContext(_SelectContext.default);
const itemPrefixCls = `${prefixCls}-item`;
const memoFlattenOptions = (0, _useMemo.default)(() => flattenOptions, [open, lockOptions], (prev, next) => next[0] && !next[1]);
// =========================== List ===========================
const listRef = React.useRef(null);
const overMaxCount = React.useMemo(() => multiple && (0, _valueUtil.isValidCount)(maxCount) && rawValues?.size >= maxCount, [multiple, maxCount, rawValues?.size]);
const onListMouseDown = event => {
event.preventDefault();
};
const scrollIntoView = args => {
listRef.current?.scrollTo(typeof args === 'number' ? {
index: args
} : args);
};
// https://github.com/ant-design/ant-design/issues/34975
const isSelected = React.useCallback(value => {
if (mode === 'combobox') {
return false;
}
return rawValues.has(value);
}, [mode, [...rawValues].toString(), rawValues.size]);
// ========================== Active ==========================
const getEnabledActiveIndex = (index, offset = 1) => {
const len = memoFlattenOptions.length;
for (let i = 0; i < len; i += 1) {
const current = (index + i * offset + len) % len;
const {
group,
data
} = memoFlattenOptions[current] || {};
if (!group && !data?.disabled && (isSelected(data.value) || !overMaxCount)) {
return current;
}
}
return -1;
};
const [activeIndex, setActiveIndex] = React.useState(() => getEnabledActiveIndex(0));
const setActive = (index, fromKeyboard = false) => {
setActiveIndex(index);
const info = {
source: fromKeyboard ? 'keyboard' : 'mouse'
};
// Trigger active event
const flattenItem = memoFlattenOptions[index];
if (!flattenItem) {
onActiveValue(null, -1, info);
return;
}
onActiveValue(flattenItem.value, index, info);
};
// Auto active first item when list length or searchValue changed
(0, _react.useEffect)(() => {
setActive(defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
}, [memoFlattenOptions.length, searchValue]);
// https://github.com/ant-design/ant-design/issues/48036
const isAriaSelected = React.useCallback(value => {
if (mode === 'combobox') {
return String(value).toLowerCase() === searchValue.toLowerCase();
}
return rawValues.has(value);
}, [mode, searchValue, [...rawValues].toString(), rawValues.size]);
// Auto scroll to item position in single mode
(0, _react.useEffect)(() => {
/**
* React will skip `onChange` when component update.
* `setActive` function will call root accessibility state update which makes re-render.
* So we need to delay to let Input component trigger onChange first.
*/
let timeoutId;
if (!multiple && open && rawValues.size === 1) {
const value = Array.from(rawValues)[0];
// Scroll to the option closest to the searchValue if searching.
const index = memoFlattenOptions.findIndex(({
data
}) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
if (index !== -1) {
setActive(index);
timeoutId = setTimeout(() => {
scrollIntoView(index);
});
}
}
// Force trigger scrollbar visible when open
if (open) {
listRef.current?.scrollTo(undefined);
}
return () => clearTimeout(timeoutId);
}, [open, searchValue]);
// ========================== Values ==========================
const onSelectValue = value => {
if (value !== undefined) {
onSelect(value, {
selected: !rawValues.has(value)
});
}
// Single mode should always close by select
if (!multiple) {
toggleOpen(false);
}
};
// ========================= Keyboard =========================
React.useImperativeHandle(ref, () => ({
onKeyDown: event => {
const {
which,
ctrlKey
} = event;
switch (which) {
// >>> Arrow keys & ctrl + n/p on Mac
case _KeyCode.default.N:
case _KeyCode.default.P:
case _KeyCode.default.UP:
case _KeyCode.default.DOWN:
{
let offset = 0;
if (which === _KeyCode.default.UP) {
offset = -1;
} else if (which === _KeyCode.default.DOWN) {
offset = 1;
} else if ((0, _platformUtil.isPlatformMac)() && ctrlKey) {
if (which === _KeyCode.default.N) {
offset = 1;
} else if (which === _KeyCode.default.P) {
offset = -1;
}
}
if (offset !== 0) {
const nextActiveIndex = getEnabledActiveIndex(activeIndex + offset, offset);
scrollIntoView(nextActiveIndex);
setActive(nextActiveIndex, true);
}
break;
}
// >>> Select (Tab / Enter)
case _KeyCode.default.TAB:
case _KeyCode.default.ENTER:
{
// value
const item = memoFlattenOptions[activeIndex];
if (!item || item.data.disabled) {
return onSelectValue(undefined);
}
if (!overMaxCount || rawValues.has(item.value)) {
onSelectValue(item.value);
} else {
onSelectValue(undefined);
}
if (open) {
event.preventDefault();
}
break;
}
// >>> Close
case _KeyCode.default.ESC:
{
toggleOpen(false);
if (open) {
event.stopPropagation();
}
}
}
},
onKeyUp: () => {},
scrollTo: index => {
scrollIntoView(index);
}
}));
// ========================== Render ==========================
if (memoFlattenOptions.length === 0) {
return /*#__PURE__*/React.createElement("div", {
role: "listbox",
id: `${id}_list`,
className: `${itemPrefixCls}-empty`,
onMouseDown: onListMouseDown
}, notFoundContent);
}
const omitFieldNameList = Object.keys(fieldNames).map(key => fieldNames[key]);
const getLabel = item => item.label;
function getItemAriaProps(item, index) {
const {
group
} = item;
return {
role: group ? 'presentation' : 'option',
id: `${id}_list_${index}`
};
}
const renderItem = index => {
const item = memoFlattenOptions[index];
if (!item) {
return null;
}
const itemData = item.data || {};
const {
value,
disabled
} = itemData;
const {
group
} = item;
const attrs = (0, _pickAttrs.default)(itemData, true);
const mergedLabel = getLabel(item);
return item ? /*#__PURE__*/React.createElement("div", _extends({
"aria-label": typeof mergedLabel === 'string' && !group ? mergedLabel : null
}, attrs, {
key: index
}, getItemAriaProps(item, index), {
"aria-selected": isAriaSelected(value),
"aria-disabled": disabled
}), value) : null;
};
const a11yProps = {
role: 'listbox',
id: `${id}_list`
};
return /*#__PURE__*/React.createElement(React.Fragment, null, virtual && /*#__PURE__*/React.createElement("div", _extends({}, a11yProps, {
style: {
height: 0,
width: 0,
overflow: 'hidden'
}
}), renderItem(activeIndex - 1), renderItem(activeIndex), renderItem(activeIndex + 1)), /*#__PURE__*/React.createElement(_virtualList.default, {
itemKey: "key",
ref: listRef,
data: memoFlattenOptions,
height: listHeight,
itemHeight: listItemHeight,
fullHeight: false,
onMouseDown: onListMouseDown,
onScroll: onPopupScroll,
virtual: virtual,
direction: direction,
innerProps: virtual ? null : a11yProps,
showScrollBar: showScrollBar,
className: contextClassNames?.popup?.list,
style: contextStyles?.popup?.list
}, (item, itemIndex) => {
const {
group,
groupOption,
data,
label,
value
} = item;
const {
key
} = data;
// Group
if (group) {
const groupTitle = data.title ?? (isTitleType(label) ? label.toString() : undefined);
return /*#__PURE__*/React.createElement("div", {
className: (0, _clsx.clsx)(itemPrefixCls, `${itemPrefixCls}-group`, data.className),
title: groupTitle
}, label !== undefined ? label : key);
}
const {
disabled,
title,
children,
style,
className,
...otherProps
} = data;
const passedProps = (0, _omit.default)(otherProps, omitFieldNameList);
// Option
const selected = isSelected(value);
const mergedDisabled = disabled || !selected && overMaxCount;
const optionPrefixCls = `${itemPrefixCls}-option`;
const optionClassName = (0, _clsx.clsx)(itemPrefixCls, optionPrefixCls, className, contextClassNames?.popup?.listItem, {
[`${optionPrefixCls}-grouped`]: groupOption,
[`${optionPrefixCls}-active`]: activeIndex === itemIndex && !mergedDisabled,
[`${optionPrefixCls}-disabled`]: mergedDisabled,
[`${optionPrefixCls}-selected`]: selected
});
const mergedLabel = getLabel(item);
const iconVisible = !menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
// https://github.com/ant-design/ant-design/issues/34145
const content = typeof mergedLabel === 'number' ? mergedLabel : mergedLabel || value;
// https://github.com/ant-design/ant-design/issues/26717
let optionTitle = isTitleType(content) ? content.toString() : undefined;
if (title !== undefined) {
optionTitle = title;
}
return /*#__PURE__*/React.createElement("div", _extends({}, (0, _pickAttrs.default)(passedProps), !virtual ? getItemAriaProps(item, itemIndex) : {}, {
"aria-selected": virtual ? undefined : isAriaSelected(value),
"aria-disabled": mergedDisabled,
className: optionClassName,
title: optionTitle,
onMouseMove: () => {
if (activeIndex === itemIndex || mergedDisabled) {
return;
}
setActive(itemIndex);
},
onClick: () => {
if (!mergedDisabled) {
onSelectValue(value);
}
},
style: {
...contextStyles?.popup?.listItem,
...style
}
}), /*#__PURE__*/React.createElement("div", {
className: `${optionPrefixCls}-content`
}, typeof optionRender === 'function' ? optionRender(item, {
index: itemIndex
}) : content), /*#__PURE__*/React.isValidElement(menuItemSelectedIcon) || selected, iconVisible && /*#__PURE__*/React.createElement(_TransBtn.default, {
className: `${itemPrefixCls}-option-state`,
customizeIcon: menuItemSelectedIcon,
customizeIconProps: {
value,
disabled: mergedDisabled,
isSelected: selected
}
}, selected ? '✓' : null));
}));
};
const RefOptionList = /*#__PURE__*/React.forwardRef(OptionList);
if (process.env.NODE_ENV !== 'production') {
RefOptionList.displayName = 'OptionList';
}
var _default = exports.default = RefOptionList;