refactored ChannelSelector component

This commit is contained in:
unknown 2021-08-29 13:57:55 +05:30
parent 9e9ea41bdd
commit d3506acd94
4 changed files with 139 additions and 83 deletions

View file

@ -9,62 +9,80 @@ import Avatar from '../../atoms/avatar/Avatar';
import NotificationBadge from '../../atoms/badge/NotificationBadge'; import NotificationBadge from '../../atoms/badge/NotificationBadge';
import { blurOnBubbling } from '../../atoms/button/script'; import { blurOnBubbling } from '../../atoms/button/script';
function ChannelSelector({ function ChannelSelectorWrapper({
selected, unread, notificationCount, alert, isSelected, onClick, content, options,
iconSrc, imageSrc, roomId, onClick, children,
}) { }) {
return ( return (
<button <div className={`channel-selector${isSelected ? ' channel-selector--selected' : ''}`}>
className={`channel-selector__button-wrapper${selected ? ' channel-selector--selected' : ''}`} <button
type="button" className="channel-selector__content"
onClick={onClick} type="button"
onMouseUp={(e) => blurOnBubbling(e, '.channel-selector__button-wrapper')} onClick={onClick}
> onMouseUp={(e) => blurOnBubbling(e, '.channel-selector__wrapper')}
<div className="channel-selector"> >
<div className="channel-selector__icon flex--center"> {content}
</button>
<div className="channel-selector__options">{options}</div>
</div>
);
}
ChannelSelectorWrapper.defaultProps = {
options: null,
};
ChannelSelectorWrapper.propTypes = {
isSelected: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
content: PropTypes.node.isRequired,
options: PropTypes.node,
};
function ChannelSelector({
name, roomId, imageSrc, iconSrc,
isSelected, isUnread, notificationCount, isAlert,
options, onClick,
}) {
return (
<ChannelSelectorWrapper
isSelected={isSelected}
content={(
<>
<Avatar <Avatar
text={children.slice(0, 1)} text={name.slice(0, 1)}
bgColor={colorMXID(roomId)} bgColor={colorMXID(roomId)}
imageSrc={imageSrc} imageSrc={imageSrc}
iconSrc={iconSrc} iconSrc={iconSrc}
size="extra-small" size="extra-small"
/> />
</div> <Text variant="b1">{name}</Text>
<div className="channel-selector__text-container"> { isUnread && (
<Text variant="b1">{children}</Text>
</div>
<div className="channel-selector__badge-container">
{ unread && (
<NotificationBadge <NotificationBadge
alert={alert} alert={isAlert}
content={notificationCount !== 0 ? notificationCount : null} content={notificationCount !== 0 ? notificationCount : null}
/> />
)} )}
</div> </>
</div> )}
</button> options={options}
onClick={onClick}
/>
); );
} }
ChannelSelector.defaultProps = { ChannelSelector.defaultProps = {
selected: false,
unread: false,
notificationCount: 0,
alert: false,
iconSrc: null,
imageSrc: null, imageSrc: null,
iconSrc: null,
options: null,
}; };
ChannelSelector.propTypes = { ChannelSelector.propTypes = {
selected: PropTypes.bool, name: PropTypes.string.isRequired,
unread: PropTypes.bool,
notificationCount: PropTypes.number,
alert: PropTypes.bool,
iconSrc: PropTypes.string,
imageSrc: PropTypes.string,
roomId: PropTypes.string.isRequired, roomId: PropTypes.string.isRequired,
imageSrc: PropTypes.string,
iconSrc: PropTypes.string,
isSelected: PropTypes.bool.isRequired,
isUnread: PropTypes.bool.isRequired,
notificationCount: PropTypes.number.isRequired,
isAlert: PropTypes.bool.isRequired,
options: PropTypes.node,
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
children: PropTypes.string.isRequired,
}; };
export default ChannelSelector; export default ChannelSelector;

View file

