Merge pull request #13544 from ramonlsouza/styled-components-userlist

styled-components conversion - userlist
This commit is contained in:
Anton Georgiev 2021-10-25 11:46:29 -04:00 committed by GitHub
commit 39d814ba8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1586 additions and 655 deletions

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import Icon from '/imports/ui/components/icon/component';
import { Session } from 'meteor/session';
import { defineMessages, injectIntl } from 'react-intl';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { PANELS, ACTIONS } from '../../layout/enums';
const propTypes = {
@ -62,18 +62,17 @@ const CaptionsListItem = (props) => {
};
return (
<div
<Styled.ListItem
role="button"
tabIndex={tabIndex}
id={locale.locale}
className={styles.listItem}
onClick={handleClickToggleCaptions}
aria-label={`${locale.name} ${intl.formatMessage(intlMessages.captionLabel)}`}
onKeyPress={() => {}}
>
<Icon iconName="closed_caption" />
<span aria-hidden>{locale.name}</span>
</div>
</Styled.ListItem>
);
};

View File

@ -0,0 +1,9 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
const ListItem = styled(Styled.ListItem)``;
export default {
ListItem,
};

View File

@ -1,22 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
import Icon from '/imports/ui/components/icon/component';
import { styles } from './styles';
import Styled from './styles';
const propTypes = {
icon: PropTypes.string.isRequired,
};
const defaultProps = {
};
const ChatIcon = props => (
<div className={styles.chatThumbnail}>
<Styled.ChatThumbnail>
<Icon iconName={props.icon} />
</div>
</Styled.ChatThumbnail>
);
ChatIcon.propTypes = propTypes;
ChatIcon.defaultProps = defaultProps;
export default ChatIcon;

View File

@ -0,0 +1,15 @@
import styled from 'styled-components';
import { colorGrayLight } from '/imports/ui/stylesheets/styled-components/palette';
const ChatThumbnail = styled.div`
display: flex;
flex-flow: column;
color: ${colorGrayLight};
justify-content: center;
font-size: 175%;
`;
export default {
ChatThumbnail,
};

View File

@ -1,16 +0,0 @@
@import "/imports/ui/stylesheets/mixins/_indicators";
@import "/imports/ui/stylesheets/variables/placeholders";
.chatThumbnail {
display: flex;
flex-flow: column;
color: var(--color-gray-light);
justify-content: center;
font-size: 175%;
}
.chatIcon {
@extend %highContrastOutline;
outline-style: solid;
flex: 0 0 2.2rem;
}

View File

