Skip to content

Commit

Permalink
🐛 Refactor Avatar scale calculate logic
Browse files Browse the repository at this point in the history
close #15351

close #15468
  • Loading branch information
afc163 committed Mar 20, 2019
1 parent 06745a6 commit 0abb04a
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 44 deletions.
55 changes: 55 additions & 0 deletions components/avatar/demo/toggle-debug.md
@@ -0,0 +1,55 @@
---
order: 4
title:
zh-CN: 隐藏情况下计算字符对齐
en-US: Calculate text style when hiding
debug: true
---

## zh-CN

切换 Avatar 显示的时候,文本样式应该居中并正确调整字体大小。

## en-US

Text inside Avatar should be set a proper font size when toggle it's visibility.

````jsx
import { Avatar, Button } from 'antd';

class App extends React.Component {
state = {
hide: false,
};

toggle = () => {
this.setState({
hide: !this.state.hide,
});
}

render() {
const { hide } = this.state;
return (
<div>
<Button onClick={this.toggle}>Toggle Avatar</Button>
<Avatar size="large" style={{ background: '#7265e6', display: hide ? 'none' : '' }}>
Avatar
</Avatar>
<Avatar size="large" src="invalid" style={{ background: '#00a2ae', display: hide ? 'none' : '' }}>
Invalid src
</Avatar>
<div style={{ display: hide ? 'none' : '' }}>
<Avatar size="large" style={{ background: '#7265e6' }}>
Avatar
</Avatar>
<Avatar size="large" src="invalid" style={{ background: '#00a2ae' }}>
Invalid src
</Avatar>
</div>
</div>
);
}
}

ReactDOM.render(<App />, mountNode);
74 changes: 30 additions & 44 deletions components/avatar/index.tsx
@@ -1,5 +1,4 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Icon from '../icon';
import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
Expand Down Expand Up @@ -31,7 +30,6 @@ export interface AvatarProps {
export interface AvatarState {
scale: number;
isImgExist: boolean;
avatarDisplay: boolean;
}

export default class Avatar extends React.Component<AvatarProps, AvatarState> {
Expand All @@ -43,59 +41,39 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
state = {
scale: 1,
isImgExist: true,
avatarDisplay: true,
};

private avatarChildren: any;
private avatarNode: HTMLElement;
private avatarChildren: HTMLElement;
private lastChildrenWidth: number;

componentDidMount() {
this.setScale();
}

componentDidUpdate(prevProps: AvatarProps, prevState: AvatarState) {
if (
prevProps.children !== this.props.children ||
(prevState.scale !== this.state.scale && this.state.scale === 1) ||
prevState.isImgExist !== this.state.isImgExist ||
!this.state.avatarDisplay
) {
this.setScale();
if (this.avatarChildren && this.avatarChildren.offsetWidth !== 0) {
this.setState({
avatarDisplay: true,
});
}
} else {
if (this.avatarChildren && this.avatarChildren.offsetWidth === 0 && this.state.scale === 1) {
this.setState({
avatarDisplay: false,
});
}
}

componentDidUpdate(prevProps: AvatarProps) {
this.setScale();
if (prevProps.src !== this.props.src) {
this.setState({ isImgExist: true, scale: 1 });
}
}

setScale = () => {
const childrenNode = this.avatarChildren;
// denominator is 0 is no meaning
if (childrenNode && childrenNode.offsetWidth !== 0) {
const childrenWidth = childrenNode.offsetWidth;
const avatarNode = ReactDOM.findDOMNode(this) as Element;
const avatarWidth = avatarNode.getBoundingClientRect().width;
// add 4px gap for each side to get better performance
if (avatarWidth - 8 < childrenWidth) {
this.setState({
scale: (avatarWidth - 8) / childrenWidth,
});
} else {
this.setState({
scale: 1,
});
}
if (
!this.avatarChildren ||
this.avatarChildren.offsetWidth === 0 ||
this.lastChildrenWidth === this.avatarChildren.offsetWidth
) {
return;
}
// denominator is 0 is no meaning
const { offsetWidth } = this.avatarChildren;
this.lastChildrenWidth = offsetWidth;
const avatarWidth = this.avatarNode.getBoundingClientRect().width;
// add 4px gap for each side to get better performance
this.setState({
scale: avatarWidth - 8 < offsetWidth ? (avatarWidth - 8) / offsetWidth : 1,
});
};

handleImgLoadError = () => {
Expand Down Expand Up @@ -167,22 +145,30 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
children = (
<span
className={`${prefixCls}-string`}
ref={span => (this.avatarChildren = span)}
ref={(node: HTMLElement) => (this.avatarChildren = node)}
style={{ ...sizeChildrenStyle, ...childrenStyle }}
>
{children}
</span>
);
} else {
children = (
<span className={`${prefixCls}-string`} ref={span => (this.avatarChildren = span)}>
<span
className={`${prefixCls}-string`}
ref={(node: HTMLElement) => (this.avatarChildren = node)}
>
{children}
</span>
);
}
}
return (
<span {...others} style={{ ...sizeStyle, ...others.style }} className={classString}>
<span
{...others}
style={{ ...sizeStyle, ...others.style }}
className={classString}
ref={(node: HTMLElement) => (this.avatarNode = node)}
>
{children}
</span>
);
Expand Down

0 comments on commit 0abb04a

Please sign in to comment.