mirror of
https://github.com/FlipsideCrypto/flipside-js.git
synced 2026-02-06 10:48:11 +00:00
Merge pull request #1 from FlipsideCrypto/spectrum-updated
Spectrum updates
This commit is contained in:
commit
88d736fda3
@ -23,6 +23,7 @@
|
||||
"@types/lodash": "^4.14.120",
|
||||
"@types/node": "^10.12.19",
|
||||
"babel-loader": "^8.0.4",
|
||||
"core-js": "^2.6.5",
|
||||
"css-loader": "^1.0.1",
|
||||
"css-modules-typescript-loader": "^1.1.1",
|
||||
"node-sass": "^4.10.0",
|
||||
|
||||
@ -79,7 +79,7 @@ export default class API {
|
||||
export type WidgetLinksSlug = "spectrum" | "multi-table" | "table" | "score";
|
||||
export type WidgetLinksLink = {
|
||||
widget_id: string;
|
||||
name: "right_link" | "left_link";
|
||||
name: string;
|
||||
link_html: string;
|
||||
};
|
||||
export type WidgetLinksResponse = {
|
||||
|
||||
@ -44,8 +44,15 @@ class CustomLinks extends Component<Props, State> {
|
||||
|
||||
const leftLink = find(state.links, { name: "left_link" });
|
||||
const rightLink = find(state.links, { name: "right_link" });
|
||||
const topLink = find(state.links, { name: "top_link" });
|
||||
return (
|
||||
<div class={css.wrapper} style={props.style}>
|
||||
{topLink && (
|
||||
<span
|
||||
class={linkClass}
|
||||
dangerouslySetInnerHTML={{ __html: topLink.link_html }}
|
||||
/>
|
||||
)}
|
||||
{leftLink && (
|
||||
<span
|
||||
class={linkClass}
|
||||
|
||||
@ -4,7 +4,8 @@ import * as css from "./style.css";
|
||||
|
||||
type Props = {
|
||||
score: number;
|
||||
kind?: "slim" | "large";
|
||||
kind?: "slim" | "normal" | "large";
|
||||
class?: string;
|
||||
};
|
||||
|
||||
type State = {
|
||||
@ -42,10 +43,7 @@ export default class Rank extends Component<Props, State> {
|
||||
rankClass = css.s;
|
||||
}
|
||||
|
||||
let kindClass = css.slim;
|
||||
if (props.kind === "large") {
|
||||
kindClass = css.large;
|
||||
}
|
||||
let kindClass = css[props.kind];
|
||||
|
||||
const classes = classNames(css.rank, rankClass, kindClass);
|
||||
return (
|
||||
|
||||
@ -39,6 +39,12 @@
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.normal {
|
||||
background-size: auto 70%;
|
||||
width: 54px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.large {
|
||||
background-size: auto 48%;
|
||||
height: 28px;
|
||||
|
||||
1
src/components/rank/style.css.d.ts
vendored
1
src/components/rank/style.css.d.ts
vendored
@ -5,6 +5,7 @@ export const b: string;
|
||||
export const c: string;
|
||||
export const f: string;
|
||||
export const large: string;
|
||||
export const normal: string;
|
||||
export const rank: string;
|
||||
export const s: string;
|
||||
export const slim: string;
|
||||
|
||||
@ -23,7 +23,7 @@ const Trend = (props: Props) => {
|
||||
}
|
||||
|
||||
const difference = calculateTrendDiff(props.value, props.change);
|
||||
const classes = classNames(directionClass, props.class);
|
||||
const classes = classNames(css.wrapper, directionClass, props.class);
|
||||
|
||||
return (
|
||||
<span class={classes}>
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 6px;
|
||||
margin-right: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.up {
|
||||
|
||||
1
src/components/trend/style.css.d.ts
vendored
1
src/components/trend/style.css.d.ts
vendored
@ -3,3 +3,4 @@
|
||||
export const down: string;
|
||||
export const icon: string;
|
||||
export const up: string;
|
||||
export const wrapper: string;
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
// ie11 polyfills
|
||||
import "core-js/fn/promise";
|
||||
import "core-js/fn/object/assign";
|
||||
|
||||
import { h, render } from "preact";
|
||||
import API from "./api";
|
||||
import Table from "./table";
|
||||
import { defaultsWithoutArrays } from "./utils";
|
||||
import SpectrumPlot, { Props as SpectrumPlotProps } from "./spectrumPlot";
|
||||
import Spectrum, { Props as SpectrumProps } from "./spectrum";
|
||||
import MultiTable, { Props as MultiTableProps } from "./multiTable";
|
||||
import Score, { Props as ScoreProps } from "./score";
|
||||
|
||||
@ -19,10 +23,10 @@ export default class Flipside {
|
||||
render(<MultiTable {...props} api={this.api} />, element);
|
||||
}
|
||||
|
||||
spectrum(el: string, opts: SpectrumPlotProps): void {
|
||||
spectrum(el: string, opts: SpectrumProps): void {
|
||||
const element = document.getElementById(el);
|
||||
const props = defaultsWithoutArrays(SpectrumPlot.defaultProps, opts);
|
||||
render(<SpectrumPlot {...props} api={this.api} />, element);
|
||||
const props = defaultsWithoutArrays(Spectrum.defaultProps, opts);
|
||||
render(<Spectrum {...props} api={this.api} />, element);
|
||||
}
|
||||
|
||||
score(el: string, opts: ScoreProps) {
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
.change {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.trend {
|
||||
|
||||
51
src/spectrum/components/carousel/index.tsx
Normal file
51
src/spectrum/components/carousel/index.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { h, Component, ComponentChildren } from "preact";
|
||||
import classNames from "classnames";
|
||||
import * as css from "./style.css";
|
||||
|
||||
type Props = {
|
||||
mode: "light" | "dark";
|
||||
items: any[];
|
||||
renderSlide: any;
|
||||
};
|
||||
|
||||
type State = {
|
||||
currentSlide: number;
|
||||
};
|
||||
|
||||
export default class Carousel extends Component<Props, State> {
|
||||
state = {
|
||||
currentSlide: 0
|
||||
};
|
||||
|
||||
slideTo = (slide: number) => {
|
||||
this.setState({ currentSlide: slide });
|
||||
};
|
||||
|
||||
render(props: Props, state: State) {
|
||||
const carouselOffset = state.currentSlide * 100;
|
||||
const carouselStyle = {
|
||||
transform: `translateX(-${carouselOffset}%)`
|
||||
};
|
||||
|
||||
return (
|
||||
<div class={classNames(css.wrapper, css[props.mode])}>
|
||||
<div class={css.carousel} style={carouselStyle}>
|
||||
{props.items.map(item => (
|
||||
<div class={css.slide}>{props.renderSlide(item)}</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{props.items.length > 1 && (
|
||||
<div class={css.dots}>
|
||||
{props.items.map((_, i) => {
|
||||
const classes = classNames(css.dotItem, {
|
||||
[css.dotActive]: state.currentSlide === i
|
||||
});
|
||||
return <div class={classes} onClick={() => this.slideTo(i)} />;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
46
src/spectrum/components/carousel/style.css
Normal file
46
src/spectrum/components/carousel/style.css
Normal file
@ -0,0 +1,46 @@
|
||||
.dark .dotItem {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
.dark .dotActive {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.light .dotItem {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.light .dotActive {
|
||||
background: rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.carousel {
|
||||
transition: transform 250ms ease-out;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.slide {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.dotItem {
|
||||
border-radius: 5px;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
margin: 0 5px;
|
||||
transition: background 250ms ease-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dotActive {
|
||||
}
|
||||
10
src/spectrum/components/carousel/style.css.d.ts
vendored
Normal file
10
src/spectrum/components/carousel/style.css.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const carousel: string;
|
||||
export const dark: string;
|
||||
export const dotActive: string;
|
||||
export const dotItem: string;
|
||||
export const dots: string;
|
||||
export const light: string;
|
||||
export const slide: string;
|
||||
export const wrapper: string;
|
||||
@ -1,12 +1,13 @@
|
||||
import { h, Component } from "preact";
|
||||
import classNames from "classnames";
|
||||
import CustomLinks from "../components/customLinks";
|
||||
import Score from "./score";
|
||||
import Plot from "./plot";
|
||||
import "./styles.scss";
|
||||
import * as css from "./style.css";
|
||||
import API, { WidgetLinksLink } from "../api";
|
||||
import Rank from "../components/rank";
|
||||
import Trend from "../components/trend";
|
||||
import Carousel from "./components/carousel";
|
||||
|
||||
type BootstrapAssetType = {
|
||||
export type BootstrapAssetType = {
|
||||
value: number;
|
||||
percent_change: number;
|
||||
asset_name: string;
|
||||
@ -17,7 +18,7 @@ type BootstrapHighlightType = {
|
||||
value: number;
|
||||
};
|
||||
|
||||
type AssetType = {
|
||||
export type AssetType = {
|
||||
symbol: string;
|
||||
highlights?: string[];
|
||||
bootstrapAsset?: BootstrapAssetType;
|
||||
@ -49,12 +50,20 @@ export type Props = {
|
||||
};
|
||||
|
||||
type State = {
|
||||
metric: any;
|
||||
loading: boolean;
|
||||
metric: {
|
||||
name: string;
|
||||
fcas: number;
|
||||
change: number;
|
||||
};
|
||||
};
|
||||
|
||||
class SpectrumPlot extends Component<Props, State> {
|
||||
interval: NodeJS.Timeout;
|
||||
class Spectrum extends Component<Props, State> {
|
||||
interval: number;
|
||||
|
||||
static defaultProps = {
|
||||
mode: "light"
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -96,7 +105,7 @@ class SpectrumPlot extends Component<Props, State> {
|
||||
}
|
||||
|
||||
_update() {
|
||||
this.interval = setInterval(async () => {
|
||||
this.interval = window.setInterval(async () => {
|
||||
await this._getData();
|
||||
}, 300000);
|
||||
}
|
||||
@ -111,86 +120,44 @@ class SpectrumPlot extends Component<Props, State> {
|
||||
this.setState({
|
||||
loading: false,
|
||||
metric: {
|
||||
fcas: "NA",
|
||||
change: "NA",
|
||||
name: "NA"
|
||||
name: "NA",
|
||||
fcas: 0,
|
||||
change: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
this._update();
|
||||
}
|
||||
|
||||
render(props: Props, { metric, loading }: State) {
|
||||
if (loading) return null;
|
||||
return (
|
||||
<div>
|
||||
<Score symbol={props.asset.symbol} metric={metric} {...props} mini />
|
||||
{props.spectrum.enabled && <Plot metric={metric} {...props} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
render(props: Props, state: State) {
|
||||
if (state.loading) return null;
|
||||
|
||||
type CarouselState = {
|
||||
currentSlide: number;
|
||||
};
|
||||
|
||||
export default class Carousel extends Component<Props, CarouselState> {
|
||||
state = {
|
||||
currentSlide: 0
|
||||
};
|
||||
|
||||
static defaultProps: Props = {
|
||||
asset: {
|
||||
symbol: "btc",
|
||||
highlights: ["eth", "zec", "zrx"],
|
||||
bootstrapAsset: null,
|
||||
bootstrapHighlights: null
|
||||
},
|
||||
disableLinks: false,
|
||||
assets: [],
|
||||
mode: "light",
|
||||
fontFamily: "inherit",
|
||||
relatedMarkers: {
|
||||
enabled: true,
|
||||
bucketDistance: 35,
|
||||
lineDistance: 25,
|
||||
fontFamily: "inherit"
|
||||
},
|
||||
name: { enabled: true },
|
||||
spectrum: { enabled: true },
|
||||
icon: { enabled: true },
|
||||
rank: { enabled: true },
|
||||
trend: { enabled: true },
|
||||
linkBootstrap: null
|
||||
};
|
||||
|
||||
slideTo = (slide: number) => {
|
||||
this.setState({ currentSlide: slide });
|
||||
};
|
||||
|
||||
render(props: Props, state: CarouselState) {
|
||||
let assets = [props.asset];
|
||||
if (props.assets.length > 0) {
|
||||
assets = props.assets;
|
||||
}
|
||||
const carouselOffset = state.currentSlide * 100;
|
||||
const carouselStyle = {
|
||||
transform: `translateX(-${carouselOffset}%)`
|
||||
};
|
||||
const { asset, mode } = props;
|
||||
const { metric } = state;
|
||||
|
||||
return (
|
||||
<div class={`fs-spectrum fs-spectrum-${props.mode}`}>
|
||||
<div class="fs-spectrum-viewport">
|
||||
<div class="fs-spectrum-carousel" style={carouselStyle}>
|
||||
{assets.map(asset => (
|
||||
<div class="fs-spectrum-carousel-item">
|
||||
<SpectrumPlot {...props} asset={asset} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div class={css[mode]}>
|
||||
<div class={css.header}>
|
||||
<img
|
||||
class={css.icon}
|
||||
src={`https://d301yvow08hyfu.cloudfront.net/svg/color/${asset.symbol.toLowerCase()}.svg`}
|
||||
/>
|
||||
<span class={css.name}>{metric.name}</span>
|
||||
</div>
|
||||
|
||||
<div class={css.meta}>
|
||||
<span class={css.symbol}>{asset.symbol}</span>
|
||||
<span class={css.fcas}>FCAS {metric.fcas}</span>
|
||||
<span class={css.trend}>
|
||||
<Trend change={metric.change} value={metric.fcas} />
|
||||
</span>
|
||||
<span class={css.rank}>
|
||||
<Rank score={metric.fcas} kind="normal" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{props.spectrum.enabled && <Plot metric={metric} {...props} />}
|
||||
|
||||
{props.disableLinks === false && (
|
||||
<CustomLinks
|
||||
widget="spectrum"
|
||||
@ -198,18 +165,49 @@ export default class Carousel extends Component<Props, CarouselState> {
|
||||
linkBootstrap={props.linkBootstrap}
|
||||
/>
|
||||
)}
|
||||
|
||||
{assets.length > 1 && (
|
||||
<div class="fs-spectrum-dots">
|
||||
{assets.map((_, i) => {
|
||||
const classes = classNames("fs-spectrum-dot", {
|
||||
"fs-spectrum-dot-active": state.currentSlide === i
|
||||
});
|
||||
return <div class={classes} onClick={() => this.slideTo(i)} />;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const MultiSpectrum = (props: Props) => {
|
||||
let assets = [props.asset];
|
||||
if (props.assets.length > 0) {
|
||||
assets = props.assets;
|
||||
}
|
||||
|
||||
return (
|
||||
<Carousel
|
||||
mode={props.mode}
|
||||
items={assets}
|
||||
renderSlide={(item: any) => <Spectrum {...props} asset={item} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
MultiSpectrum.defaultProps = {
|
||||
asset: {
|
||||
symbol: "btc",
|
||||
highlights: ["eth", "zec", "zrx"],
|
||||
bootstrapAsset: null,
|
||||
bootstrapHighlights: null
|
||||
},
|
||||
disableLinks: false,
|
||||
assets: [],
|
||||
mode: "light",
|
||||
fontFamily: "inherit",
|
||||
relatedMarkers: {
|
||||
enabled: true,
|
||||
bucketDistance: 35,
|
||||
lineDistance: 25,
|
||||
fontFamily: "inherit"
|
||||
},
|
||||
name: { enabled: true },
|
||||
spectrum: { enabled: true },
|
||||
icon: { enabled: true },
|
||||
rank: { enabled: true },
|
||||
trend: { enabled: true },
|
||||
linkBootstrap: null
|
||||
} as Props;
|
||||
|
||||
export default MultiSpectrum;
|
||||
@ -1,13 +1,20 @@
|
||||
import { h, Component } from "preact";
|
||||
import { sortObjectArray } from "../../utils";
|
||||
import "./styles.scss";
|
||||
import * as css from "./style.css";
|
||||
|
||||
const PLOT_WIDTH = 240;
|
||||
const PLOT_SCALE = PLOT_WIDTH / 1000;
|
||||
const DEFAULT_BUCKET_DISTANCE = 35;
|
||||
const DEFAULT_LINE_DISTANCE = 25;
|
||||
|
||||
export default class Plot extends Component {
|
||||
// TODO: Port this component to TS
|
||||
// type Props = {
|
||||
// mode: "light" | "dark"
|
||||
// }
|
||||
|
||||
export default class Plot extends Component<any, any> {
|
||||
interval: any;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
@ -48,13 +55,13 @@ export default class Plot extends Component {
|
||||
}
|
||||
|
||||
async _getHighlights() {
|
||||
const highlights = this.getHighlights();
|
||||
const highlights: any[] = this.getHighlights();
|
||||
let nextHighlightState = [];
|
||||
let nextHighlightedSymbolState = [];
|
||||
if (this.props.asset && this.props.asset.bootstrapHighlights) {
|
||||
nextHighlightState = this.props.asset.bootstrapHighlights;
|
||||
nextHighlightedSymbolState = this.props.asset.bootstrapHighlights.map(
|
||||
highlight => highlight.symbol
|
||||
(highlight: any) => highlight.symbol
|
||||
);
|
||||
} else {
|
||||
await Promise.all(
|
||||
@ -118,7 +125,7 @@ export default class Plot extends Component {
|
||||
return highlights;
|
||||
}
|
||||
|
||||
getBuckets() {
|
||||
getBuckets(): any {
|
||||
if (this.state.highlights.length == 0) {
|
||||
return [];
|
||||
}
|
||||
@ -128,10 +135,10 @@ export default class Plot extends Component {
|
||||
bucketDistance = DEFAULT_BUCKET_DISTANCE;
|
||||
}
|
||||
|
||||
let buckets = [];
|
||||
let buckets: any[] = [];
|
||||
let currentBucketIndex = 0;
|
||||
let anchorX = 0;
|
||||
let scoresToBuckets = {};
|
||||
let scoresToBuckets: any = {};
|
||||
let highlightLength = this.state.highlights.length;
|
||||
let sortedHighLights = sortObjectArray(this.state.highlights, "value");
|
||||
|
||||
@ -164,7 +171,7 @@ export default class Plot extends Component {
|
||||
return { buckets, scoresToBuckets };
|
||||
}
|
||||
|
||||
getYCoords(asset, buckets, scoresToBuckets) {
|
||||
getYCoords(asset: any, buckets: any, scoresToBuckets: any) {
|
||||
let { lineDistance } = this.props.relatedMarkers;
|
||||
if (!lineDistance) {
|
||||
lineDistance = DEFAULT_LINE_DISTANCE;
|
||||
@ -192,7 +199,7 @@ export default class Plot extends Component {
|
||||
return { y: 44 - 10 * index, toClose };
|
||||
}
|
||||
|
||||
render(props, { loading, distribution }) {
|
||||
render(props: any, { loading, distribution }: any) {
|
||||
if (loading) return null;
|
||||
|
||||
const highlightedSymbols = this.state.highlightedSymbols;
|
||||
@ -202,8 +209,8 @@ export default class Plot extends Component {
|
||||
|
||||
const xPos = `${(props.metric.fcas / 1000) * 100}%`;
|
||||
const highlightedAssets = distribution
|
||||
.filter(i => highlightedSymbols.indexOf(i.symbol) > -1)
|
||||
.filter(i => i.symbol != props.asset.symbol.toUpperCase());
|
||||
.filter((i: any) => highlightedSymbols.indexOf(i.symbol) > -1)
|
||||
.filter((i: any) => i.symbol != props.asset.symbol.toUpperCase());
|
||||
|
||||
const { buckets, scoresToBuckets } = this.getBuckets();
|
||||
|
||||
@ -220,7 +227,8 @@ export default class Plot extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<svg class="fs-plot" width="100%" height="104" overflow="visible">
|
||||
// @ts-ignore
|
||||
<svg width="100%" height="104" overflow="visible" class={css[props.mode]}>
|
||||
<defs>
|
||||
<linearGradient id="gradient">
|
||||
<stop stop-color="#ff2600" offset="0%" />
|
||||
@ -245,7 +253,7 @@ export default class Plot extends Component {
|
||||
: "rgba(0, 0, 0, 0.4)"
|
||||
}
|
||||
>
|
||||
{distribution.map(i => (
|
||||
{distribution.map((i: any) => (
|
||||
<circle cx={`${(i.value / 1000) * 100}%`} cy="58" r="2.5" />
|
||||
))}
|
||||
</g>
|
||||
@ -256,7 +264,7 @@ export default class Plot extends Component {
|
||||
{/* Spectrum Legend */}
|
||||
<text
|
||||
y="85"
|
||||
class="fs-plot-legend"
|
||||
class={css.legend}
|
||||
fill={props.mode === "dark" ? "#fff" : "#000"}
|
||||
>
|
||||
<tspan text-anchor="start" x="0">
|
||||
@ -271,11 +279,11 @@ export default class Plot extends Component {
|
||||
</text>
|
||||
|
||||
{props.relatedMarkers.enabled &&
|
||||
highlightedAssets.map(a => {
|
||||
highlightedAssets.map((a: any) => {
|
||||
const xPos = `${(a.value / 1000) * 100}%`;
|
||||
let { y, toClose } = this.getYCoords(a, buckets, scoresToBuckets);
|
||||
return (
|
||||
<g class="fs-plot-related" style={relatedLabelStyle}>
|
||||
<g class={css.related} style={relatedLabelStyle}>
|
||||
<text x={xPos} y={y} text-anchor="middle" font-size="10">
|
||||
{a.symbol}
|
||||
</text>
|
||||
@ -285,7 +293,7 @@ export default class Plot extends Component {
|
||||
y1={y + 3}
|
||||
x2={xPos}
|
||||
y2="60"
|
||||
class="fs-plot-related-line"
|
||||
class={css.relatedLine}
|
||||
style={relatedLineStyle}
|
||||
/>
|
||||
)}
|
||||
@ -294,18 +302,14 @@ export default class Plot extends Component {
|
||||
})}
|
||||
|
||||
{/* Blue FCAS Marker */}
|
||||
<text
|
||||
class="fs-plot-asset-marker"
|
||||
text-anchor="middle"
|
||||
font-weight="bold"
|
||||
>
|
||||
<text class={css.marker} text-anchor="middle" font-weight="bold">
|
||||
<tspan x={xPos} y={26}>
|
||||
{props.asset.symbol.toUpperCase()}
|
||||
</tspan>
|
||||
</text>
|
||||
|
||||
{/* Blue FCAS Marker Line */}
|
||||
<line x1={xPos} y1={28} x2={xPos} y2={60} class="fs-plot-asset-line" />
|
||||
<line x1={xPos} y1={28} x2={xPos} y2={60} class={css.line} />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
41
src/spectrum/plot/style.css
Normal file
41
src/spectrum/plot/style.css
Normal file
@ -0,0 +1,41 @@
|
||||
.light .marker {
|
||||
fill: #2d57ed;
|
||||
}
|
||||
.light .line {
|
||||
stroke: #2d57ed;
|
||||
}
|
||||
.light .related {
|
||||
fill: #000;
|
||||
}
|
||||
.light .relatedLine {
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
.dark .marker {
|
||||
fill: #20b7fc;
|
||||
}
|
||||
.dark .line {
|
||||
stroke: #20b7fc;
|
||||
}
|
||||
.dark .related {
|
||||
fill: #fff;
|
||||
}
|
||||
.dark .relatedLine {
|
||||
stroke: #fff;
|
||||
}
|
||||
|
||||
.marker {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.line {
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.relatedLine {
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
|
||||
.legend {
|
||||
font-size: 7px;
|
||||
}
|
||||
9
src/spectrum/plot/style.css.d.ts
vendored
Normal file
9
src/spectrum/plot/style.css.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const dark: string;
|
||||
export const legend: string;
|
||||
export const light: string;
|
||||
export const line: string;
|
||||
export const marker: string;
|
||||
export const related: string;
|
||||
export const relatedLine: string;
|
||||
60
src/spectrum/style.css
Normal file
60
src/spectrum/style.css
Normal file
@ -0,0 +1,60 @@
|
||||
.light .meta,
|
||||
.light a {
|
||||
color: #2d57ed;
|
||||
}
|
||||
|
||||
.light .name {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.dark .meta,
|
||||
.dark a {
|
||||
color: #20b7fc;
|
||||
}
|
||||
|
||||
.dark .name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.fcas {
|
||||
margin: 0 6px;
|
||||
}
|
||||
|
||||
.rank {
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.trend {
|
||||
font-size: 10px;
|
||||
margin-left: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
12
src/spectrum/style.css.d.ts
vendored
Normal file
12
src/spectrum/style.css.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const dark: string;
|
||||
export const fcas: string;
|
||||
export const header: string;
|
||||
export const icon: string;
|
||||
export const light: string;
|
||||
export const meta: string;
|
||||
export const name: string;
|
||||
export const rank: string;
|
||||
export const symbol: string;
|
||||
export const trend: string;
|
||||
@ -1,15 +0,0 @@
|
||||
.fs-plot-asset-marker {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.fs-plot-asset-line {
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.fs-plot-related-line {
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
|
||||
.fs-plot-legend {
|
||||
font-size: 7px;
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
import { h, Component } from "preact";
|
||||
|
||||
function round(value) {
|
||||
if (!value) {
|
||||
return value;
|
||||
}
|
||||
return Math.round(value * 100) / 100;
|
||||
}
|
||||
|
||||
export default class Data extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
showTooltip: false
|
||||
};
|
||||
this._showTooltip = this._showTooltip.bind(this);
|
||||
this._hideTooltip = this._hideTooltip.bind(this);
|
||||
}
|
||||
|
||||
_showTooltip() {
|
||||
this.setState({ showTooltip: true });
|
||||
}
|
||||
|
||||
_hideTooltip() {
|
||||
this.setState({ showTooltip: false });
|
||||
}
|
||||
|
||||
render({ opts, metric, rank }, { showTooltip }) {
|
||||
let trendDir, trendIcon;
|
||||
if (metric.change < 0) {
|
||||
trendDir = "down";
|
||||
trendIcon = require("./images/icon-down.svg");
|
||||
} else if (metric.change == 0) {
|
||||
trendDir = "eq";
|
||||
trendIcon = require("./images/icon-eq.svg");
|
||||
} else {
|
||||
trendDir = "up";
|
||||
trendIcon = require("./images/icon-up.svg");
|
||||
}
|
||||
|
||||
const trendDiff = Math.abs(metric.fcas * (metric.change / 100));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class="fs-fcas">
|
||||
<h2 class="fs-fcas__header">FCAS</h2>
|
||||
<span
|
||||
class="fs-link fs-fcas__what"
|
||||
onMouseEnter={this._showTooltip}
|
||||
onMouseLeave={this._hideTooltip}
|
||||
>
|
||||
What's this?
|
||||
{showTooltip && (
|
||||
<div class="fs-tooltip">
|
||||
<div class="fs-tooltip__content">
|
||||
<p>
|
||||
<b>FCAS</b> is Flipside’s Crypto Asset Score, ranging from 0
|
||||
- 1000. The score combines values from the 3 major market
|
||||
factors to create a comparative metric across digital
|
||||
assets.
|
||||
</p>
|
||||
<p>
|
||||
Powered by{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://flipsidecrypto.com"
|
||||
class="fs-link"
|
||||
>
|
||||
flipsidecrypto.com
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="fs-data">
|
||||
<h3 class="fs-value">{metric.fcas}</h3>
|
||||
|
||||
{opts.trend && (
|
||||
<div class="fs-score-trend">
|
||||
<div
|
||||
class={`fs-score-trend__change fs-score-trend__change--${trendDir}`}
|
||||
>
|
||||
<img class="fs-score-trend__icon" src={trendIcon} />{" "}
|
||||
{round(trendDiff)}
|
||||
</div>
|
||||
7d
|
||||
</div>
|
||||
)}
|
||||
|
||||
{opts.rank && (
|
||||
<div class="fs-score-rank">
|
||||
<b class={`fs-score-rank__letter fs-score-rank__letter--${rank}`}>
|
||||
{rank}
|
||||
</b>{" "}
|
||||
Rank
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
import { h } from "preact";
|
||||
|
||||
export default props => {
|
||||
return (
|
||||
<div class="fs-data-mini">
|
||||
FCAS {props.metric.fcas}
|
||||
<div
|
||||
class={`fs-score-rank fs-score-rank__letter fs-score-rank__letter--mini fs-score-rank__letter--${
|
||||
props.rank
|
||||
}`}
|
||||
>
|
||||
{props.rank}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="11px" height="12px" viewBox="0 0 11 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.4 (67378) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icon-down</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M4,7 L0,7 L5.5,0 L11,7 L7,7 L7,12 L4,12 L4,7 Z" id="icon-down" fill="#FF2700" transform="translate(5.500000, 6.000000) rotate(-180.000000) translate(-5.500000, -6.000000) "></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 630 B |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="8px" height="7px" viewBox="0 0 8 7" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.4 (67378) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icon-eq</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M0,4 L8,4 L8,7 L0,7 L0,4 Z M0,0 L8,0 L8,3 L0,3 L0,0 Z" id="icon-eq" fill="#808080"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="11px" height="12px" viewBox="0 0 11 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.4 (67378) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icon-up</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M4,7 L0,7 L5.5,0 L11,7 L7,7 L7,12 L4,12 L4,7 Z" id="icon-up" fill="#057511"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 531 B |
@ -1,57 +0,0 @@
|
||||
import { h, Component } from "preact";
|
||||
import Data from "./Data";
|
||||
import DataMini from "./DataMini";
|
||||
import "./styles.scss";
|
||||
|
||||
function round(value) {
|
||||
if (!value) {
|
||||
return value;
|
||||
}
|
||||
return Math.round(value * 100) / 100;
|
||||
}
|
||||
|
||||
export default class Score extends Component {
|
||||
render(props, { showTooltip }) {
|
||||
let rank;
|
||||
if (props.metric.fcas <= 500) {
|
||||
rank = "f";
|
||||
} else if (props.metric.fcas <= 649) {
|
||||
rank = "c";
|
||||
} else if (props.metric.fcas <= 749) {
|
||||
rank = "b";
|
||||
} else if (props.metric.fcas <= 899) {
|
||||
rank = "a";
|
||||
} else {
|
||||
rank = "s";
|
||||
}
|
||||
|
||||
let wrapperClass = "fs-score";
|
||||
if (props.mode === "dark") wrapperClass += " fs-score--dark";
|
||||
if (props.mini) wrapperClass += " fs-score--mini";
|
||||
|
||||
const DataComponent = props.mini ? DataMini : Data;
|
||||
|
||||
return (
|
||||
<div class={wrapperClass}>
|
||||
<header class="fs-token">
|
||||
{props.icon.enabled && (
|
||||
<img
|
||||
class="fs-token__logo"
|
||||
src={`https://d301yvow08hyfu.cloudfront.net/svg/color/${props.asset.symbol.toLowerCase()}.svg`}
|
||||
/>
|
||||
)}
|
||||
<h1 class="fs-token__name">
|
||||
<span style={props.name.style}>
|
||||
{props.name.enabled && props.metric.name}
|
||||
</span>
|
||||
{props.asset && (
|
||||
<span class="fs-token__sym">{props.asset.symbol}</span>
|
||||
)}
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
{props.rank.enabled && <DataComponent {...props} rank={rank} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,170 +0,0 @@
|
||||
.fs-score {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.fs-score--dark {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fs-score--mini {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.fs-token {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
.fs-token__logo {
|
||||
margin-right: 8px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.fs-token__name {
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.fs-token__sym {
|
||||
font-size: 12px;
|
||||
color: #2d57ed;
|
||||
text-transform: uppercase;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.fs-fcas {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fs-fcas__header {
|
||||
margin: 0 10px 0 0;
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.fs-fcas__what {
|
||||
font-size: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fs-tooltip {
|
||||
padding-left: 15px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.fs-tooltip__content {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
border-radius: 8px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.15);
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
line-height: 14px;
|
||||
padding: 5px 15px;
|
||||
border: 1px solid rgba(200, 200, 200, 0.5);
|
||||
&:before {
|
||||
display: block;
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: calc(50% - 10px);
|
||||
transform: rotate(-45deg);
|
||||
background: #fff;
|
||||
box-shadow: -1px -1px 0 rgba(200, 200, 200, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.fs-data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.fs-data-mini {
|
||||
font-size: 14px;
|
||||
color: #2d57ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fs-value {
|
||||
font-size: 58px;
|
||||
font-weight: bold;
|
||||
margin: 0 14px 0 0;
|
||||
}
|
||||
|
||||
.fs-score-trend {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.fs-score-trend__icon {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.fs-score-trend__change {
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 28px;
|
||||
margin-bottom: 5px;
|
||||
&--up {
|
||||
color: #057511;
|
||||
}
|
||||
&--down {
|
||||
color: #ff2700;
|
||||
}
|
||||
&--eq {
|
||||
color: #808080;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-score-rank {
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.fs-score-rank__letter {
|
||||
width: 32px;
|
||||
height: 28px;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
border-radius: 2px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 5px;
|
||||
text-transform: uppercase;
|
||||
color: #000;
|
||||
}
|
||||
.fs-score-rank__letter--mini {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
width: 50px;
|
||||
margin: 0 0 0 auto;
|
||||
}
|
||||
.fs-score-rank__letter--s {
|
||||
background: #68ba66;
|
||||
}
|
||||
.fs-score-rank__letter--a {
|
||||
background: #8fcb89;
|
||||
}
|
||||
.fs-score-rank__letter--b {
|
||||
background: #b2dbad;
|
||||
}
|
||||
.fs-score-rank__letter--c {
|
||||
background: #ff7a18;
|
||||
}
|
||||
.fs-score-rank__letter--f {
|
||||
background: #ff2600;
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
.fs-spectrum {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
|
||||
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
line-height: 1;
|
||||
border-radius: 25px;
|
||||
|
||||
&-viewport {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
&-carousel {
|
||||
transition: transform 250ms ease-out;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&-carousel-item {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&-dot {
|
||||
border-radius: 5px;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
margin: 0 5px;
|
||||
transition: background 250ms ease-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-spectrum-light {
|
||||
color: #000;
|
||||
a {
|
||||
color: #2d57ed;
|
||||
}
|
||||
.fs-spectrum-dot {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
&-active {
|
||||
background: rgba(0, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
.fs-plot-asset-marker {
|
||||
fill: #2d57ed;
|
||||
}
|
||||
.fs-plot-asset-line {
|
||||
stroke: #2d57ed;
|
||||
}
|
||||
.fs-plot-related {
|
||||
fill: #000;
|
||||
}
|
||||
.fs-plot-related-line {
|
||||
stroke: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-spectrum-dark {
|
||||
color: #fff;
|
||||
a {
|
||||
color: #20b7fc;
|
||||
}
|
||||
.fs-spectrum-dot {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
&-active {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
.fs-plot-asset-marker {
|
||||
fill: #20b7fc;
|
||||
}
|
||||
.fs-plot-asset-line {
|
||||
stroke: #20b7fc;
|
||||
}
|
||||
.fs-plot-related {
|
||||
fill: #fff;
|
||||
}
|
||||
.fs-plot-related-line {
|
||||
stroke: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-link {
|
||||
color: #2d57ed;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -1,9 +1,10 @@
|
||||
import { h, Component } from "preact";
|
||||
import keyBy from "lodash/keyBy";
|
||||
import keyBy = require("lodash/keyBy");
|
||||
import CustomLinks from "./components/customLinks";
|
||||
import "./styles.scss";
|
||||
import API from "../api";
|
||||
|
||||
function getMetricTrend(change) {
|
||||
function getMetricTrend(change: number) {
|
||||
if (change < 0) {
|
||||
return "down";
|
||||
} else if (change == 0) {
|
||||
@ -13,11 +14,23 @@ function getMetricTrend(change) {
|
||||
}
|
||||
}
|
||||
|
||||
function calculateDiff(value, percent) {
|
||||
function calculateDiff(value: number, percent: number) {
|
||||
return Math.round(Math.abs(value * (percent / 100)));
|
||||
}
|
||||
|
||||
export default class Table extends Component {
|
||||
type Props = {
|
||||
api: API;
|
||||
symbol: string;
|
||||
dark: boolean;
|
||||
borderColor?: string;
|
||||
};
|
||||
|
||||
type State = {
|
||||
loading: boolean;
|
||||
metrics: any;
|
||||
};
|
||||
|
||||
export default class Table extends Component<Props, State> {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { loading: true, metrics: null };
|
||||
@ -50,7 +63,7 @@ export default class Table extends Component {
|
||||
window.location.assign(learnMoreUrl);
|
||||
}
|
||||
|
||||
render({ dark }, { loading, metrics }) {
|
||||
render({ dark }: Props, { loading, metrics }: State) {
|
||||
if (loading) {
|
||||
return null;
|
||||
}
|
||||
@ -94,7 +107,7 @@ export default class Table extends Component {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th style={tdStyle} colspan="2">
|
||||
<th style={tdStyle} colSpan={2}>
|
||||
User Activity
|
||||
</th>
|
||||
<td style={tdStyle}>{utility.value}</td>
|
||||
@ -107,7 +120,7 @@ export default class Table extends Component {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th style={tdStyle} colspan="2">
|
||||
<th style={tdStyle} colSpan={2}>
|
||||
Developer Behavior
|
||||
</th>
|
||||
<td style={tdStyle}>{dev.value}</td>
|
||||
@ -4,9 +4,10 @@
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": true,
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"target": "es5",
|
||||
"lib": ["es2015", "dom"],
|
||||
"jsx": "react",
|
||||
"jsxFactory": "h",
|
||||
"allowJs": true
|
||||
"allowJs": true,
|
||||
"jsxFactory": "h"
|
||||
}
|
||||
}
|
||||
|
||||
15
yarn.lock
15
yarn.lock
@ -102,6 +102,13 @@
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-syntax-jsx" "^7.0.0"
|
||||
|
||||
"@babel/polyfill@^7.2.5":
|
||||
version "7.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.5.tgz#6c54b964f71ad27edddc567d065e57e87ed7fa7d"
|
||||
dependencies:
|
||||
core-js "^2.5.7"
|
||||
regenerator-runtime "^0.12.0"
|
||||
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.1.2":
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644"
|
||||
@ -976,6 +983,10 @@ copy-descriptor@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
|
||||
core-js@^2.5.7, core-js@^2.6.5:
|
||||
version "2.6.5"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@ -3339,6 +3350,10 @@ regenerate@^1.2.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||
|
||||
regenerator-runtime@^0.12.0:
|
||||
version "0.12.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
|
||||
|
||||
regex-not@^1.0.0, regex-not@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user