@ -1,24 +1,35 @@
.channel-selector__button-wrapper { .channel-selector-flex {
display: block; display: flex;
width: calc(100% - var(--sp-extra-tight)); align-items: center;
margin-left: auto; }
padding: var(--sp-extra-tight) var(--sp-extra-tight); .channel-selector-flexItem {
flex: 1;
min-width: 0;
min-height: 0;
}
.channel-selector {
@extend .channel-selector-flex;
border: 1px solid transparent; border: 1px solid transparent;
border-radius: var(--bo-radius); border-radius: var(--bo-radius);
cursor: pointer; cursor: pointer;
[dir=rtl] & { &--selected {
background-color: var(--bg-surface);
border-color: var(--bg-surface-border);
margin: { & .channel-selector__options {
left: 0; display: flex;
right: auto;
} }
} }
@media (hover: hover) { @media (hover: hover) {
&:hover { &:hover {
background-color: var(--bg-surface-hover); background-color: var(--bg-surface-hover);
& .channel-selector__options {
display: flex;
}
} }
} }
&:focus { &:focus {
@ -28,33 +39,50 @@
&:active { &:active {
background-color: var(--bg-surface-active); background-color: var(--bg-surface-active);
} }
} &--selected:hover,
.channel-selector { &--selected:focus,
display: flex; &--selected:active {
align-items: center; background-color: var(--bg-surface);
&__icon {
width: 24px;
height: 24px;
.avatar__border {
box-shadow: none;
}
} }
&__text-container { }
flex: 1;
min-width: 0; .channel-selector__content {
@extend .channel-selector-flexItem;
@extend .channel-selector-flex;
padding: 0 var(--sp-extra-tight);
min-height: 40px;
cursor: inherit;
& > .avatar-container .avatar__bordered {
box-shadow: none;
}
& > .text {
@extend .channel-selector-flexItem;
margin: 0 var(--sp-extra-tight); margin: 0 var(--sp-extra-tight);
& .text { color: var(--tc-surface-normal);
color: var(--tc-surface-normal); overflow: hidden;
overflow: hidden; white-space: nowrap;
white-space: nowrap; text-overflow: ellipsis;
text-overflow: ellipsis;
}
} }
} }
.channel-selector__options {
@extend .channel-selector-flex;
display: none;
margin-right: var(--sp-ultra-tight);
.channel-selector--selected { [dir=rtl] & {
background-color: var(--bg-surface); margin-right: 0;
border-color: var(--bg-surface-border); margin-left: var(--sp-ultra-tight);
}
&:empty {
margin: 0 !important;
}
& .ic-btn-surface {
padding: 6px;
border-radius: calc(var(--bo-radius) / 2);
}
} }

View file

@ -102,6 +102,9 @@ function renderSelector(room, roomId, isSelected, isDM) {
return ( return (
<ChannelSelector <ChannelSelector
key={roomId} key={roomId}
name={room.name}
roomId={roomId}
imageSrc={isDM ? imageSrc : null}
iconSrc={ iconSrc={
isDM isDM
? null ? null
@ -112,16 +115,12 @@ function renderSelector(room, roomId, isSelected, isDM) {
return (room.getJoinRule() === 'invite' ? HashLockIC : HashIC); return (room.getJoinRule() === 'invite' ? HashLockIC : HashIC);
})() })()
} }
imageSrc={isDM ? imageSrc : null} isSelected={isSelected}
roomId={roomId} isUnread={doesRoomHaveUnread(room)}
unread={doesRoomHaveUnread(room)}
onClick={() => selectRoom(roomId)}
notificationCount={room.getUnreadNotificationCount('total')} notificationCount={room.getUnreadNotificationCount('total')}
alert={room.getUnreadNotificationCount('highlight') !== 0} isAlert={room.getUnreadNotificationCount('highlight') !== 0}
selected={isSelected} onClick={() => selectRoom(roomId)}
> />
{room.name}
</ChannelSelector>
); );
} }

View file

@ -35,7 +35,18 @@
.channels-container { .channels-container {
padding-bottom: var(--sp-extra-loose); padding-bottom: var(--sp-extra-loose);
& > .channel-selector__button-wrapper:first-child { & > .channel-selector {
width: calc(100% - var(--sp-extra-tight));
margin-left: auto;
[dir=rtl] & {
margin-left: 0;
margin-right: auto;
}
}
& > .channel-selector:first-child {
margin-top: var(--sp-extra-tight); margin-top: var(--sp-extra-tight);
} }