select 超过 100 行数据时才使用 virtual list,这样就不需要每次都加上滚动条宽度了

This commit is contained in:
wuduoyi 2020-08-19 21:54:22 +08:00
parent dd2b5e0959
commit 40b7f5b60d
2 changed files with 86 additions and 85 deletions

View File

@ -759,52 +759,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
const itemHeight = this.state.itemHeight;
const menu = (
<div ref={this.menu} className={cx('Select-menu')}>
{searchable ? (
<div
className={cx(`Select-input`, {
'is-focused': this.state.isFocused
})}
>
<Icon icon="search" className="icon" />
<Input
{...getInputProps({
onFocus: this.onFocus,
onBlur: this.onBlur,
disabled: disabled,
placeholder: __(searchPromptText),
onChange: this.handleInputChange,
ref: this.inputRef
})}
/>
</div>
) : null}
{multiple && checkAll && filtedOptions.length ? (
<div className={cx('Select-option')}>
<Checkbox
checked={checkedPartial}
partial={checkedPartial && !checkedAll}
onChange={this.toggleCheckAll}
>
{__(checkAllLabel)}
</Checkbox>
</div>
) : null}
<div ref={this.menuItemRef} className={cx('Select-option invisible')}>
<span>Placeholder</span>
</div>
{filtedOptions.length ? (
<VirtualList
height={
filtedOptions.length > 8 ? 280 : filtedOptions.length * itemHeight
}
itemCount={filtedOptions.length}
itemSize={itemHeight}
renderItem={({index, style}) => {
// 渲染单个选项
const renderItem = ({index, style}) => {
const item = filtedOptions[index];
const checked =
selectedItem === item ||
@ -879,8 +835,58 @@ export class Select extends React.Component<SelectProps, SelectState> {
)}
</div>
);
}}
}
const menu = (
<div ref={this.menu} className={cx('Select-menu')}>
{searchable ? (
<div
className={cx(`Select-input`, {
'is-focused': this.state.isFocused
})}
>
<Icon icon="search" className="icon" />
<Input
{...getInputProps({
onFocus: this.onFocus,
onBlur: this.onBlur,
disabled: disabled,
placeholder: __(searchPromptText),
onChange: this.handleInputChange,
ref: this.inputRef
})}
/>
</div>
) : null}
{multiple && checkAll && filtedOptions.length ? (
<div className={cx('Select-option')}>
<Checkbox
checked={checkedPartial}
partial={checkedPartial && !checkedAll}
onChange={this.toggleCheckAll}
>
{__(checkAllLabel)}
</Checkbox>
</div>
) : null}
<div ref={this.menuItemRef} className={cx('Select-option invisible')}>
<span>Placeholder</span>
</div>
{filtedOptions.length ? (
filtedOptions.length > 100 ? ( // 超过 100 个数据才启用 virtuallist 避免滚动条问题
<VirtualList
height={
filtedOptions.length > 8 ? 280 : filtedOptions.length * itemHeight
}
itemCount={filtedOptions.length}
itemSize={itemHeight}
renderItem={renderItem}
/>): (
filtedOptions.map((item, index) => { return renderItem({index}) })
)
) : (
<div className={cx('Select-noResult')}>{__(noResultsText)}</div>
)}

View File

@ -177,12 +177,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
}
// 自适应宽度
updateRootWidth(isDidUpdate: boolean = false) {
let scrollbarWidth =
window.innerWidth - document.documentElement.clientWidth || 15;
if (isDidUpdate) {
scrollbarWidth = 0;
}
updateRootWidth() {
const itemsDom = this.rootNode.children[0].children;
const containerWidth = this.rootNode.parentElement!.getBoundingClientRect()
.width;
@ -196,7 +191,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
if (containerWidth >= maxItemWidth) {
this.rootNode.style.width = containerWidth + 'px';
} else {
this.rootNode.style.width = maxItemWidth + scrollbarWidth + 'px';
this.rootNode.style.width = maxItemWidth + 'px';
}
}
@ -258,7 +253,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
}
componentDidUpdate(_: Props, prevState: State) {
this.updateRootWidth(true);
this.updateRootWidth();
const {offset, scrollChangeReason} = this.state;
if (
prevState.offset !== offset &&