FEAT Using a library for infinite scroll.
This is better. Always nice to let the professionals do all the hard lifting for ya when you're pressed for time. Also: Incorporated a pretty nice little modal pop-up. Styling sucks (at the moment), but I can fix that later.
This commit is contained in:
parent
642e7e9f2f
commit
73e310ea14
|
@ -3,6 +3,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@egjs/react-infinitegrid": "^3.0.5",
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
"react-modal": "^3.11.2",
|
||||||
"react-scripts": "3.4.3",
|
"react-scripts": "3.4.3",
|
||||||
"sass": "^1.26.10",
|
"sass": "^1.26.10",
|
||||||
"typescript": "^3.9.3"
|
"typescript": "^3.9.3"
|
||||||
|
@ -38,6 +40,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/react-modal": "^3.10.6",
|
||||||
"http-server": "^0.12.3"
|
"http-server": "^0.12.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
58
src/App.scss
58
src/App.scss
|
@ -9,6 +9,21 @@ body {
|
||||||
font-family: "Marcellus";
|
font-family: "Marcellus";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.current-card {
|
||||||
|
background: repeat url("images/elder_scrolling_bg.png") #0c0c0c;
|
||||||
|
color: #f8f8f8;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullcard tr td {
|
||||||
|
padding-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullcard tr td:nth-child(3) {
|
||||||
|
padding-left: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
body * {
|
body * {
|
||||||
font-family: "Marcellus";
|
font-family: "Marcellus";
|
||||||
}
|
}
|
||||||
|
@ -50,32 +65,29 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cardbox {
|
.card {
|
||||||
display: flex;
|
width: 192px;
|
||||||
flex-wrap: wrap;
|
height: 540px;
|
||||||
flex-direction: row;
|
border: 1px solid #707c80;
|
||||||
font-size: 1.4rem;
|
border-radius: 8px;
|
||||||
justify-content: space-between;
|
padding: 0.5rem;
|
||||||
align-content: space-between;
|
margin: 0.5rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 290px;
|
||||||
|
width: 175px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
line-height: 1.4;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.content table td {
|
||||||
width: 192px;
|
font-size: 1.4rem;
|
||||||
border: 1px solid #707c80;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin: 0.5rem;
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 290px;
|
|
||||||
width: 175px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-text {
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.lds-spinner-container {
|
.lds-spinner-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { CardProps } from "./types";
|
import { CardProps } from "./types";
|
||||||
|
|
||||||
export const Card = ({ card }: { card: CardProps }) => {
|
export const Card = ({
|
||||||
|
card,
|
||||||
|
onClick
|
||||||
|
}: {
|
||||||
|
card: CardProps;
|
||||||
|
onClick: Function | null;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="card" key="{idx}">
|
<div
|
||||||
|
className="card"
|
||||||
|
key="{idx}"
|
||||||
|
onClick={_event => onClick && onClick(card.id)}
|
||||||
|
>
|
||||||
<img src={card.imageUrl} alt={card.name} />
|
<img src={card.imageUrl} alt={card.name} />
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<h4>{card.name}</h4>
|
<h4>{card.name}</h4>
|
||||||
|
@ -28,4 +38,3 @@ export const Card = ({ card }: { card: CardProps }) => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@ import * as React from "react";
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import { Loading } from "./Loading";
|
import { Loading } from "./Loading";
|
||||||
import { Card } from "./Card";
|
import { Card } from "./Card";
|
||||||
import { useInfiniteScroll } from "./infiniteScroll";
|
import { JustifiedLayout, GridLayout } from "@egjs/react-infinitegrid";
|
||||||
|
import ReactModal from "react-modal";
|
||||||
|
import { FullCard, fullcardStyles } from "./FullCard";
|
||||||
import {
|
import {
|
||||||
CardProps,
|
CardProps,
|
||||||
CardRequestProps,
|
CardRequestProps,
|
||||||
|
@ -16,54 +18,85 @@ const firstUrl = `https://api.elderscrollslegends.io/v1/cards?pageSize=${PAGE_SI
|
||||||
|
|
||||||
const emptyCards: CardState = {
|
const emptyCards: CardState = {
|
||||||
cards: [],
|
cards: [],
|
||||||
next: firstUrl
|
next: firstUrl,
|
||||||
|
maxCards: -1
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Cards = () => {
|
export const Cards = () => {
|
||||||
const [cards, setCards]: CardStateHandler = useState(emptyCards);
|
const [cards, setCards]: CardStateHandler = useState(emptyCards);
|
||||||
const [cardPage, setCardPage]: [string | null, Function] = useState(null);
|
|
||||||
const [loading, setLoading]: [boolean, Function] = useState(false);
|
const [loading, setLoading]: [boolean, Function] = useState(false);
|
||||||
|
const [currentCard, setCurrentCard]: [CardProps | null, Function] = useState(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const getNextPage = () => {
|
const loadItems = () => {
|
||||||
setCardPage(cards.next);
|
if (cards.next === null || cards.cards.length === cards.maxCards) {
|
||||||
setLoading(true);
|
return;
|
||||||
};
|
|
||||||
|
|
||||||
let pageBottomRef = useRef(null);
|
|
||||||
useInfiniteScroll(pageBottomRef, getNextPage);
|
|
||||||
|
|
||||||
const fetchMoreCards = async () => {
|
|
||||||
if (cards.next === null || cardPage === null) {
|
|
||||||
return cards;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const request = new Request(cardPage!);
|
setLoading(true);
|
||||||
const response = await fetch(request);
|
const request = new Request(cards.next);
|
||||||
const data: CardRequestProps = await response.json();
|
fetch(request)
|
||||||
setCards({
|
.then(response => response.json())
|
||||||
cards: cards.cards.concat(data.cards),
|
.then((data: CardRequestProps) => {
|
||||||
next: data._links && data._links.next ? data._links.next : null
|
setCards({
|
||||||
});
|
cards: [...cards.cards, ...data.cards],
|
||||||
setLoading(false);
|
next: data._links && data._links.next ? data._links.next : null,
|
||||||
|
maxcards: data._totalCount
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cards.next && cardPage === null) {
|
const loadMoreCards = (options: any) => {
|
||||||
getNextPage();
|
if (options.startLoading !== null) {
|
||||||
}
|
options.startLoading();
|
||||||
|
}
|
||||||
|
loadItems();
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const onLayoutComplete = (options: any) => {
|
||||||
fetchMoreCards();
|
!options.isLayout && options.endLoading();
|
||||||
}, [cardPage]);
|
};
|
||||||
|
|
||||||
|
const handleCloseCard = () => {
|
||||||
|
setCurrentCard(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenCard = (id: string) => {
|
||||||
|
const card = cards.cards.find(card => card.id === id);
|
||||||
|
if (card) {
|
||||||
|
setCurrentCard(card);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="cardbox">
|
<ReactModal
|
||||||
|
isOpen={currentCard !== null}
|
||||||
|
style={fullcardStyles}
|
||||||
|
contentLabel=""
|
||||||
|
onRequestClose={handleCloseCard}
|
||||||
|
>
|
||||||
|
<FullCard card={currentCard} />
|
||||||
|
</ReactModal>
|
||||||
|
<GridLayout
|
||||||
|
options={{
|
||||||
|
isConstantSize: true,
|
||||||
|
isEqualSize: true,
|
||||||
|
transitionDuration: 0.2
|
||||||
|
}}
|
||||||
|
layoutOptions={{
|
||||||
|
margin: 10
|
||||||
|
}}
|
||||||
|
onAppend={loadMoreCards}
|
||||||
|
onLayoutComplete={onLayoutComplete}
|
||||||
|
>
|
||||||
{cards.cards.map((card: CardProps, count: number) => (
|
{cards.cards.map((card: CardProps, count: number) => (
|
||||||
<Card card={card} key={count} />
|
<Card card={card} key={count} onClick={handleOpenCard} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</GridLayout>
|
||||||
{loading && <Loading />}
|
{loading ? <Loading /> : ""}
|
||||||
<div id="page-bottom" ref={pageBottomRef} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { CardProps } from "./types";
|
||||||
|
|
||||||
|
export const fullcardStyles = {
|
||||||
|
content: {
|
||||||
|
backgroundColor: "#0c0c0c",
|
||||||
|
color: "#f8f8f8"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FullCard = ({ card }: { card: CardProps | null }) => {
|
||||||
|
if (card === null) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fullcard">
|
||||||
|
<img src={card.imageUrl} alt={card.name} />
|
||||||
|
<div className="content">
|
||||||
|
<h4>{card.name}</h4>
|
||||||
|
<p className="card-text">{card.text}</p>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Type</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.type}</td>
|
||||||
|
<td>
|
||||||
|
<strong>Cost</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.cost}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Subtypes</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.subtypes.join(", ")}</td>
|
||||||
|
<td>
|
||||||
|
<strong>Power</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.power}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Rarity</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.rarity}</td>
|
||||||
|
<td>
|
||||||
|
<strong>Health</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.health}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Set</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.set.name}</td>
|
||||||
|
<td>
|
||||||
|
<strong>Soul Summon</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.soulSummon}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Attributes</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.attributes.join(", ")}</td>
|
||||||
|
<td>
|
||||||
|
<strong>Soul Trap</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.soulTrap}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Keywords</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.keywords}</td>
|
||||||
|
<td />
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Set Name:</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.set.name}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Type:</strong>
|
||||||
|
</td>
|
||||||
|
<td>{card.type}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{card.collectible ? <p>This card is considered collectible.</p> : ""}
|
||||||
|
{card.unique ? (
|
||||||
|
<p>
|
||||||
|
This card is unique. Unique cards may only be used once per deck.
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,33 +0,0 @@
|
||||||
import * as React from "react";
|
|
||||||
import { useEffect, useCallback } from "react";
|
|
||||||
|
|
||||||
// From the Smashing Magazine article,
|
|
||||||
// https://www.smashingmagazine.com/2020/03/infinite-scroll-lazy-image-loading-react/
|
|
||||||
|
|
||||||
// As this is new to me, I'm going to try to explain it;
|
|
||||||
// IntersectionObserver takes a callback to be called when it's
|
|
||||||
// triggred. It's trigged when the node it's been asked to observe
|
|
||||||
// changes its relationship with another object or, without a
|
|
||||||
// specified object, with the viewport. When the `intersectionRatio`
|
|
||||||
// exceed zero, it is _intersecting_ the viewport, i.e. it is now
|
|
||||||
// visible.
|
|
||||||
|
|
||||||
// useCallback is a memoizer; it only updates the contents of the
|
|
||||||
// function its wrapped if the included function changes, which
|
|
||||||
// it shouldn't.
|
|
||||||
|
|
||||||
export const useInfiniteScroll = (scrollRef: React.RefObject<HTMLElement>, stateUpdate: Function) => {
|
|
||||||
const scrollObserver = (node: HTMLElement) => {
|
|
||||||
new IntersectionObserver(entries => {
|
|
||||||
if (entries.some(en => en.intersectionRatio > 0)) {
|
|
||||||
stateUpdate();
|
|
||||||
}
|
|
||||||
}).observe(node);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (scrollRef.current) {
|
|
||||||
scrollObserver(scrollRef.current);
|
|
||||||
}
|
|
||||||
}, [scrollObserver, scrollRef]);
|
|
||||||
}
|
|
|
@ -9,11 +9,14 @@ export interface CardProps {
|
||||||
rarity: string;
|
rarity: string;
|
||||||
type: string;
|
type: string;
|
||||||
cost: number;
|
cost: number;
|
||||||
|
power: number;
|
||||||
|
health: number;
|
||||||
set: SetProps;
|
set: SetProps;
|
||||||
collectible: boolean;
|
collectible: boolean;
|
||||||
soulSummon: number;
|
soulSummon: number;
|
||||||
soulTrap: number;
|
soulTrap: number;
|
||||||
text: string;
|
text: string;
|
||||||
|
subtypes: string[];
|
||||||
attributes: string[];
|
attributes: string[];
|
||||||
keywords: string[];
|
keywords: string[];
|
||||||
unique: boolean;
|
unique: boolean;
|
||||||
|
@ -33,11 +36,10 @@ export interface CardRequestProps {
|
||||||
_totalCount: number;
|
_totalCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface CardState {
|
export interface CardState {
|
||||||
cards: CardProps[];
|
cards: CardProps[];
|
||||||
next: string | null;
|
next: string | null;
|
||||||
|
maxCards: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CardStateHandler = [CardState, Function];
|
export type CardStateHandler = [CardState, Function];
|
||||||
|
|
||||||
|
|
70
yarn.lock
70
yarn.lock
|
@ -1166,6 +1166,40 @@
|
||||||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
||||||
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
||||||
|
|
||||||
|
"@egjs/component@^2.1.2":
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@egjs/component/-/component-2.1.2.tgz#c466a0a6fc6ba2d479814dcbe6ee4643c25a2e5b"
|
||||||
|
integrity sha512-7tnPiqxbSZ0porzlm0+/O3qZdanMj0zOq0sb17wQXuaRG49XKKKJaO+SacGnZDqf308N5hzJ0m9fZ4+j+VBvXA==
|
||||||
|
|
||||||
|
"@egjs/infinitegrid@^3.6.3":
|
||||||
|
version "3.6.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@egjs/infinitegrid/-/infinitegrid-3.6.3.tgz#f12f60b4d7d983a6cc0371735df69991101618cc"
|
||||||
|
integrity sha512-GELg3eeOjIvk6DkUB61sab2eyV8yJHB2npR7mHmp0rjGf3nJoEBR6A1FqjIrAtT+NjseBxTP2EqYRyI9CwhrIA==
|
||||||
|
dependencies:
|
||||||
|
"@egjs/component" "^2.1.2"
|
||||||
|
"@egjs/lazyloaded" "0.0.2"
|
||||||
|
"@egjs/list-differ" "^1.0.0"
|
||||||
|
|
||||||
|
"@egjs/lazyloaded@0.0.2":
|
||||||
|
version "0.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@egjs/lazyloaded/-/lazyloaded-0.0.2.tgz#1658a2188239e1c5e9dee71734830bcca6625388"
|
||||||
|
integrity sha512-UWgJCDHxsEP/sF+ztwl8F79rP1RHmlwG5ur0fFUT6RgaqKN6aQTnuYm9G/MQB48mWpw/tsY80Ha7xhvhryl+FA==
|
||||||
|
dependencies:
|
||||||
|
"@egjs/component" "^2.1.2"
|
||||||
|
|
||||||
|
"@egjs/list-differ@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@egjs/list-differ/-/list-differ-1.0.0.tgz#2277aff52e3e4bd9318d5c30ffc3ba3b6216f05e"
|
||||||
|
integrity sha512-HsbMKc0ZAQH+EUeCmI/2PvTYSybmkaWwakU8QGDYYgMVIg9BQ5sM0A0Nnombjxo2+JzXHxmH+jw//yGX+y6GYw==
|
||||||
|
|
||||||
|
"@egjs/react-infinitegrid@^3.0.5":
|
||||||
|
version "3.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@egjs/react-infinitegrid/-/react-infinitegrid-3.0.5.tgz#be3759b219c67d7f8e487a2857ccd7d453949b26"
|
||||||
|
integrity sha512-Lf90xlCuThKeg9JfZEd9gdn4a5WgHaL/DmsiS/qWe3dUs7XmEolvfh3tzCP6j8APt6ezQsblr0q/DpUnG/7xkg==
|
||||||
|
dependencies:
|
||||||
|
"@egjs/infinitegrid" "^3.6.3"
|
||||||
|
"@egjs/list-differ" "^1.0.0"
|
||||||
|
|
||||||
"@hapi/address@2.x.x":
|
"@hapi/address@2.x.x":
|
||||||
version "2.1.4"
|
version "2.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
|
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
|
||||||
|
@ -1671,6 +1705,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-modal@^3.10.6":
|
||||||
|
version "3.10.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-3.10.6.tgz#76717220f32bc72769190692147814a540053c7e"
|
||||||
|
integrity sha512-XpshhwVYir1TRZ2HS5EfmNotJjB8UEC2IkT3omNtiQzROOXSzVLz5xsjwEpACP8U+PctkpfZepX+WT5oDf0a9g==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^16.9.49":
|
"@types/react@*", "@types/react@^16.9.49":
|
||||||
version "16.9.49"
|
version "16.9.49"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872"
|
||||||
|
@ -4528,6 +4569,11 @@ execa@^1.0.0:
|
||||||
signal-exit "^3.0.0"
|
signal-exit "^3.0.0"
|
||||||
strip-eof "^1.0.0"
|
strip-eof "^1.0.0"
|
||||||
|
|
||||||
|
exenv@^1.2.0:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
|
integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
|
||||||
|
|
||||||
exit@^0.1.2:
|
exit@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||||
|
@ -8856,7 +8902,7 @@ prompts@^2.0.1:
|
||||||
kleur "^3.0.3"
|
kleur "^3.0.3"
|
||||||
sisteransi "^1.0.4"
|
sisteransi "^1.0.4"
|
||||||
|
|
||||||
prop-types@^15.6.2, prop-types@^15.7.2:
|
prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
|
@ -9082,6 +9128,21 @@ react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-lifecycles-compat@^3.0.0:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-modal@^3.11.2:
|
||||||
|
version "3.11.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.11.2.tgz#bad911976d4add31aa30dba8a41d11e21c4ac8a4"
|
||||||
|
integrity sha512-o8gvvCOFaG1T7W6JUvsYjRjMVToLZgLIsi5kdhFIQCtHxDkA47LznX62j+l6YQkpXDbvQegsDyxe/+JJsFQN7w==
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.0"
|
||||||
|
prop-types "^15.5.10"
|
||||||
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
warning "^4.0.3"
|
||||||
|
|
||||||
react-scripts@3.4.3:
|
react-scripts@3.4.3:
|
||||||
version "3.4.3"
|
version "3.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.3.tgz#21de5eb93de41ee92cd0b85b0e1298d0bb2e6c51"
|
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.3.tgz#21de5eb93de41ee92cd0b85b0e1298d0bb2e6c51"
|
||||||
|
@ -10990,6 +11051,13 @@ walker@^1.0.7, walker@~1.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
makeerror "1.0.x"
|
makeerror "1.0.x"
|
||||||
|
|
||||||
|
warning@^4.0.3:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||||
|
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.0.0"
|
||||||
|
|
||||||
watchpack-chokidar2@^2.0.0:
|
watchpack-chokidar2@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
||||||
|
|
Loading…
Reference in New Issue