@ -1,10 +1,9 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { defineMessages, injectIntl } from 'react-intl';
import _ from 'lodash';
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
import { styles } from './styles';
import Styled from './styles';
import ChatAvatar from './chat-avatar/component';
import ChatIcon from './chat-icon/component';
import ChatUnreadCounter from './chat-unread-messages/component';
@ -73,9 +72,6 @@ const ChatListItem = (props) => {
const chatPanelOpen = sidebarContentIsOpen && sidebarContentPanel === PANELS.CHAT;
const isCurrentChat = chat.chatId === activeChatId && chatPanelOpen;
const linkClasses = {};
linkClasses[styles.active] = isCurrentChat;
const [stateUreadCount, setStateUreadCount] = useState(0);
@ -137,11 +133,11 @@ const ChatListItem = (props) => {
};
return (
<div
<Styled.ChatListItem
data-test="chatButton"
role="button"
className={cx(styles.chatListItem, linkClasses)}
aria-expanded={isCurrentChat}
active={isCurrentChat}
tabIndex={tabIndex}
accessKey={isPublicChat(chat) ? TOGGLE_CHAT_PUB_AK : null}
onClick={handleClickToggleChat}
@ -149,9 +145,8 @@ const ChatListItem = (props) => {
aria-label={isPublicChat(chat) ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
onKeyPress={() => {}}
>
<div className={styles.chatListItemLink}>
<div className={styles.chatIcon}>
<Styled.ChatListItemLink>
<Styled.ChatIcon>
{chat.icon
? <ChatIcon icon={chat.icon} />
: (
@ -162,16 +157,16 @@ const ChatListItem = (props) => {
name={chat.name.toLowerCase().slice(0, 2)}
/>
)}
</div>
<div className={styles.chatName} aria-live="off">
</Styled.ChatIcon>
<Styled.ChatName aria-live="off">
{!compact
? (
<span className={styles.chatNameMain}>
<Styled.ChatNameMain>
{isPublicChat(chat)
? intl.formatMessage(intlMessages.titlePublic) : chat.name}
</span>
</Styled.ChatNameMain>
) : null}
</div>
</Styled.ChatName>
{(stateUreadCount > 0)
? (
<ChatUnreadCounter
@ -181,8 +176,8 @@ const ChatListItem = (props) => {
/>
)
: null}
</div>
</div>
</Styled.ChatListItemLink>
</Styled.ChatListItem>
);
};

View File

@ -0,0 +1,92 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import { fontSizeSmall } from '/imports/ui/stylesheets/styled-components/typography';
import {
lgPaddingY,
smPaddingY,
borderSize,
} from '/imports/ui/stylesheets/styled-components/general';
import {
colorGrayDark,
colorOffWhite,
listItemBgHover,
} from '/imports/ui/stylesheets/styled-components/palette';
const ChatListItemLink = styled.div`
display: flex;
flex-grow: 1;
align-items: center;
text-decoration: none;
width: 100%;
`;
const ChatIcon = styled.div`
flex: 0 0 2.2rem;
`;
const ChatName = styled.div`
display: flex;
align-items: center;
flex-grow: 1;
justify-content: center;
width: 50%;
padding-right: ${smPaddingY};
`;
const ChatNameMain = styled.span`
margin: 0;
min-width: 0;
display: inline-block;
white-space: nowrap;
overflow: hidden;
font-weight: 400;
font-size: ${fontSizeSmall};
color: ${colorGrayDark};
flex-grow: 1;
line-height: 2;
text-align: left;
padding: 0 0 0 ${lgPaddingY};
text-overflow: ellipsis;
[dir="rtl"] & {
text-align: right;
padding: 0 ${lgPaddingY} 0 0;
}
${({ active }) => active && `
background-color: ${listItemBgHover};
`}
`;
const ChatListItem = styled(Styled.ListItem)`
cursor: pointer;
text-decoration: none;
flex-grow: 1;
line-height: 2;
color: ${colorGrayDark};
background-color: ${colorOffWhite};
padding-top: ${lgPaddingY};
padding-bottom: ${lgPaddingY};
padding-left: ${lgPaddingY};
padding-right: 0;
margin-left: ${borderSize};
margin-top: ${borderSize};
margin-bottom: ${borderSize};
margin-right: 0;
[dir="rtl"] & {
padding-left: 0;
padding-right: ${lgPaddingY};
margin-left: 0;
margin-right: ${borderSize};
}
`;
export default {
ChatListItemLink,
ChatIcon,
ChatName,
ChatNameMain,
ChatListItem,
};

View File

@ -1,104 +0,0 @@
@import "/imports/ui/stylesheets/mixins/_indicators";
@import "/imports/ui/stylesheets/variables/placeholders";
%list-item {
display: flex;
flex-flow: row;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: pointer;
[dir="rtl"] & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
&:first-child {
margin-top: 0;
}
&:hover {
@extend %highContrastOutline;
background-color: var(--list-item-bg-hover);
}
&:active,
&:focus {
@extend %highContrastOutline;
outline-style: solid;
background-color: var(--list-item-bg-hover);
box-shadow: inset 0 0 0 var(--border-size) var(--item-focus-border), inset 1px 0 0 1px var(--item-focus-border);
}
}
.chatListItem {
@extend %list-item;
cursor: pointer;
text-decoration: none;
flex-grow: 1;
line-height: 2;
color: var(--color-gray-dark);
background-color: var(--color-off-white);
padding-top: var(--lg-padding-y);
padding-bottom: var(--lg-padding-y);
padding-left: var(--lg-padding-y);
padding-right: 0;
margin-left: var(--border-size);
margin-top: var(--border-size);
margin-bottom: var(--border-size);
margin-right: 0;
[dir="rtl"] & {
padding-left: 0;
padding-right: var(--lg-padding-y);
margin-left: 0;
margin-right: var(--border-size);
}
}
.chatListItemLink {
display: flex;
flex-grow: 1;
align-items: center;
text-decoration: none;
width: 100%;
}
.chatIcon {
flex: 0 0 2.2rem;
}
.chatName {
display: flex;
align-items: center;
flex-grow: 1;
justify-content: center;
width: 50%;
padding-right: var(--sm-padding-y);
}
.chatNameMain {
margin: 0;
@extend %text-elipsis;
font-weight: 400;
font-size: var(--font-size-small);
color: var(--color-gray-dark);
flex-grow: 1;
line-height: 2;
text-align: left;
padding: 0 0 0 var(--lg-padding-y);
text-overflow: ellipsis;
[dir="rtl"] & {
text-align: right;
padding: 0 var(--lg-padding-y) 0 0;
}
}
.active {
background-color: var(--list-item-bg-hover);
}

View File

@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import { injectIntl } from 'react-intl';
import PropTypes from 'prop-types';
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
import { styles } from './styles.scss';
import Styled from './styles';
import CustomLogo from './custom-logo/component';
import UserContentContainer from './user-list-content/container';
@ -40,7 +40,7 @@ class UserList extends PureComponent {
} = this.props;
return (
<div className={styles.userList}>
<Styled.UserList>
{
showBranding
&& !compact
@ -60,7 +60,7 @@ class UserList extends PureComponent {
}
}
/>}
</div>
</Styled.UserList>
);
}
}

View File

@ -1,13 +1,12 @@
import React from 'react';
import { styles } from './styles';
import Styled from './styles';
const CustomLogo = props => (
<div>
<div className={styles.branding}>
<Styled.Branding>
<img src={props.CustomLogoUrl} alt="custom branding logo" />
</div>
<div className={styles.separator} />
</Styled.Branding>
<Styled.Separator />
</div>
);

View File

@ -0,0 +1,28 @@
import styled from 'styled-components';
import { colorGrayLighter } from '/imports/ui/stylesheets/styled-components/palette';
import { lineHeightComputed } from '/imports/ui/stylesheets/styled-components/typography';
import { smPaddingX } from '/imports/ui/stylesheets/styled-components/general';
const Separator = styled.div`
height: 1px;
background-color: ${colorGrayLighter};
margin-bottom: calc(${lineHeightComputed} * .5);
`;
const Branding = styled.div`
padding: ${smPaddingX};
width: 100%;
& > img {
max-height: 2rem;
max-width: 100%;
display: block;
margin-left: auto;
margin-right: auto;
}
`;
export default {
Separator,
Branding,
}

View File

@ -1,17 +0,0 @@
.separator {
height: 1px;
background-color: var(--color-gray-lighter);
margin-bottom: calc(var(--line-height-computed) * .5);
}
.branding {
padding: var(--sm-padding-x);
width: 100%;
& > img {
max-height: 2rem;
max-width: 100%;
display: block;
margin-left: auto;
margin-right: auto;
}
}

View File

@ -0,0 +1,80 @@
import styled from 'styled-components';
import { FlexColumn } from '/imports/ui/stylesheets/styled-components/placeholders';
import {
userListBg,
userListText,
colorGray,
listItemBgHover,
itemFocusBorder,
} from '/imports/ui/stylesheets/styled-components/palette';
import { smPaddingX, borderSize } from '/imports/ui/stylesheets/styled-components/general';
const UserList = styled(FlexColumn)`
justify-content: flex-start;
background-color: ${userListBg};
color: ${userListText};
height: 100%;
`;
const SmallTitle = styled.h2`
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
padding: 0 ${smPaddingX};
color: ${colorGray};
flex: 1;
margin: 0;
`;
const Messages = styled.div`
flex-grow: 0;
display: flex;
flex-flow: column;
flex-shrink: 0;
max-height: 30vh;
`;
const ListItem = styled.div`
display: flex;
flex-flow: row;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: pointer;
[dir="rtl"] & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
&:first-child {
margin-top: 0;
}
&:hover {
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
background-color: ${listItemBgHover};
}
&:active,
&:focus {
outline: transparent;
outline-width: ${borderSize};
outline-style: solid;
background-color: ${listItemBgHover};
box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder};
}
`;
export default {
UserList,
SmallTitle,
ListItem,
Messages,
};

View File

@ -40,14 +40,6 @@
* ==========
*/
.userList {
@extend %flex-column;
justify-content: flex-start;
background-color: var(--user-list-bg);
color: var(--user-list-text);
height: 100%;
}
.lists {
@extend %flex-column;
@extend %no-margin;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import Icon from '/imports/ui/components/icon/component';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { ACTIONS, PANELS } from '../../../layout/enums';
const intlMessages = defineMessages({
@ -33,29 +33,28 @@ const BreakoutRoomItem = ({
if (hasBreakoutRoom) {
return (
<div className={styles.messages}>
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Messages>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.breakoutTitle)}
</h2>
</div>
<div className={styles.scrollableList}>
<div className={styles.list}>
<div
</Styled.SmallTitle>
</Styled.Container>
<Styled.ScrollableList>
<Styled.List>
<Styled.ListItem
role="button"
tabIndex={0}
onClick={toggleBreakoutPanel}
data-test="breakoutRoomsItem"
className={styles.listItem}
aria-label={intl.formatMessage(intlMessages.breakoutTitle)}
onKeyPress={() => {}}
>
<Icon iconName="rooms" />
<span aria-hidden>{intl.formatMessage(intlMessages.breakoutTitle)}</span>
</div>
</div>
</div>
</div>
</Styled.ListItem>
</Styled.List>
</Styled.ScrollableList>
</Styled.Messages>
);
}
return <span />;

View File

@ -0,0 +1,25 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
const ListItem = styled(StyledContent.ListItem)``;
export default {
Messages,
Container,
SmallTitle,
ScrollableList,
List,
ListItem,
};

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { styles } from './styles';
import Styled from './styles';
import UserParticipantsContainer from './user-participants/container';
import UserMessages from './user-messages/container';
import UserNotesContainer from './user-notes/container';
@ -57,10 +57,7 @@ class UserContent extends PureComponent {
|| pendingUsers.length > 0;
return (
<div
data-test="userListContent"
className={styles.content}
>
<Styled.Content data-test="userListContent">
{CHAT_ENABLED
? (
<UserMessages
@ -126,7 +123,7 @@ class UserContent extends PureComponent {
requestUserInformation,
}}
/>
</div>
</Styled.Content>
);
}
}

View File

@ -0,0 +1,175 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import { FlexColumn } from '/imports/ui/stylesheets/styled-components/placeholders';
import {
smPaddingX,
lgPaddingY,
borderSize,
mdPaddingY,
mdPaddingX,
} from '/imports/ui/stylesheets/styled-components/general';
import {
colorPrimary,
userListBg,
colorWhite,
colorOffWhite,
colorGrayDark,
colorGrayLight,
colorGrayLighter,
listItemBgHover,
itemFocusBorder,
unreadMessagesBg,
} from '/imports/ui/stylesheets/styled-components/palette';
import { fontSizeSmall } from '/imports/ui/stylesheets/styled-components/typography';
import { ScrollboxVertical } from '/imports/ui/stylesheets/styled-components/scrollable';
const Content = styled(FlexColumn)`
flex-grow: 1;
overflow: hidden;
`;
const Container = styled.div`
display: flex;
align-items: center;
margin-bottom: ${lgPaddingY};
margin-top: ${smPaddingX};
`;
const ScrollableList = styled(ScrollboxVertical)`
background: linear-gradient(${userListBg} 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), ${userListBg} 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
outline: none;
&:hover {
/* Visible in Windows high-contrast themes */
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
}
&:focus,
&:active {
border-radius: none;
box-shadow: inset 0 0 1px ${colorPrimary};
outline-style: transparent;
}
overflow-x: hidden;
padding-top: 1px;
padding-right: 1px;
`;
const List = styled.div`
margin: 0 0 1px ${mdPaddingY};
[dir="rtl"] & {
margin: 0 ${mdPaddingY} 1px 0;
}
`;
const ListItem = styled(Styled.ListItem)`
align-items: center;
cursor: pointer;
display: flex;
flex-flow: row;
flex-grow: 0;
flex-shrink: 0;
padding-top: ${lgPaddingY};
padding-bottom: ${lgPaddingY};
padding-left: ${lgPaddingY};
text-decoration: none;
width: 100%;
color: ${colorGrayDark};
background-color: ${colorOffWhite};
[dir="rtl"] & {
padding-right: ${lgPaddingY};
padding-left: 0;
}
> i {
display: flex;
font-size: 175%;
color: ${colorGrayLight};
flex: 0 0 2.2rem;
margin-right: ${smPaddingX};
[dir="rtl"] & {
margin-right: 0;
margin-left: ${smPaddingX};
}
}
> span {
font-weight: 400;
font-size: ${fontSizeSmall};
color: ${colorGrayDark};
position: relative;
flex-grow: 1;
line-height: 2;
text-align: left;
padding-left: ${lgPaddingY};
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
[dir="rtl"] & {
text-align: right;
padding-right: ${mdPaddingX};
}
}
div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&:active {
background-color: ${listItemBgHover};
box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder};
}
`;
const UnreadMessages = styled(FlexColumn)`
justify-content: center;
margin-left: auto;
[dir="rtl"] & {
margin-right: auto;
margin-left: 0;
}
`;
const UnreadMessagesText = styled(FlexColumn)`
margin: 0;
justify-content: center;
color: ${colorWhite};
line-height: calc(1rem + 1px);
padding: 0 0.5rem;
text-align: center;
border-radius: 0.5rem/50%;
font-size: 0.8rem;
background-color: ${unreadMessagesBg};
`;
const Separator = styled.hr`
margin: 1rem auto;
width: 2.2rem;
border: 0;
border-top: 1px solid ${colorGrayLighter};
`;
export default {
Content,
Container,
ScrollableList,
List,
ListItem,
UnreadMessages,
UnreadMessagesText,
Separator,
};

View File

@ -4,12 +4,6 @@
@import "/imports/ui/stylesheets/mixins/_indicators";
@import "/imports/ui/stylesheets/variables/placeholders";
.content {
@extend %flex-column;
flex-grow: 1;
overflow: hidden;
}
.container{
display: flex;
align-items: center;
@ -165,12 +159,6 @@
background-color: var(--unread-messages-bg);
}
.smallTitle {
@extend .smallTitle;
flex: 1;
margin: 0;
}
.separator {
margin: 1rem auto;
width: 2.2rem;

View File

@ -3,16 +3,7 @@ import PropTypes from 'prop-types';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import CaptionsListItem from '/imports/ui/components/user-list/captions-list-item/component';
import { defineMessages } from 'react-intl';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
const listTransition = {
enter: styles.enter,
enterActive: styles.enterActive,
appear: styles.appear,
appearActive: styles.appearActive,
leave: styles.leave,
leaveActive: styles.leaveActive,
};
import Styled from './styles';
const propTypes = {
ownedLocales: PropTypes.arrayOf(PropTypes.object).isRequired,
@ -47,21 +38,22 @@ class UserCaptions extends Component {
return ownedLocales.map((locale) => (
<CSSTransition
classNames={listTransition}
classNames="transition"
appear
enter
exit={false}
timeout={0}
component="div"
className={styles.captionsList}
key={locale.locale}
>
<CaptionsListItem
{...{
locale, layoutContextDispatch, sidebarContentPanel,
}}
tabIndex={-1}
/>
<Styled.ListTransition>
<CaptionsListItem
{...{
locale, layoutContextDispatch, sidebarContentPanel,
}}
tabIndex={-1}
/>
</Styled.ListTransition>
</CSSTransition>
));
}
@ -75,25 +67,24 @@ class UserCaptions extends Component {
if (ownedLocales.length < 1) return null;
return (
<div className={styles.messages}>
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Messages>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.title)}
</h2>
</div>
<div
</Styled.SmallTitle>
</Styled.Container>
<Styled.ScrollableList
role="tabpanel"
tabIndex={0}
className={styles.scrollableList}
ref={(ref) => { this._msgsList = ref; }}
>
<div className={styles.list}>
<Styled.List>
<TransitionGroup ref={(ref) => { this._msgItems = ref; }}>
{this.renderCaptions()}
</TransitionGroup>
</div>
</div>
</div>
</Styled.List>
</Styled.ScrollableList>
</Styled.Messages>
);
}
}

View File

@ -0,0 +1,61 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
import { borderSize } from '/imports/ui/stylesheets/styled-components/general';
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
const ListTransition = styled.div`
display: flex;
flex-flow: column;
margin: 0;
padding: 0;
padding-top: ${borderSize};
outline: none;
overflow: hidden;
flex-shrink: 1;
&.transition-enter,
&.transition-appear {
opacity: 0.01;
}
&.transition-enter-active,
&.transition-appear-active {
opacity: 1;
&.animationsEnabled {
transition: all 600ms;
}
}
&.transition-leave {
opacity: 1;
}
&.transition-leave-active {
opacity: 0;
&.animationsEnabled {
transition: all 600ms;
}
}
`;
export default {
Messages,
Container,
SmallTitle,
ScrollableList,
List,
ListTransition,
};

View File

@ -2,8 +2,7 @@ import React, { PureComponent } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import cx from 'classnames';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { findDOMNode } from 'react-dom';
import ChatListItemContainer from '../../chat-list-item/container';
@ -21,15 +20,6 @@ const defaultProps = {
compact: false,
};
const listTransition = {
enter: styles.enter,
enterActive: styles.enterActive,
appear: styles.appear,
appearActive: styles.appearActive,
leave: styles.leave,
leaveActive: styles.leaveActive,
};
const intlMessages = defineMessages({
messagesTitle: {
id: 'app.userList.messagesTitle',
@ -81,23 +71,22 @@ class UserMessages extends PureComponent {
return activeChats.map(chat => (
<CSSTransition
classNames={listTransition}
classNames={"transition"}
appear
enter
exit={false}
timeout={0}
component="div"
className={cx(styles.chatsList)}
key={chat.userId}
>
<div ref={(node) => { this.activeChatRefs[index += 1] = node; }}>
<Styled.ListTransition ref={(node) => { this.activeChatRefs[index += 1] = node; }}>
<ChatListItemContainer
isPublicChat={isPublicChat}
compact={compact}
chat={chat}
tabIndex={-1}
/>
</div>
</Styled.ListTransition>
</CSSTransition>
));
}
@ -120,31 +109,30 @@ class UserMessages extends PureComponent {
} = this.props;
return (
<div className={styles.messages}>
<div className={styles.container}>
<Styled.Messages>
<Styled.Container>
{
!compact ? (
<h2 className={styles.smallTitle}>
<Styled.MessagesTitle>
{intl.formatMessage(intlMessages.messagesTitle)}
</h2>
</Styled.MessagesTitle>
) : (
<hr className={styles.separator} />
<Styled.Separator />
)
}
</div>
<div
</Styled.Container>
<Styled.ScrollableList
role="tabpanel"
tabIndex={0}
className={styles.scrollableList}
ref={(ref) => { this._msgsList = ref; }}
>
<div className={styles.list} aria-live="polite">
<Styled.List aria-live="polite">
<TransitionGroup ref={(ref) => { this._msgItems = ref; }}>
{this.getActiveChats()}
</TransitionGroup>
</div>
</div>
</div>
</Styled.List>
</Styled.ScrollableList>
</Styled.Messages>
);
}
}

View File

@ -0,0 +1,67 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
import { borderSize } from '/imports/ui/stylesheets/styled-components/general';
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const Separator = styled(StyledContent.Separator)``;
const MessagesTitle = styled(Styled.SmallTitle)`
flex: 1;
margin: 0;
`;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
const ListTransition = styled.div`
display: flex;
flex-flow: column;
margin: 0;
padding: 0;
padding-top: ${borderSize};
outline: none;
overflow: hidden;
flex-shrink: 1;
&.transition-enter,
&.transition-appear {
opacity: 0.01;
}
&.transition-enter-active,
&.transition-appear-active {
opacity: 1;
&.animationsEnabled {
transition: all 600ms;
}
}
&.transition-leave {
opacity: 1;
}
&.transition-leave-active {
opacity: 0;
&.animationsEnabled {
transition: all 600ms;
}
}
`;
export default {
Messages,
Container,
Separator,
MessagesTitle,
ScrollableList,
List,
ListTransition,
};

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import Icon from '/imports/ui/components/icon/component';
import NoteService from '/imports/ui/components/note/service';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { PANELS } from '../../../layout/enums';
const propTypes = {
@ -80,42 +80,38 @@ class UserNotes extends Component {
let notification = null;
if (unread) {
notification = (
<div
className={styles.unreadMessages}
aria-label={intl.formatMessage(intlMessages.unreadContent)}
>
<div className={styles.unreadMessagesText} aria-hidden="true">
<Styled.UnreadMessages aria-label={intl.formatMessage(intlMessages.unreadContent)}>
<Styled.UnreadMessagesText aria-hidden="true">
···
</div>
</div>
</Styled.UnreadMessagesText>
</Styled.UnreadMessages>
);
}
return (
<div
<Styled.ListItem
aria-label={intl.formatMessage(intlMessages.sharedNotes)}
aria-describedby="lockedNote"
role="button"
tabIndex={0}
className={styles.listItem}
onClick={() => NoteService.toggleNotePanel(sidebarContentPanel, layoutContextDispatch)}
onKeyPress={() => { }}
>
<Icon iconName="copy" />
<div aria-hidden>
<div className={styles.noteTitle} data-test="sharedNotes">
<Styled.NoteTitle data-test="sharedNotes">
{intl.formatMessage(intlMessages.sharedNotes)}
</div>
</Styled.NoteTitle>
{disableNote
? (
<div className={styles.noteLock}>
<Styled.NoteLock>
<Icon iconName="lock" />
<span id="lockedNote">{`${intl.formatMessage(intlMessages.locked)} ${intl.formatMessage(intlMessages.byModerator)}`}</span>
</div>
</Styled.NoteLock>
) : null}
</div>
{notification}
</div>
</Styled.ListItem>
);
}
@ -125,18 +121,18 @@ class UserNotes extends Component {
if (!NoteService.isEnabled()) return null;
return (
<div className={styles.messages}>
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Messages>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.title)}
</h2>
</div>
<div className={styles.scrollableList}>
<div className={styles.list}>
</Styled.SmallTitle>
</Styled.Container>
<Styled.ScrollableList>
<Styled.List>
{this.renderNotes()}
</div>
</div>
</div>
</Styled.List>
</Styled.ScrollableList>
</Styled.Messages>
);
}
}

View File

@ -0,0 +1,54 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
import { colorGray } from '/imports/ui/stylesheets/styled-components/palette';
import {
fontSizeSmall,
fontSizeSmaller,
fontSizeXS,
} from '/imports/ui/stylesheets/styled-components/typography';
const UnreadMessages = styled(StyledContent.UnreadMessages)``;
const UnreadMessagesText = styled(StyledContent.UnreadMessagesText)``;
const ListItem = styled(StyledContent.ListItem)``;
const NoteTitle = styled.div`
font-weight: 400;
font-size: ${fontSizeSmall};
`;
const NoteLock = styled.div`
font-weight: 200;
font-size: ${fontSizeSmaller};
color: ${colorGray};
> i {
font-size: ${fontSizeXS};
}
`;
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
export default {
UnreadMessages,
UnreadMessagesText,
ListItem,
NoteTitle,
NoteLock,
Messages,
Container,
SmallTitle,
ScrollableList,
List,
};

View File

@ -1,11 +1,10 @@
import React, { Component } from 'react';
import { defineMessages } from 'react-intl';
import PropTypes from 'prop-types';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import _ from 'lodash';
import { findDOMNode } from 'react-dom';
import {
List,
AutoSizer,
CellMeasurer,
CellMeasurerCache,
@ -194,17 +193,17 @@ class UserParticipants extends Component {
const { isOpen, scrollArea } = this.state;
return (
<div className={styles.userListColumn}>
<Styled.UserListColumn>
{
!compact
? (
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.usersTitle)}
&nbsp;(
{users.length}
)
</h2>
</Styled.SmallTitle>
{currentUser.role === ROLE_MODERATOR
? (
<UserOptionsContainer {...{
@ -216,15 +215,14 @@ class UserParticipants extends Component {
) : null
}
</div>
</Styled.Container>
)
: <hr className={styles.separator} />
: <Styled.Separator />
}
<div
<Styled.VirtualizedScrollableList
id={'user-list-virtualized-scroll'}
aria-label="Users list"
role="region"
className={styles.virtulizedScrollableList}
tabIndex={0}
ref={(ref) => {
this.refScrollContainer = ref;
@ -233,7 +231,7 @@ class UserParticipants extends Component {
<span id="participants-destination" />
<AutoSizer>
{({ height, width }) => (
<List
<Styled.VirtualizedList
{...{
isOpen,
users,
@ -252,15 +250,14 @@ class UserParticipants extends Component {
rowCount={users.length}
height={height - 1}
width={width - 1}
className={styles.scrollStyle}
overscanRowCount={30}
deferredMeasurementCache={this.cache}
tabIndex={-1}
/>
)}
</AutoSizer>
</div>
</div>
</Styled.VirtualizedScrollableList>
</Styled.UserListColumn>
);
}
}

View File

@ -0,0 +1,82 @@
import styled from 'styled-components';
import { FlexColumn } from '/imports/ui/stylesheets/styled-components/placeholders';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
import {
ScrollboxVertical,
VirtualizedScrollboxVertical,
} from '/imports/ui/stylesheets/styled-components/scrollable';
import { borderSize, mdPaddingY } from '/imports/ui/stylesheets/styled-components/general';
import { colorPrimary, userListBg } from '/imports/ui/stylesheets/styled-components/palette';
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const Separator = styled(StyledContent.Separator)``;
const UserListColumn = styled(FlexColumn)`
min-height: 0;
flex-grow: 1;
`;
const VirtualizedScrollableList = styled(ScrollboxVertical)`
background: linear-gradient(${userListBg} 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), ${userListBg} 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
> div {
outline: none;
}
&:hover {
/* Visible in Windows high-contrast themes */
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
}
&:focus {
outline: none;
}
&:focus,
&:active {
box-shadow: inset 0 0 1px ${colorPrimary};
border-radius: none;
outline-style: transparent;
}
flex-grow: 1;
flex-shrink: 1;
margin: 0 0 1px ${mdPaddingY};
[dir="rtl"] & {
margin: 0 ${mdPaddingY} 1px 0;
}
margin-left: 0;
padding-top: 1px;
`;
const VirtualizedList = styled(VirtualizedScrollboxVertical)`
background: linear-gradient(#f3f6f9 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), #f3f6f9 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
outline: none;
`;
export default {
Container,
SmallTitle,
Separator,
UserListColumn,
VirtualizedScrollableList,
VirtualizedList,
};

View File

@ -4,14 +4,13 @@ import _ from 'lodash';
import { Session } from 'meteor/session';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import cx from 'classnames';
import UserAvatar from '/imports/ui/components/user-avatar/component';
import Icon from '/imports/ui/components/icon/component';
import lockContextContainer from '/imports/ui/components/lock-viewers/context/container';
import { withModalMounter } from '/imports/ui/components/modal/service';
import RemoveUserModal from '/imports/ui/components/modal/remove-user/component';
import BBBMenu from '/imports/ui/components/menu/component';
import { styles } from './styles';
import Styled from './styles';
import UserName from '../user-name/component';
import { PANELS, ACTIONS } from '../../../../../layout/enums';
import WhiteboardService from '/imports/ui/components/whiteboard/service';
@ -584,13 +583,6 @@ class UserDropdown extends PureComponent {
const actions = this.getUsersActions();
const userItemContentsStyle = {};
userItemContentsStyle[styles.selected] = selected === true;
userItemContentsStyle[styles.dropdown] = true;
userItemContentsStyle[styles.userListItem] = !isActionsOpen;
userItemContentsStyle[styles.usertListItemWithMenu] = isActionsOpen;
const you = isMe(user.userId) ? intl.formatMessage(messages.you) : '';
const presenter = (user.presenter)
@ -607,47 +599,59 @@ class UserDropdown extends PureComponent {
},
);
const contents = (
<div
data-test={isMe(user.userId) ? 'userListItemCurrent' : 'userListItem'}
className={!actions.length ? styles.noActionsListItem : null}
style={{ direction: isRTL ? 'rtl' : 'ltr', width: '100%' }}
>
<div className={styles.userItemContents}>
<div className={styles.userAvatar}>
{this.renderUserAvatar()}
</div>
<UserName
{...{
user,
compact,
intl,
isThisMeetingLocked,
userAriaLabel,
isActionsOpen,
isMe,
}}
/>
</div>
</div>
const innerContents = (
<Styled.UserItemInnerContents>
<Styled.UserAvatar>
{this.renderUserAvatar()}
</Styled.UserAvatar>
<UserName
{...{
user,
compact,
intl,
isThisMeetingLocked,
userAriaLabel,
isActionsOpen,
isMe,
}}
/>
</Styled.UserItemInnerContents>
);
const contents = !actions.length
? (
<Styled.NoActionsListItem
data-test={isMe(user.userId) ? 'userListItemCurrent' : 'userListItem'}
style={{ direction: isRTL ? 'rtl' : 'ltr' }}
>
{innerContents}
</Styled.NoActionsListItem>
)
: (
<div
data-test={isMe(user.userId) ? 'userListItemCurrent' : 'userListItem'}
style={{ direction: isRTL ? 'rtl' : 'ltr', width: '100%' }}
>
{innerContents}
</div>
);
if (!actions.length) return contents;
return (
<BBBMenu
trigger={
(
<div
<Styled.UserItemContents
isActionsOpen={isActionsOpen}
selected={selected === true}
tabIndex={-1}
onClick={() => this.setState({ selected: true })}
className={cx(userItemContentsStyle)}
style={{ width: '100%', marginLeft: '.5rem' }}
onKeyPress={() => {}}
onKeyPress={() => { }}
role="button"
>
{contents}
</div>
</Styled.UserItemContents>
)
}
actions={actions}

View File

@ -0,0 +1,103 @@
import styled from 'styled-components';
import { lgPaddingY, smPaddingY, borderSize } from '/imports/ui/stylesheets/styled-components/general';
import { listItemBgHover, itemFocusBorder } from '/imports/ui/stylesheets/styled-components/palette';
const UserItemContents = styled.div`
position: static;
padding: .45rem;
width: 100%;
margin-left: .5rem;
${({ selected }) => selected && `
background-color: ${listItemBgHover};
border-top-left-radius: ${smPaddingY};
border-bottom-left-radius: ${smPaddingY};
&:focus {
box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder};
}
`}
${({ isActionsOpen }) => !isActionsOpen && `
display: flex;
flex-flow: row;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: pointer;
[dir="rtl"] & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
&:first-child {
margin-top: 0;
}
&:hover {
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
background-color: ${listItemBgHover};
}
&:active,
&:focus {
outline: transparent;
outline-width: ${borderSize};
outline-style: solid;
background-color: ${listItemBgHover};
box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder};
}
flex-flow: column;
flex-shrink: 0;
`}
${({ isActionsOpen }) => isActionsOpen && `
outline: transparent;
outline-width: ${borderSize};
outline-style: solid;
background-color: ${listItemBgHover};
box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder};
border-top-left-radius: ${smPaddingY};
border-bottom-left-radius: ${smPaddingY};
&:focus {
outline-style: solid;
outline-color: transparent !important;
}
`}
`;
const UserItemInnerContents = styled.div`
flex-grow: 0;
display: flex;
flex-flow: row;
padding: 3px;
[dir="rtl"] & {
padding: ${lgPaddingY} ${lgPaddingY} ${lgPaddingY} 0;
}
`;
const UserAvatar = styled.div`
flex: 0 0 2.25rem;
`;
const NoActionsListItem = styled.div`
margin-left: 0.5rem;
padding: .45rem;
width: 100%;
`;
export default {
UserItemContents,
UserItemInnerContents,
UserAvatar,
NoActionsListItem,
};

View File

@ -1,195 +0,0 @@
@import "/imports/ui/stylesheets/variables/breakpoints";
@import "/imports/ui/stylesheets/variables/placeholders";
@import '/imports/ui/stylesheets/mixins/_indicators';
@import '/imports/ui/stylesheets/mixins/focus';
%list-item {
display: flex;
flex-flow: row;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: pointer;
[dir="rtl"] & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
&:first-child {
margin-top: 0;
}
&:hover {
@extend %highContrastOutline;
background-color: var(--list-item-bg-hover);
}
&:active,
&:focus {
@extend %highContrastOutline;
outline-style: solid;
background-color: var(--list-item-bg-hover);
box-shadow: inset 0 0 0 var(--border-size) var(--item-focus-border), inset 1px 0 0 1px var(--item-focus-border);
}
}
/* Animations
* ==========
*/
// Actions
.enter,
.appear {
opacity: 0;
max-height: 0;
}
.enterActive,
.appearActive {
opacity: 1;
max-height: 10rem;
:global(.animationsEnabled) & {
transition: all 300ms;
}
}
.leave {
opacity: 1;
max-height: 10rem;
}
.leaveActive {
opacity: 0;
max-height: 0rem;
:global(.animationsEnabled) & {
transition: all 500ms;
}
}
// Text under username
.subUserNameEnter,
.subUserNameAppear {
opacity: 0.01;
transform: translateY(-100%);
}
.subUserNameEnterActive,
.subUserNameAppearActive {
transform: translateY(0%);
opacity: 1;
max-height: 10rem;
:global(.animationsEnabled) & {
transition: all 500ms;
}
}
.subUserNameLeave {
opacity: 1;
transform: translateY(0%);
}
.subUserNameLeaveActive {
opacity: 0;
transform: translateY(-100%);
:global(.animationsEnabled) & {
transition: all 300ms;
}
}
.actionsHeader {
color: var(--color-gray);
&:hover {
color: var(--color-gray) !important;
cursor: default;
}
}
.active {
background-color: var(--list-item-bg-hover);
box-shadow: inset 0 0 0 var(--border-size) var(--item-focus-border), inset 1px 0 0 1px var(--item-focus-border);
}
.usertListItemWithMenu {
@extend %highContrastOutline;
outline-style: solid;
background-color: var(--list-item-bg-hover);
box-shadow: inset 0 0 0 var(--border-size) var(--item-focus-border), inset 1px 0 0 1px var(--item-focus-border);
border-top-left-radius: var(--sm-padding-y);
border-bottom-left-radius: var(--sm-padding-y);
&:focus {
outline-style: solid;
outline-color: transparent !important;
}
}
.userListItem {
@extend %list-item;
flex-flow: column;
flex-shrink: 0;
}
.noActionsListItem {
margin-left: 0.5rem;
padding: .45rem;
}
.userAvatar {
flex: 0 0 2.25rem;
}
.userItemContents {
flex-grow: 0;
display: flex;
flex-flow: row;
padding: 3px;
[dir="rtl"] & {
padding: var(--lg-padding-y) var(--lg-padding-y) var(--lg-padding-y) 0;
}
}
.selected {
background-color: var(--list-item-bg-hover);
border-top-left-radius: var(--sm-padding-y);
border-bottom-left-radius: var(--sm-padding-y);
&:focus {
box-shadow: inset 0 0 0 var(--border-size) var(--item-focus-border), inset 1px 0 0 1px var(--item-focus-border);
}
}
.dropdown {
position: static;
padding: .45rem;
}
.dropdownContent {
@extend %text-elipsis;
cursor: default;
min-width: 10vw;
@include mq($medium-only) {
min-width: 23vw;
}
@include mq($large-up) {
min-width: 14vw;
}
max-width: 100%;
overflow: visible;
}
.emojiSelected {
span,
i {
color: var(--color-primary);
}
}

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import Icon from '/imports/ui/components/icon/component';
import _ from 'lodash';
import { styles } from './styles';
import Styled from './styles';
const messages = defineMessages({
presenter: {
@ -111,33 +111,31 @@ const UserName = (props) => {
}
return (
<div
className={styles.userName}
<Styled.UserName
role="button"
aria-label={userAriaLabel}
aria-expanded={isActionsOpen}
>
<span aria-hidden className={styles.userNameMain}>
<Styled.UserNameMain>
<span>
{user.name}
&nbsp;
</span>
<i>{(isMe(user.userId)) ? `(${intl.formatMessage(messages.you)})` : ''}</i>
</span>
</Styled.UserNameMain>
{
userNameSub.length
? (
<span
<Styled.UserNameSub
aria-hidden
className={styles.userNameSub}
data-test={user.mobile ? 'mobileUser' : undefined}
>
{userNameSub.reduce((prev, curr) => [prev, ' | ', curr])}
</span>
</Styled.UserNameSub>
)
: null
}
</div>
</Styled.UserName>
);
};

View File

@ -1,25 +1,30 @@
.userName {
import styled from 'styled-components';
import { smPaddingX } from '/imports/ui/stylesheets/styled-components/general';
import { colorGray, colorGrayDark } from '/imports/ui/stylesheets/styled-components/palette';
const UserName = styled.div`
display: flex;
flex-flow: column;
min-width: 0;
flex-grow: 1;
margin: 0 0 0 var(--sm-padding-x);
margin: 0 0 0 ${smPaddingX};
justify-content: center;
font-size: 90%;
[dir="rtl"] & {
margin: 0 var(--sm-padding-x) 0 0;
margin: 0 ${smPaddingX} 0 0;
}
}
`;
.userNameMain {
const UserNameMain = styled.span`
margin: 0;
font-size: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 400;
color: var(--color-gray-dark);
color: ${colorGrayDark};
display: flex;
flex-direction: row;
@ -29,16 +34,15 @@
overflow: hidden;
}
:global(.animationsEnabled) & {
&.animationsEnabled {
transition: all .3s;
}
}
}`;
.userNameSub {
const UserNameSub = styled.span`
margin: 0;
font-size: 0.75rem;
font-weight: 200;
color: var(--color-gray);
color: ${colorGray};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@ -47,4 +51,10 @@
line-height: 0;
font-size: 75%;
}
}
`;
export default {
UserName,
UserNameMain,
UserNameSub,
};

View File

@ -3,14 +3,13 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import _ from 'lodash';
import { withModalMounter } from '/imports/ui/components/modal/service';
import Button from '/imports/ui/components/button/component';
import LockViewersContainer from '/imports/ui/components/lock-viewers/container';
import GuestPolicyContainer from '/imports/ui/components/waiting-users/guest-policy/container';
import BreakoutRoom from '/imports/ui/components/actions-bar/create-breakout-room/container';
import CaptionsService from '/imports/ui/components/captions/service';
import CaptionsWriterMenu from '/imports/ui/components/captions/writer-menu/container';
import BBBMenu from '/imports/ui/components/menu/component';
import { styles } from './styles';
import Styled from './styles';
import { getUserNamesLink } from '/imports/ui/components/user-list/service';
import Settings from '/imports/ui/services/settings';
@ -349,14 +348,13 @@ class UserOptions extends PureComponent {
return (
<BBBMenu
trigger={(
<Button
<Styled.OptionsButton
label={intl.formatMessage(intlMessages.optionsLabel)}
data-test="manageUsers"
icon="settings"
ghost
color="primary"
hideLabel
className={styles.optionsButton}
size="sm"
onClick={() => null}
/>

View File

@ -0,0 +1,27 @@
import styled from 'styled-components';
import Button from '/imports/ui/components/button/component';
import { colorOffWhite, colorGrayDark } from '/imports/ui/stylesheets/styled-components/palette';
import { fontSizeBase } from '/imports/ui/stylesheets/styled-components/typography';
const OptionsButton = styled(Button)`
border-radius: 50%;
display: block;
padding: 0;
i {
width: auto;
font-size: ${fontSizeBase} !important;
color: ${colorGrayDark} !important;
background-color: transparent !important;
}
&:hover,
&:focus {
background-color: ${colorOffWhite} !important;
}
`;
export default {
OptionsButton,
};

View File

@ -1,53 +0,0 @@
@import "/imports/ui/stylesheets/variables/breakpoints";
:root {
--user-manage-menu-top : -0.5rem;
--user-manage-menu-right : -0.75rem;
--user-manage-menu-width : 12rem;
}
.dropdown {
position: absolute;
right: 0;
left: auto;
[dir="rtl"] & {
left: 0;
right: auto;
}
}
.dropdownContent {
top: var(--user-manage-menu-top);
right: var(--user-manage-menu-right);
left: auto;
width: var(--user-manage-menu-width);
[dir="rtl"] & {
top: var(--user-manage-menu-top);
right: -1rem;
}
@include mq($small-only) {
width: 100vw;
}
}
.optionsButton{
border-radius: 50%;
display: block;
padding: 0;
i {
width: auto;
font-size: var(--font-size-base) !important;
color: var(--color-gray-dark) !important;
background-color: transparent !important;
}
&:hover,
&:focus {
background-color: var(--color-off-white) !important;
}
}

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import Icon from '/imports/ui/components/icon/component';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { ACTIONS, PANELS } from '../../../layout/enums';
const intlMessages = defineMessages({
@ -37,28 +37,27 @@ const UserPolls = ({
};
return (
<div className={styles.messages}>
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Messages>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.pollLabel)}
</h2>
</div>
<div className={styles.list}>
<div className={styles.scrollableList}>
<div
</Styled.SmallTitle>
</Styled.Container>
<Styled.List>
<Styled.ScrollableList>
<Styled.ListItem
role="button"
tabIndex={0}
className={styles.listItem}
data-test="pollMenuButton"
onClick={handleClickTogglePoll}
onKeyPress={() => {}}
>
<Icon iconName="polling" />
<span>{intl.formatMessage(intlMessages.pollLabel)}</span>
</div>
</div>
</div>
</div>
</Styled.ListItem>
</Styled.ScrollableList>
</Styled.List>
</Styled.Messages>
);
};

View File

@ -0,0 +1,25 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
const ListItem = styled(StyledContent.ListItem)``;
export default {
Messages,
Container,
SmallTitle,
ScrollableList,
List,
ListItem,
};

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import Icon from '/imports/ui/components/icon/component';
import { styles } from '/imports/ui/components/user-list/user-list-content/styles';
import Styled from './styles';
import { ACTIONS, PANELS } from '../../../layout/enums';
const propTypes = {
@ -42,35 +42,34 @@ const WaitingUsers = ({
};
return (
<div className={styles.messages}>
<div className={styles.container}>
<h2 className={styles.smallTitle}>
<Styled.Messages>
<Styled.Container>
<Styled.SmallTitle>
{intl.formatMessage(intlMessages.waitingUsersTitle)}
</h2>
</div>
<div className={styles.scrollableList}>
<div className={styles.list}>
<div
</Styled.SmallTitle>
</Styled.Container>
<Styled.ScrollableList>
<Styled.List>
<Styled.ListItem
role="button"
data-test="waitingUsersBtn"
tabIndex={0}
className={styles.listItem}
onClick={toggleWaitingPanel}
onKeyPress={() => { }}
>
<Icon iconName="user" />
<span>{intl.formatMessage(intlMessages.title)}</span>
{pendingUsers.length > 0 && (
<div className={styles.unreadMessages}>
<div className={styles.unreadMessagesText}>
<Styled.UnreadMessages>
<Styled.UnreadMessagesText>
{pendingUsers.length}
</div>
</div>
</Styled.UnreadMessagesText>
</Styled.UnreadMessages>
)}
</div>
</div>
</div>
</div>
</Styled.ListItem>
</Styled.List>
</Styled.ScrollableList>
</Styled.Messages>
);
};

View File

@ -0,0 +1,31 @@
import styled from 'styled-components';
import Styled from '/imports/ui/components/user-list/styles';
import StyledContent from '/imports/ui/components/user-list/user-list-content/styles';
const Messages = styled(Styled.Messages)``;
const Container = styled(StyledContent.Container)``;
const SmallTitle = styled(Styled.SmallTitle)``;
const ScrollableList = styled(StyledContent.ScrollableList)``;
const List = styled(StyledContent.List)``;
const ListItem = styled(StyledContent.ListItem)``;
const UnreadMessages = styled(StyledContent.UnreadMessages)``;
const UnreadMessagesText = styled(StyledContent.UnreadMessagesText)``;
export default {
Messages,
Container,
SmallTitle,
ScrollableList,
List,
ListItem,
UnreadMessages,
UnreadMessagesText,
};

View File

@ -0,0 +1,17 @@
const borderSize = '2px';
const smPaddingX = '.75rem';
const smPaddingY = '.3rem';
const mdPaddingY = '.45rem';
const mdPaddingX = '1rem';
const lgPaddingX = '1.25rem';
const lgPaddingY = '0.6rem';
export {
borderSize,
smPaddingX,
smPaddingY,
mdPaddingX,
mdPaddingY,
lgPaddingX,
lgPaddingY,
};

View File

@ -0,0 +1,35 @@
const colorWhite = '#FFF';
const colorOffWhite = '#F3F6F9';
const colorGray = '#4E5A66';
const colorGrayDark = '#06172A';
const colorGrayLight = '#8B9AA8';
const colorGrayLighter = '#A7B3BD';
const colorBlueLighter = '#92BCEA';
const colorPrimary = '#0F70D7';
const colorDanger = '#DF2721';
const userListBg = colorOffWhite;
const userListText = colorGray;
const unreadMessagesBg = colorDanger;
const listItemBgHover = '#DCE4ED';
const itemFocusBorder = colorBlueLighter;
export {
colorWhite,
colorOffWhite,
colorGray,
colorGrayDark,
colorGrayLight,
colorGrayLighter,
colorPrimary,
colorDanger,
userListBg,
userListText,
unreadMessagesBg,
listItemBgHover,
itemFocusBorder,
};

View File

@ -0,0 +1,10 @@
import styled from 'styled-components';
const FlexColumn = styled.div`
display: flex;
flex-flow: column;
`;
export {
FlexColumn,
}

View File

@ -0,0 +1,86 @@
import styled from 'styled-components';
import { List } from 'react-virtualized';
const ScrollboxVertical = styled.div`
overflow-y: auto;
background: linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background-repeat: no-repeat;
background-color: transparent;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
background-attachment: local, local, scroll, scroll;
// Fancy scroll
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-button {
width: 0;
height: 0;
}
&::-webkit-scrollbar-thumb {
background: rgba(0,0,0,.25);
border: none;
border-radius: 50px;
}
&::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.5); }
&::-webkit-scrollbar-thumb:active { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-track {
background: rgba(0,0,0,.25);
border: none;
border-radius: 50px;
}
&::-webkit-scrollbar-track:hover { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-track:active { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-corner { background: 0 0; }
`;
const VirtualizedScrollboxVertical = styled(List)`
overflow-y: auto;
background: linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background-repeat: no-repeat;
background-color: transparent;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
background-attachment: local, local, scroll, scroll;
// Fancy scroll
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-button {
width: 0;
height: 0;
}
&::-webkit-scrollbar-thumb {
background: rgba(0,0,0,.25);
border: none;
border-radius: 50px;
}
&::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.5); }
&::-webkit-scrollbar-thumb:active { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-track {
background: rgba(0,0,0,.25);
border: none;
border-radius: 50px;
}
&::-webkit-scrollbar-track:hover { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-track:active { background: rgba(0,0,0,.25); }
&::-webkit-scrollbar-corner { background: 0 0; }
`;
export {
ScrollboxVertical,
VirtualizedScrollboxVertical,
}

View File

@ -0,0 +1,13 @@
const lineHeightComputed = '1rem';
const fontSizeBase = '1rem';
const fontSizeSmall = '0.875rem';
const fontSizeSmaller = '.75rem';
const fontSizeXS = '.575rem';
export {
lineHeightComputed,
fontSizeBase,
fontSizeSmall,
fontSizeSmaller,
fontSizeXS,
};

View File

@ -11,6 +11,73 @@
"@babel/highlight": "^7.10.4"
}
},
"@babel/generator": {
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz",
"integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==",
"requires": {
"@babel/types": "^7.15.6",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
"dependencies": {
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
}
}
},
"@babel/helper-annotate-as-pure": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz",
"integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==",
"requires": {
"@babel/types": "^7.15.4"
}
},
"@babel/helper-function-name": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz",
"integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==",
"requires": {
"@babel/helper-get-function-arity": "^7.15.4",
"@babel/template": "^7.15.4",
"@babel/types": "^7.15.4"
}
},
"@babel/helper-get-function-arity": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz",
"integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==",
"requires": {
"@babel/types": "^7.15.4"
}
},
"@babel/helper-hoist-variables": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz",
"integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==",
"requires": {
"@babel/types": "^7.15.4"
}
},
"@babel/helper-module-imports": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz",
"integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==",
"requires": {
"@babel/types": "^7.15.4"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz",
"integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==",
"requires": {
"@babel/types": "^7.15.4"
}
},
"@babel/helper-validator-identifier": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
@ -54,6 +121,11 @@
}
}
},
"@babel/parser": {
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz",
"integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA=="
},
"@babel/runtime": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
@ -72,6 +144,168 @@
"regenerator-runtime": "^0.13.4"
}
},
"@babel/template": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz",
"integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==",
"requires": {
"@babel/code-frame": "^7.14.5",
"@babel/parser": "^7.15.4",
"@babel/types": "^7.15.4"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
"integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==",
"requires": {
"@babel/highlight": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
},
"@babel/highlight": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
"integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"requires": {
"@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"@babel/traverse": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz",
"integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==",
"requires": {
"@babel/code-frame": "^7.14.5",
"@babel/generator": "^7.15.4",
"@babel/helper-function-name": "^7.15.4",
"@babel/helper-hoist-variables": "^7.15.4",
"@babel/helper-split-export-declaration": "^7.15.4",
"@babel/parser": "^7.15.4",
"@babel/types": "^7.15.4",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
"integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==",
"requires": {
"@babel/highlight": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
},
"@babel/highlight": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
"integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"requires": {
"@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"@babel/types": {
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz",
"integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==",
"requires": {
"@babel/helper-validator-identifier": "^7.14.9",
"to-fast-properties": "^2.0.0"
},
"dependencies": {
"@babel/helper-validator-identifier": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
}
}
},
"@browser-bunyan/console-formatted-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/@browser-bunyan/console-formatted-stream/-/console-formatted-stream-1.6.2.tgz",
@ -121,6 +355,29 @@
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
},
"@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"requires": {
"@emotion/memoize": "0.7.4"
}
},
"@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
},
"@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"@eslint/eslintrc": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz",
@ -668,6 +925,22 @@
"integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==",
"dev": true
},
"babel-plugin-styled-components": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz",
"integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.15.4",
"@babel/helper-module-imports": "^7.15.4",
"babel-plugin-syntax-jsx": "^6.18.0",
"lodash": "^4.17.11"
}
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@ -805,6 +1078,11 @@
"quick-lru": "^4.0.1"
}
},
"camelize": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
},
"caniuse-lite": {
"version": "1.0.30001233",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz",
@ -1181,6 +1459,11 @@
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
},
"css-selector-tokenizer": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz",
@ -1191,6 +1474,16 @@
"fastparse": "^1.1.2"
}
},
"css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
"integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
"requires": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"css-vendor": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
@ -2859,6 +3152,11 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@ -3606,11 +3904,6 @@
"lru-cache": "^6.0.0"
}
},
"trim-newlines": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz",
"integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew=="
},
"type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
@ -5640,6 +5933,11 @@
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
},
"shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -5932,6 +6230,33 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"styled-components": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz",
"integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^0.8.8",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@ -6070,6 +6395,11 @@
"os-tmpdir": "~1.0.2"
}
},
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -6088,6 +6418,11 @@
"punycode": "^2.1.1"
}
},
"trim-newlines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
"integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="
},
"triple-beam": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",

View File

@ -76,6 +76,7 @@
"scheduler": "^0.20.2",
"sdp-transform": "2.7.0",
"string-hash": "~1.1.3",
"styled-components": "^5.3.3",
"tippy.js": "^5.1.3",
"use-context-selector": "^1.3.7",
"useragent": "^2.3.0",