Add ReactIcons (#149)

This commit is contained in:
Riccardo Graziosi
2022-08-22 10:38:03 +02:00
committed by GitHub
parent 4c73b398e8
commit 6198d814d8
32 changed files with 267 additions and 226 deletions

View File

@@ -1,6 +1,9 @@
import * as React from 'react';
import I18n from 'i18n-js';
import Button from '../common/Button';
import Switch from '../common/Switch';
import ActionLink from '../common/ActionLink';
import { CancelIcon } from '../common/Icons';
interface Props {
id: number;
@@ -61,34 +64,23 @@ class CommentEditForm extends React.Component<Props, State> {
<div>
<div>
{
isPowerUser ?
<>
<input
id={`isPostUpdateFlagComment${id}`}
type="checkbox"
onChange={e => this.handleCommentIsPostUpdateChange(e.target.checked)}
checked={isPostUpdate || false}
/>
&nbsp;
<label htmlFor={`isPostUpdateFlagComment${id}`}>
{I18n.t('post.new_comment.is_post_update')}
</label>
</>
:
null
isPowerUser &&
<Switch
htmlId={`isPostUpdateFlagComment${id}`}
onClick={e => this.handleCommentIsPostUpdateChange(!isPostUpdate)}
checked={isPostUpdate || false}
label={I18n.t('post.new_comment.is_post_update')}
/>
}
</div>
<div>
<a className="commentLink" onClick={toggleEditMode}>
{ I18n.t('common.buttons.cancel') }
</a>
<div className="editCommentFormActions">
<ActionLink onClick={toggleEditMode} icon={<CancelIcon />}>
{I18n.t('common.buttons.cancel')}
</ActionLink>
&nbsp;
<Button
onClick={() => handleUpdateComment(body, isPostUpdate)}
>
{ I18n.t('common.buttons.update') }
<Button onClick={() => handleUpdateComment(body, isPostUpdate)}>
{I18n.t('common.buttons.update')}
</Button>
</div>
</div>

View File

@@ -5,6 +5,8 @@ import Separator from '../common/Separator';
import { MutedText } from '../common/CustomTexts';
import friendlyDate from '../../helpers/datetime';
import { ReplyFormState } from '../../reducers/replyFormReducer';
import ActionLink from '../common/ActionLink';
import { CancelIcon, DeleteIcon, EditIcon, ReplyIcon } from '../common/Icons';
interface Props {
id: number;
@@ -34,43 +36,43 @@ const CommentFooter = ({
toggleEditMode,
}: Props) => (
<div className="commentFooter">
<a className="commentReplyButton commentLink" onClick={handleToggleCommentReply}>
<ActionLink
onClick={handleToggleCommentReply}
icon={replyForm.isOpen ? <CancelIcon /> : <ReplyIcon />}
>
{
replyForm.isOpen ?
I18n.t('common.buttons.cancel')
:
I18n.t('post.comments.reply_button')
}
</a>
</ActionLink>
{
isPowerUser || currentUserEmail === commentAuthorEmail ?
<>
<Separator />
<a onClick={toggleEditMode} className="commentLink">
<ActionLink onClick={toggleEditMode} icon={<EditIcon />}>
{I18n.t('common.buttons.edit')}
</a>
</ActionLink>
<Separator />
<a
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDeleteComment(id)}
className="commentLink">
{I18n.t('common.buttons.delete')}
</a>
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</ActionLink>
</>
:
null
}
<Separator />
<MutedText>{friendlyDate(createdAt)}</MutedText>
{
createdAt !== updatedAt ?
createdAt !== updatedAt &&
<>
<Separator />
<MutedText>{ I18n.t('common.edited').toLowerCase() }</MutedText>
</>
:
null
}
</div>
);

View File

@@ -2,6 +2,7 @@ import * as React from 'react';
import I18n from 'i18n-js';
import { MutedText } from '../common/CustomTexts';
import Switch from '../common/Switch';
interface Props {
postUpdateFlagValue: boolean;
@@ -13,21 +14,15 @@ const NewCommentUpdateSection = ({
handlePostUpdateFlag,
}: Props) => (
<div className="commentIsUpdateForm">
<div>
<input
id="isPostUpdateFlag"
type="checkbox"
onChange={handlePostUpdateFlag}
checked={postUpdateFlagValue || false}
/>
&nbsp;
<label htmlFor="isPostUpdateFlag">{I18n.t('post.new_comment.is_post_update')}</label>
</div>
<Switch
htmlId="isPostUpdateFlag"
onClick={handlePostUpdateFlag}
checked={postUpdateFlagValue || false}
label={I18n.t('post.new_comment.is_post_update')}
/>
{
postUpdateFlagValue ?
postUpdateFlagValue &&
<MutedText>{I18n.t('post.new_comment.user_notification')}</MutedText>
:
null
}
</div>
);

View File

@@ -8,6 +8,8 @@ import IPostStatus from '../../interfaces/IPostStatus';
import IBoard from '../../interfaces/IBoard';
import Button from '../common/Button';
import Spinner from '../common/Spinner';
import ActionLink from '../common/ActionLink';
import { CancelIcon } from '../common/Icons';
interface Props {
title: string;
@@ -93,9 +95,9 @@ const PostEditForm = ({
/>
<div className="postEditFormButtons">
<a onClick={toggleEditMode}>
{ I18n.t('common.buttons.cancel') }
</a>
<ActionLink onClick={toggleEditMode} icon={<CancelIcon />}>
{I18n.t('common.buttons.cancel')}
</ActionLink>
&nbsp;
<Button onClick={() => handleUpdatePost(title, description, boardId, postStatusId)}>
{ isUpdating ? <Spinner /> : I18n.t('common.buttons.update') }

View File

@@ -5,6 +5,8 @@ import I18n from 'i18n-js';
import { MutedText } from '../common/CustomTexts';
import friendlyDate from '../../helpers/datetime';
import Separator from '../common/Separator';
import ActionLink from '../common/ActionLink';
import { DeleteIcon, EditIcon } from '../common/Icons';
interface Props {
createdAt: string;
@@ -27,26 +29,29 @@ const PostFooter = ({
}: Props) => (
<div className="postFooter">
<div className="postAuthor">
<span>{ I18n.t('post.published_by').toLowerCase() } &nbsp;</span>
<span>{I18n.t('post.published_by').toLowerCase()} &nbsp;</span>
<Gravatar email={authorEmail} size={24} className="postAuthorAvatar" /> &nbsp;
{authorFullName}
<Separator />
{friendlyDate(createdAt)}
</div>
{
isPowerUser || authorEmail === currentUserEmail ?
<>
<a onClick={toggleEditMode}>
{ I18n.t('common.buttons.edit') }
</a>
<Separator />
<a onClick={() => confirm(I18n.t('common.confirmation')) && handleDeletePost()}>
{ I18n.t('common.buttons.delete') }
</a>
<Separator />
</>
<div className="postFooterActions">
<ActionLink onClick={toggleEditMode} icon={<EditIcon />}>
{I18n.t('common.buttons.edit')}
</ActionLink>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDeletePost()}
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</ActionLink>
</div>
:
null
}
<MutedText>{friendlyDate(createdAt)}</MutedText>
</div>
);

View File

@@ -9,6 +9,8 @@ import { IOAuth } from '../../../interfaces/IOAuth';
import { AuthenticationPages } from './AuthenticationSiteSettingsP';
import { useState } from 'react';
import Separator from '../../common/Separator';
import ActionLink from '../../common/ActionLink';
import { BackIcon } from '../../common/Icons';
interface Props {
selectedOAuth: IOAuth;
@@ -88,16 +90,18 @@ const OAuthForm = ({
return (
<>
<a
<ActionLink
onClick={() => {
let confirmation = true;
if (isDirty)
confirmation = confirm(I18n.t('common.unsaved_changes') + ' ' + I18n.t('common.confirmation'));
if (confirmation) setPage('index');
}}
className="backButton link">
{ I18n.t('common.buttons.back') }
</a>
icon={<BackIcon />}
customClass="backButton"
>
{I18n.t('common.buttons.back')}
</ActionLink>
<h2>{ I18n.t(`site_settings.authentication.form.title_${page}`) }</h2>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="formRow">

View File

@@ -6,6 +6,8 @@ import Switch from '../../common/Switch';
import Separator from '../../common/Separator';
import { AuthenticationPages } from './AuthenticationSiteSettingsP';
import CopyToClipboardButton from '../../common/CopyToClipboardButton';
import ActionLink from '../../common/ActionLink';
import { DeleteIcon, EditIcon, TestIcon } from '../../common/Icons';
interface Props {
oAuth: IOAuth;
@@ -44,23 +46,32 @@ const OAuthProviderItem = ({
label={I18n.t('site_settings.authentication.copy_url')}
textToCopy={oAuth.callbackUrl}
/>
<Separator />
<a onClick={() =>
window.open(`/o_auths/${oAuth.id}/start?reason=test`, '', 'width=640, height=640')
}>
Test
</a>
<Separator />
<a onClick={() => {
setSelectedOAuth(oAuth.id);
setPage('edit');
}}>
{ I18n.t('common.buttons.edit') }
</a>
<Separator />
<a onClick={() => confirm(I18n.t('common.confirmation')) && handleDeleteOAuth(oAuth.id)}>
{ I18n.t('common.buttons.delete') }
</a>
<ActionLink
onClick={() =>
window.open(`/o_auths/${oAuth.id}/start?reason=test`, '', 'width=640, height=640')
}
icon={<TestIcon />}
>
{I18n.t('common.buttons.test')}
</ActionLink>
<ActionLink
onClick={() => {
setSelectedOAuth(oAuth.id);
setPage('edit');
}}
icon={<EditIcon />}
>
{I18n.t('common.buttons.edit')}
</ActionLink>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDeleteOAuth(oAuth.id)}
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</ActionLink>
</div>
</li>
);

View File

@@ -8,6 +8,8 @@ import DragZone from '../../common/DragZone';
import PostBoardLabel from '../../common/PostBoardLabel';
import Separator from '../../common/Separator';
import BoardForm from './BoardForm';
import ActionLink from '../../common/ActionLink';
import { CancelIcon, DeleteIcon, EditIcon } from '../../common/Icons';
interface Props {
id: number;
@@ -83,13 +85,16 @@ class BoardsEditable extends React.Component<Props, State> {
</div>
<div className="boardEditableActions">
<a onClick={this.toggleEditMode}>{I18n.t('common.buttons.edit')}</a>
<ActionLink onClick={this.toggleEditMode} icon={<EditIcon />}>
{I18n.t('common.buttons.edit')}
</ActionLink>
<Separator />
<a onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</a>
</ActionLink>
</div>
</>
:
@@ -102,11 +107,12 @@ class BoardsEditable extends React.Component<Props, State> {
handleUpdate={this.handleUpdate}
/>
<a
className="boardFormCancelButton"
onClick={this.toggleEditMode}>
<ActionLink
onClick={this.toggleEditMode}
icon={<CancelIcon />}
>
{I18n.t('common.buttons.cancel')}
</a>
</ActionLink>
</>
}
</li>

View File

@@ -68,6 +68,7 @@ const BoardForm = ({
{...register('name', { required: true })}
placeholder={I18n.t('site_settings.boards.form.name')}
autoFocus={mode === 'update'}
autoComplete={'off'}
className="formControl"
/>

View File

@@ -6,6 +6,8 @@ import PostStatusLabel from "../../common/PostStatusLabel";
import DragZone from '../../common/DragZone';
import Separator from '../../common/Separator';
import PostStatusForm from './PostStatusForm';
import ActionLink from '../../common/ActionLink';
import { CancelIcon, DeleteIcon, EditIcon } from '../../common/Icons';
interface Props {
id: number;
@@ -74,13 +76,16 @@ class PostStatusEditable extends React.Component<Props, State> {
<PostStatusLabel name={name} color={color} />
<div className="postStatusEditableActions">
<a onClick={this.toggleEditMode}>{I18n.t('common.buttons.edit')}</a>
<ActionLink onClick={this.toggleEditMode} icon={<EditIcon />}>
{I18n.t('common.buttons.edit')}
</ActionLink>
<Separator />
<a onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</a>
</ActionLink>
</div>
</>
:
@@ -93,11 +98,12 @@ class PostStatusEditable extends React.Component<Props, State> {
handleUpdate={this.handleUpdate}
/>
<a
className="postStatusFormCancelButton"
onClick={this.toggleEditMode}>
<ActionLink
onClick={this.toggleEditMode}
icon={<CancelIcon />}
>
{I18n.t('common.buttons.cancel')}
</a>
</ActionLink>
</>
}
</li>

View File

@@ -72,6 +72,7 @@ const PostStatusForm = ({
{...register('name', { required: true })}
placeholder={I18n.t('site_settings.post_statuses.form.name')}
autoFocus={mode === 'update'}
autoComplete={'off'}
className="formControl"
/>

View File

@@ -6,6 +6,8 @@ import IUser, { UserRoles, USER_ROLE_ADMIN, USER_ROLE_USER, USER_STATUS_ACTIVE,
import Separator from "../../common/Separator";
import UserForm from "./UserForm";
import { MutedText } from "../../common/CustomTexts";
import { BlockIcon, CancelIcon, EditIcon, UnblockIcon } from "../../common/Icons";
import ActionLink from "../../common/ActionLink";
interface Props {
user: IUser;
@@ -119,18 +121,18 @@ class UserEditable extends React.Component<Props, State> {
</div>
<div className="userEditableActions">
<a
<ActionLink
onClick={() => editEnabled && this.toggleEditMode()}
className={editEnabled ? '' : 'actionDisabled'}
icon={<EditIcon />}
disabled={!editEnabled}
>
{ I18n.t('common.buttons.edit') }
</a>
</ActionLink>
<Separator />
<a
<ActionLink
onClick={() => blockEnabled && this._handleUpdateUserStatus()}
className={blockEnabled ? '' : 'actionDisabled'}
icon={user.status !== USER_STATUS_BLOCKED ? <BlockIcon /> : <UnblockIcon />}
disabled={!blockEnabled}
>
{
user.status !== USER_STATUS_BLOCKED ?
@@ -138,15 +140,15 @@ class UserEditable extends React.Component<Props, State> {
:
I18n.t('site_settings.users.unblock')
}
</a>
</ActionLink>
</div>
</>
:
<>
<UserForm user={user} updateUserRole={this._handleUpdateUserRole} />
<a onClick={this.toggleEditMode} className="userEditCancelButton">
{ I18n.t('common.buttons.cancel') }
</a>
<ActionLink onClick={this.toggleEditMode} icon={<CancelIcon />}>
{I18n.t('common.buttons.cancel')}
</ActionLink>
</>
}
</li>

View File

@@ -0,0 +1,26 @@
import * as React from 'react';
interface Props {
onClick: React.MouseEventHandler<HTMLAnchorElement>;
icon?: React.ReactElement;
disabled?: boolean;
customClass?: string;
children: React.ReactNode;
}
const ActionLink = ({
onClick,
icon,
disabled = false,
customClass,
children,
}: Props) => (
<a
onClick={onClick}
className={`actionLink${disabled ? ' actionLinkDisabled' : ''}${customClass ? ' ' + customClass : ''}`}
>
{icon}{children}
</a>
);
export default ActionLink;

View File

@@ -1,6 +1,8 @@
import * as React from 'react';
import I18n from 'i18n-js';
import { useState } from 'react';
import ActionLink from './ActionLink';
import { CopyIcon, DoneIcon } from './Icons';
interface Props {
label: string;
@@ -20,7 +22,7 @@ const CopyToClipboardButton = ({
return (
ready ?
<a
<ActionLink
onClick={() => {
if (navigator.clipboard) {
navigator.clipboard.writeText(textToCopy).then(() => {
@@ -32,11 +34,14 @@ const CopyToClipboardButton = ({
alertError();
}
}}
icon={<CopyIcon />}
>
{label}
</a>
</ActionLink>
:
<span>{copiedLabel}</span>
<span style={{display: 'flex', marginRight: 12}}>
{copiedLabel}
</span>
);
};

View File

@@ -1,11 +1,22 @@
import * as React from 'react';
import { MdDragIndicator } from 'react-icons/md';
const DragZone = ({dndProvided, isDragDisabled, color = 'black'}) => (
interface Props {
dndProvided: any;
isDragDisabled: boolean;
color?: 'black' | 'white';
}
const DragZone = ({
dndProvided,
isDragDisabled,
color = 'black',
}: Props) => (
<span
className={`drag-zone${isDragDisabled ? ' drag-zone-disabled' : ''}`}
{...dndProvided.dragHandleProps}
>
<span className={`drag-icon${color === 'white' ? ' drag-icon-white' : ''}`}></span>
<MdDragIndicator color={color} size={18} />
</span>
);

View File

@@ -0,0 +1,28 @@
import * as React from 'react';
import { BsReply } from 'react-icons/bs';
import { FiEdit, FiDelete } from 'react-icons/fi';
import { ImCancelCircle } from 'react-icons/im';
import { TbLock, TbLockOpen } from 'react-icons/tb';
import { MdContentCopy, MdDone, MdOutlineArrowBack } from 'react-icons/md';
import { GrTest } from 'react-icons/gr';
export const EditIcon = () => <FiEdit />;
export const DeleteIcon = () => <FiDelete />;
export const CancelIcon = () => <ImCancelCircle />;
export const BlockIcon = () => <TbLock />;
export const UnblockIcon = () => <TbLockOpen />;
export const CopyIcon = () => <MdContentCopy />;
export const TestIcon = () => <GrTest />;
export const DoneIcon = () => <MdDone />;
export const BackIcon = () => <MdOutlineArrowBack />;
export const ReplyIcon = () => <BsReply />;

View File

@@ -187,4 +187,25 @@
.link {
cursor: pointer;
&:hover { text-decoration: underline; }
}
.actionLink {
display: flex;
cursor: pointer;
align-self: center;
margin-right: 12px;
&:hover { text-decoration: underline !important; }
svg {
margin-right: 4px;
align-self: center;
}
&.actionLinkDisabled {
color: $astuto-grey !important;
text-decoration: none !important;
cursor: not-allowed;
}
}

View File

@@ -1,15 +1,6 @@
.commentsContainer {
@extend .my-3;
a.commentLink {
color: $primary-color;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
.commentForm {
@extend
.form-control,
@@ -41,7 +32,7 @@
.justify-content-between,
.mt-3;
margin-left: 48px;
margin-left: 58px;
}
.currentUserAvatar {
@@ -71,6 +62,8 @@
.d-flex,
.justify-content-between;
}
.editCommentFormActions { @extend .d-flex; }
}
.commentsTitle {
@@ -113,7 +106,9 @@
}
.commentFooter {
font-size: 14px;
@extend .d-flex;
font-size: 13px;
}
}
}

View File

@@ -141,12 +141,7 @@
.postAuthorAvatar { @extend .gravatar; }
}
a {
&:hover {
cursor: pointer;
text-decoration: underline;
}
}
.postFooterActions { @extend .d-flex; }
}
.postEditForm {
@@ -155,14 +150,7 @@
}
.postEditFormButtons {
text-align: right;
a {
&:hover {
cursor: pointer;
text-decoration: underline;
}
}
@extend .d-flex, .justify-content-end;
}
}
}

View File

@@ -25,6 +25,7 @@
.columnTitle {
color: white;
text-transform: uppercase;
}
}

View File

@@ -34,11 +34,9 @@
}
.oAuthActions {
align-self: center;
@extend .d-flex;
a {
@extend .link;
}
align-self: center;
}
}
}
@@ -46,12 +44,8 @@
.authenticationFormPage {
a.backButton {
@extend .mb-2;
@extend .mb-2, .align-self-start;
font-size: 18px;
}
a.link {
@extend .link;
}
}

View File

@@ -13,12 +13,6 @@
column-gap: 32px;
a {
cursor: pointer;
&:hover { text-decoration: underline; }
}
.boardInfo {
@extend
.d-flex,
@@ -30,8 +24,8 @@
.boardDescription { @extend .text-center; }
}
.boardEditableActions, .boardFormCancelButton {
@extend .align-self-center;
.boardEditableActions {
@extend .d-flex, .align-self-center;
}
}
}

View File

@@ -11,15 +11,7 @@
.justify-content-between,
.p-3;
a {
cursor: pointer;
&:hover { text-decoration: underline; }
}
.postStatusFormCancelButton {
align-self: center;
}
.postStatusEditableActions { @extend .d-flex; }
}
}

View File

@@ -45,6 +45,7 @@
color: white;
padding: 8px 4px;
text-transform: uppercase;
.titleText { @extend .align-self-center; }
}

View File

@@ -30,7 +30,7 @@ ul.usersList {
}
.userEditableActions {
@extend .align-self-center;
@extend .d-flex, .align-self-center;
}
.userForm {
@@ -41,24 +41,8 @@ ul.usersList {
}
}
.updateUserButton { @extend .align-self-center; }
.userEditCancelButton { @extend .align-self-center; }
a {
cursor: pointer;
&:hover { text-decoration: underline; }
}
a.actionDisabled {
@extend .mutedText;
text-decoration: none;
cursor: not-allowed;
}
.updateUserButton {
@extend .align-self-center;
margin-left: 16px;
}

View File

@@ -1,28 +0,0 @@
/* Code taken from: https://gist.github.com/JakeSidSmith/83c324dbe7e4d91ee8c52525b1d504d9 */
/* Thanks JakeSidSmith */
span.drag-icon {
display: inline-block;
width: 16px;
height: 8px;
}
span.drag-icon,
span.drag-icon::before {
background-image: radial-gradient(black 40%, transparent 40%);
background-size: 4px 4px;
background-position: 0 100%;
background-repeat: repeat-x;
}
span.drag-icon.drag-icon-white,
span.drag-icon.drag-icon-white::before {
background-image: radial-gradient(white 40%, transparent 40%);
}
span.drag-icon::before {
content: '';
display: block;
width: 100%;
height: 33%;
}

View File

@@ -22,7 +22,4 @@
@import 'components/SiteSettings/PostStatuses';
@import 'components/SiteSettings/Roadmap';
@import 'components/SiteSettings/Users';
@import 'components/SiteSettings/Authentication';
/* Icons */
@import 'icons/drag_icon';
@import 'components/SiteSettings/Authentication';

View File

@@ -40,10 +40,9 @@
<div class="actions">
<%= f.submit t('common.forms.auth.sign_up'), class: "btn btn-dark btn-block" %>
</div>
<hr />
<% if not @o_auths.empty? %>
<hr />
<% @o_auths.each do |o_auth| %>
<p>
<%= link_to t('common.forms.auth.sign_up_with', { o_auth: o_auth.name }),

View File

@@ -29,10 +29,9 @@
<div class="actions">
<%= f.submit t('common.forms.auth.log_in'), class: "btn btn-dark btn-block" %>
</div>
<hr />
<% if not @o_auths.empty? %>
<hr />
<% @o_auths.each do |o_auth| %>
<p>
<%= link_to t('common.forms.auth.log_in_with', { o_auth: o_auth.name }),

View File

@@ -53,6 +53,7 @@ en:
update: 'Save'
confirm: 'Confirm'
back: 'Back'
test: 'Test'
datetime:
now: 'just now'
minutes:

View File

@@ -22,6 +22,7 @@
"react-dom": "^16.9.0",
"react-gravatar": "^2.6.3",
"react-hook-form": "7.33.1",
"react-icons": "4.4.0",
"react-infinite-scroller": "^1.2.4",
"react-markdown": "^5.0.3",
"react-redux": "^7.1.1",

View File

@@ -6388,6 +6388,11 @@ react-hook-form@7.33.1:
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.33.1.tgz#8c4410e3420788d3b804d62cc4c142915c2e46d0"
integrity sha512-ydTfTxEJdvgjCZBj5DDXRc58oTEfnFupEwwTAQ9FSKzykEJkX+3CiAkGtAMiZG7IPWHuzgT6AOBfogiKhUvKgg==
react-icons@4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.4.0.tgz#a13a8a20c254854e1ec9aecef28a95cdf24ef703"
integrity sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==
react-infinite-scroller@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz#f67eaec4940a4ce6417bebdd6e3433bfc38826e9"