Skip to content

Commit

Permalink
fix(dropdown): dropdown问题修复 (#150)
Browse files Browse the repository at this point in the history
* fix(icon): 修复icon不居中显示和class重复设置问题

* fix(icon): 修复icon不居中显示和class重复设置问题

* fix(icon): 修复icon不居中显示和class重复设置问题

* fix(watermark): 修复watermark无法生成水印及其它展示问题

* fix(message): 临时使用console代替

* feat(select-input): 增加select-input组件

* refactor(input): restore input

* perf(popup): 优化popup dom结构

* feat(popup): 优化popup

* feat(input-select): add input-select

* fix(omi-transition): 动画enter、leave多次同时运行问题修复

* feat(select-input): add select-input

* feat(select-input): add select-input

* feat(select-input): 去除--force

* feat(select-input): 优化css字符串

* fix(dropdown): dropdown问题修复
  • Loading branch information
duenyang authored Sep 25, 2024
1 parent c138fc7 commit 6415f4a
Show file tree
Hide file tree
Showing 7 changed files with 575 additions and 19 deletions.
6 changes: 2 additions & 4 deletions src/dropdown/_example/child.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function BasicDropdown() {
MessagePlugin.success(`选中【${data.value}】`);
};
return (
<t-dropdown minColumnWidth={100} trigger="click">
<t-dropdown minColumnWidth={100} trigger="click" onClick={clickHandler}>
<t-button variant="text" suffix={<t-icon name="chevron-down" size="16" />}>
更多
</t-button>
Expand Down Expand Up @@ -39,9 +39,7 @@ export default function BasicDropdown() {
<t-dropdown-item value={211}>操作2-1-2</t-dropdown-item>
</t-dropdown-menu>
</t-dropdown-item>
<t-dropdown-item value={22} onClick={clickHandler}>
操作2-2
</t-dropdown-item>
<t-dropdown-item value={22}>操作2-2</t-dropdown-item>
</t-dropdown-menu>
</t-dropdown-item>
<t-dropdown-item value={3}>操作三</t-dropdown-item>
Expand Down
32 changes: 22 additions & 10 deletions src/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './dropdownItem';
import './dropdownMenu';
import '../popup';

import { isFunction } from 'lodash';
import omit from 'lodash/omit';
import { Component, css, tag } from 'omi';

Expand Down Expand Up @@ -59,8 +60,23 @@ export default class Dropdown extends Component<DropdownProps> {
this.options = getDropdownOptions(this.props.children as TNode[], this.props.options);
}

getOverlayInnerStyle = () => {
const { popupProps } = this.props;
if (!popupProps?.overlayInnerStyle) return { padding: 0 };
if (isFunction(popupProps.overlayInnerStyle)) {
return (triggerElement: HTMLElement, popupElement: HTMLElement) => ({
padding: 0,
...(popupProps as any).overlayInnerStyle(triggerElement, popupElement),
});
}
return {
padding: 0,
...(popupProps?.overlayInnerStyle || {}),
};
};

render(props: DropdownProps) {
const { popupProps = {}, disabled, placement, trigger, className, children, popupCss, style } = props;
const { popupProps = {}, disabled, placement, trigger, innerClass, children, innerStyle } = props;

const renderContent = <t-dropdown-menu {...props} options={this.options} onClick={this.handleMenuClick} />;

Expand All @@ -71,22 +87,18 @@ export default class Dropdown extends Component<DropdownProps> {
showArrow: false,
content: renderContent,
...omit(popupProps, 'onVisibleChange'),
overlayInnerClassName: classNames(`${getClassPrefix()}-dropdown`, className, popupProps?.overlayInnerClassName),
overlayInnerStyle: style,
overlayInnerClassName: classNames(`${getClassPrefix()}-dropdown`, popupProps?.overlayInnerClassName),
overlayInnerStyle: this.getOverlayInnerStyle(),
};

return (
<t-popup
expandAnimation={false}
destroyOnClose={true}
// destroyOnClose={true}
visible={this.isPopupVisible}
onVisibleChange={this.handleVisibleChange}
css={`
.${getClassPrefix()}-dropdown {
padding: 0px !important;
}
${popupCss || ''}
`}
innerClass={innerClass}
innerStyle={innerStyle}
{...popupParams}
>
{children?.[0]}
Expand Down
15 changes: 10 additions & 5 deletions src/dropdown/dropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,18 @@ export default class DropdownMenu extends Component<DropdownProps> {
this.update();
};

throttleUpdate = throttle(this.handleScroll, 100);
throttleUpdate = throttle(this.handleScroll, 10);

renderOptions = (data: Array<DropdownOption | TNode>, deep: number) => {
const { minColumnWidth = 10, maxColumnWidth = 160 } = this.props;
const arr = [];
let renderContent: TNode;
data.forEach?.((menu, idx) => {
const optionItem = { ...(menu as DropdownOption) };
const onViewIdx = Math.ceil(this.calcScrollTopMap[deep] / 30);
const isOverflow = idx >= onViewIdx;
const itemIdx = isOverflow ? idx - onViewIdx : idx;

// 只有第一层子节点需要加上 panelTopContent 的高度
const shouldCalcPanelTopContent = this.props.panelTopContent && deep > 0;

if (optionItem.children) {
optionItem.children = this.renderOptions(optionItem.children, deep + 1);
renderContent = (
Expand Down Expand Up @@ -113,7 +114,11 @@ export default class DropdownMenu extends Component<DropdownProps> {
})}
style={{
position: 'absolute',
top: `${itemIdx * 30 + (isOverflow ? 0 : this.panelTopContentHeight)}px`,
top: `${
idx * 30 -
this.calcScrollTopMap[deep] +
(shouldCalcPanelTopContent ? 0 : this.panelTopContentHeight)
}px`,
}}
>
<div
Expand Down
28 changes: 28 additions & 0 deletions src/select/defaultProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TdOptionGroupProps, TdOptionProps, TdSelectProps } from './type';

export const selectDefaultProps: TdSelectProps = {
autoWidth: false,
autofocus: false,
borderless: false,
clearable: false,
creatable: false,
loading: false,
max: 0,
minCollapsedNum: 0,
multiple: false,
placeholder: undefined,
readonly: false,
reserveKeyword: false,
showArrow: true,
size: 'medium',
status: 'default',
valueType: 'value',
};

export const optionDefaultProps: TdOptionProps = { checkAll: false, disabled: false };

export const optionGroupDefaultProps: TdOptionGroupProps = { divider: true };
167 changes: 167 additions & 0 deletions src/select/option.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// import classNames from 'classnames';
// import get from 'lodash/get';
// import isNumber from 'lodash/isNumber';
// import isString from 'lodash/isString';

// import classname, { getClassPrefix } from '../_util/classname';
// import { StyledProps, TNode } from '../common';
// import { SelectKeysType, SelectOption, SelectValue, TdOptionProps, TdSelectProps } from './type';

// /**
// * Option 组件属性
// */
// export interface SelectOptionProps
// extends StyledProps,
// TdOptionProps,
// Pick<TdSelectProps, 'size' | 'multiple' | 'max'> {
// selectedValue?: SelectValue;
// children?: TNode;
// onSelect?: (
// value: string | number,
// context: {
// label?: string;
// selected?: boolean;
// event: MouseEvent;
// restData?: Record<string, any>;
// },
// ) => void;
// onCheckAllChange?: (checkAll: boolean, e: MouseEvent) => void;
// restData?: Record<string, any>;
// keys?: SelectKeysType;
// optionLength?: number;
// isVirtual?: boolean;
// onRowMounted?: (rowData: { ref: HTMLElement; data: SelectOption }) => void;
// }

// const componentType = 'select';

// const Option = (props: SelectOptionProps) => {
// const {
// disabled: propDisabled,
// label: propLabel,
// title: propTitle,
// selectedValue,
// checkAll,
// multiple,
// size,
// max,
// keys,
// value,
// onSelect,
// children,
// content,
// restData,
// style,
// className,
// isVirtual,
// } = props;

// let selected: boolean;
// let indeterminate: boolean;
// const label = propLabel || value;
// const disabled = propDisabled || (multiple && Array.isArray(selectedValue) && max && selectedValue.length >= max);

// const titleContent = useMemo(() => {
// // 外部设置 props,说明希望受控
// const controlledTitle = Reflect.has(props, 'title');
// if (controlledTitle) return propTitle;
// if (typeof label === 'string') return label;
// return null;
// }, [propTitle, label]);

// const { classPrefix } = useConfig();

// // 使用斜八角动画
// const [optionRef, setRefCurrent] = useDomRefCallback();

// useEffect(() => {
// if (isVirtual && optionRef) {
// props.onRowMounted?.({
// ref: optionRef,
// data: props,
// });
// }
// // eslint-disable-next-line
// }, [isVirtual, optionRef]);

// useRipple(optionRef);

// // 处理单选场景
// if (!multiple) {
// selected =
// isNumber(selectedValue) || isString(selectedValue)
// ? value === selectedValue
// : value === get(selectedValue, keys?.value || 'value');
// }
// // 处理多选场景
// if (multiple && Array.isArray(selectedValue)) {
// selected = selectedValue.some((item) => {
// if (isNumber(item) || isString(item)) {
// // 如果非 object 类型
// return item === value;
// }
// return get(item, keys?.value || 'value') === value;
// });
// if (props.checkAll) {
// selected = selectedValue.length === props.optionLength;
// indeterminate = selectedValue.length > 0 && !selected;
// }
// }

// const handleSelect = (event: MouseEvent) => {
// if (!disabled && !checkAll) {
// onSelect(value, { label: String(label), selected, event, restData });
// }
// if (checkAll) {
// props.onCheckAllChange?.(selected, event);
// }
// };

// const renderItem = (children: TNode) => {
// if (multiple) {
// return (
// <label
// className={classNames(`${classPrefix}-checkbox`, {
// [`${classPrefix}-is-indeterminate`]: indeterminate,
// [`${classPrefix}-is-disabled`]: disabled,
// [`${classPrefix}-is-checked`]: selected,
// })}
// title={titleContent}
// >
// <input
// type="checkbox"
// className={classNames(`${classPrefix}-checkbox__former`)}
// value=""
// disabled={disabled && !selected}
// onClick={(e) => {
// e.stopPropagation();
// e.stopImmediatePropagation();
// }}
// />
// <span className={classNames(`${classPrefix}-checkbox__input`)}></span>
// <span className={classNames(`${classPrefix}-checkbox__label`)}>{children || content || label}</span>
// </label>
// );
// }
// return <span title={titleContent}>{children || content || label}</span>;
// };

// return (
// <li
// className={classNames(className, `${classPrefix}-${componentType}-option`, {
// [`${classPrefix}-is-disabled`]: disabled,
// [`${classPrefix}-is-selected`]: selected,
// [`${classPrefix}-size-s`]: size === 'small',
// [`${classPrefix}-size-l`]: size === 'large',
// })}
// key={value}
// onClick={handleSelect}
// ref={setRefCurrent}
// style={style}
// >
// {renderItem(children)}
// </li>
// );
// };

// export default Option;
9 changes: 9 additions & 0 deletions src/select/style/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { css, globalCSS } from 'omi';

import styles from '../../_common/style/web/components/select/_index.less';

export const styleSheet = css`
${styles}
`;

globalCSS(styleSheet);
Loading

0 comments on commit 6415f4a

Please sign in to comment.