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

View file

@ -1,24 +1,35 @@
.channel-selector__button-wrapper {
display: block;
width: calc(100% - var(--sp-extra-tight));
margin-left: auto;
padding: var(--sp-extra-tight) var(--sp-extra-tight);
border: 1px solid transparent;
border-radius: var(--bo-radius);
cursor: pointer;
.channel-selector-flex {
display: flex;
align-items: center;
}
.channel-selector-flexItem {
flex: 1;
min-width: 0;
min-height: 0;
}
[dir=rtl] & {
margin: {
left: 0;
right: auto;
.channel-selector {
@extend .channel-selector-flex;
border: 1px solid transparent;
border-radius: var(--bo-radius);
cursor: pointer;
&--selected {
background-color: var(--bg-surface);
border-color: var(--bg-surface-border);
& .channel-selector__options {
display: flex;
}
}
@media (hover: hover) {
&:hover {
background-color: var(--bg-surface-hover);
& .channel-selector__options {
display: flex;
}
}
}
&:focus {
@ -28,33 +39,50 @@
&:active {
background-color: var(--bg-surface-active);
}
}
.channel-selector {
display: flex;
align-items: center;
&__icon {
width: 24px;
height: 24px;
.avatar__border {
box-shadow: none;
}
&--selected:hover,
&--selected:focus,
&--selected:active {
background-color: var(--bg-surface);
}
&__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);
& .text {
color: var(--tc-surface-normal);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
color: var(--tc-surface-normal);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.channel-selector__options {
@extend .channel-selector-flex;
display: none;
margin-right: var(--sp-ultra-tight);
.channel-selector--selected {
background-color: var(--bg-surface);
border-color: var(--bg-surface-border);
[dir=rtl] & {
margin-right: 0;
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 (
<ChannelSelector
key={roomId}
name={room.name}
roomId={roomId}
imageSrc={isDM ? imageSrc : null}
iconSrc={
isDM
? null
@ -112,16 +115,12 @@ function renderSelector(room, roomId, isSelected, isDM) {
return (room.getJoinRule() === 'invite' ? HashLockIC : HashIC);
})()
}
imageSrc={isDM ? imageSrc : null}
roomId={roomId}
unread={doesRoomHaveUnread(room)}
onClick={() => selectRoom(roomId)}
isSelected={isSelected}
isUnread={doesRoomHaveUnread(room)}
notificationCount={room.getUnreadNotificationCount('total')}
alert={room.getUnreadNotificationCount('highlight') !== 0}
selected={isSelected}
>
{room.name}
</ChannelSelector>
isAlert={room.getUnreadNotificationCount('highlight') !== 0}
onClick={() => selectRoom(roomId)}
/>
);
}

View file

@ -35,7 +35,18 @@
.channels-container {
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);
}