diff --git a/package.json b/package.json index 0e4612d..d148a71 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/api.ts b/src/api.ts index a75c4f0..26cce15 100644 --- a/src/api.ts +++ b/src/api.ts @@ -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 = { diff --git a/src/components/customLinks/index.tsx b/src/components/customLinks/index.tsx index ecac09c..cc4ec34 100644 --- a/src/components/customLinks/index.tsx +++ b/src/components/customLinks/index.tsx @@ -44,8 +44,15 @@ class CustomLinks extends Component { 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 (
+ {topLink && ( + + )} {leftLink && ( { 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 ( diff --git a/src/components/rank/style.css b/src/components/rank/style.css index 554eac2..5561f49 100644 --- a/src/components/rank/style.css +++ b/src/components/rank/style.css @@ -39,6 +39,12 @@ width: 32px; } +.normal { + background-size: auto 70%; + width: 54px; + height: 22px; +} + .large { background-size: auto 48%; height: 28px; diff --git a/src/components/rank/style.css.d.ts b/src/components/rank/style.css.d.ts index 8c369fb..f4e9075 100644 --- a/src/components/rank/style.css.d.ts +++ b/src/components/rank/style.css.d.ts @@ -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; diff --git a/src/components/trend/index.tsx b/src/components/trend/index.tsx index 1a9239b..c0736dd 100644 --- a/src/components/trend/index.tsx +++ b/src/components/trend/index.tsx @@ -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 ( diff --git a/src/components/trend/style.css b/src/components/trend/style.css index 389ed7d..095049e 100644 --- a/src/components/trend/style.css +++ b/src/components/trend/style.css @@ -1,7 +1,11 @@ +.wrapper { + display: flex; + align-items: center; +} + .icon { height: 6px; margin-right: 2px; - vertical-align: middle; } .up { diff --git a/src/components/trend/style.css.d.ts b/src/components/trend/style.css.d.ts index ce7aebe..d684ecc 100644 --- a/src/components/trend/style.css.d.ts +++ b/src/components/trend/style.css.d.ts @@ -3,3 +3,4 @@ export const down: string; export const icon: string; export const up: string; +export const wrapper: string; diff --git a/src/index.tsx b/src/index.tsx index 3735db3..cb1e1b4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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(, 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(, element); + const props = defaultsWithoutArrays(Spectrum.defaultProps, opts); + render(, element); } score(el: string, opts: ScoreProps) { diff --git a/src/score/style.css b/src/score/style.css index 89fe224..1e8d069 100644 --- a/src/score/style.css +++ b/src/score/style.css @@ -34,6 +34,8 @@ .change { font-size: 15px; font-weight: 600; + display: flex; + justify-content: flex-end; } .trend { diff --git a/src/spectrum/components/carousel/index.tsx b/src/spectrum/components/carousel/index.tsx new file mode 100644 index 0000000..caf4016 --- /dev/null +++ b/src/spectrum/components/carousel/index.tsx @@ -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 { + 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 ( +
+
+ {props.items.map(item => ( +
{props.renderSlide(item)}
+ ))} +
+ + {props.items.length > 1 && ( +
+ {props.items.map((_, i) => { + const classes = classNames(css.dotItem, { + [css.dotActive]: state.currentSlide === i + }); + return
this.slideTo(i)} />; + })} +
+ )} +
+ ); + } +} diff --git a/src/spectrum/components/carousel/style.css b/src/spectrum/components/carousel/style.css new file mode 100644 index 0000000..e0aad1b --- /dev/null +++ b/src/spectrum/components/carousel/style.css @@ -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 { +} diff --git a/src/spectrum/components/carousel/style.css.d.ts b/src/spectrum/components/carousel/style.css.d.ts new file mode 100644 index 0000000..8be48ae --- /dev/null +++ b/src/spectrum/components/carousel/style.css.d.ts @@ -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; diff --git a/src/spectrumPlot/index.tsx b/src/spectrum/index.tsx similarity index 51% rename from src/spectrumPlot/index.tsx rename to src/spectrum/index.tsx index b1d25a4..19ddfaf 100644 --- a/src/spectrumPlot/index.tsx +++ b/src/spectrum/index.tsx @@ -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 { - interval: NodeJS.Timeout; +class Spectrum extends Component { + interval: number; + + static defaultProps = { + mode: "light" + }; constructor() { super(); @@ -96,7 +105,7 @@ class SpectrumPlot extends Component { } _update() { - this.interval = setInterval(async () => { + this.interval = window.setInterval(async () => { await this._getData(); }, 300000); } @@ -111,86 +120,44 @@ class SpectrumPlot extends Component { 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 ( -
- - {props.spectrum.enabled && } -
- ); - } -} + render(props: Props, state: State) { + if (state.loading) return null; -type CarouselState = { - currentSlide: number; -}; - -export default class Carousel extends Component { - 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 ( -
-
- +
+
+ + {metric.name}
+
+ {asset.symbol} + FCAS {metric.fcas} + + + + + + +
+ + {props.spectrum.enabled && } + {props.disableLinks === false && ( { linkBootstrap={props.linkBootstrap} /> )} - - {assets.length > 1 && ( -
- {assets.map((_, i) => { - const classes = classNames("fs-spectrum-dot", { - "fs-spectrum-dot-active": state.currentSlide === i - }); - return
this.slideTo(i)} />; - })} -
- )}
); } } + +const MultiSpectrum = (props: Props) => { + let assets = [props.asset]; + if (props.assets.length > 0) { + assets = props.assets; + } + + return ( + } + /> + ); +}; + +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; diff --git a/src/spectrumPlot/plot/index.js b/src/spectrum/plot/index.tsx similarity index 87% rename from src/spectrumPlot/plot/index.js rename to src/spectrum/plot/index.tsx index 2be20af..949521c 100644 --- a/src/spectrumPlot/plot/index.js +++ b/src/spectrum/plot/index.tsx @@ -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 { + 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 ( - + // @ts-ignore + @@ -245,7 +253,7 @@ export default class Plot extends Component { : "rgba(0, 0, 0, 0.4)" } > - {distribution.map(i => ( + {distribution.map((i: any) => ( ))} @@ -256,7 +264,7 @@ export default class Plot extends Component { {/* Spectrum Legend */} @@ -271,11 +279,11 @@ export default class Plot extends Component { {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 ( - + {a.symbol} @@ -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 */} - + {props.asset.symbol.toUpperCase()} {/* Blue FCAS Marker Line */} - + ); } diff --git a/src/spectrum/plot/style.css b/src/spectrum/plot/style.css new file mode 100644 index 0000000..8ef9ee4 --- /dev/null +++ b/src/spectrum/plot/style.css @@ -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; +} diff --git a/src/spectrum/plot/style.css.d.ts b/src/spectrum/plot/style.css.d.ts new file mode 100644 index 0000000..a928501 --- /dev/null +++ b/src/spectrum/plot/style.css.d.ts @@ -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; diff --git a/src/spectrum/style.css b/src/spectrum/style.css new file mode 100644 index 0000000..cf1e089 --- /dev/null +++ b/src/spectrum/style.css @@ -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; +} diff --git a/src/spectrum/style.css.d.ts b/src/spectrum/style.css.d.ts new file mode 100644 index 0000000..daee530 --- /dev/null +++ b/src/spectrum/style.css.d.ts @@ -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; diff --git a/src/spectrumPlot/plot/styles.scss b/src/spectrumPlot/plot/styles.scss deleted file mode 100644 index fba56a5..0000000 --- a/src/spectrumPlot/plot/styles.scss +++ /dev/null @@ -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; -} diff --git a/src/spectrumPlot/score/Data.js b/src/spectrumPlot/score/Data.js deleted file mode 100644 index d47f0ac..0000000 --- a/src/spectrumPlot/score/Data.js +++ /dev/null @@ -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 ( -
-
-

FCAS

- - What's this? - {showTooltip && ( -
-
-

- FCAS 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. -

-

- Powered by{" "} - - flipsidecrypto.com - -

-
-
- )} -
-
- -
-

{metric.fcas}

- - {opts.trend && ( -
-
- {" "} - {round(trendDiff)} -
- 7d -
- )} - - {opts.rank && ( -
- - {rank} - {" "} - Rank -
- )} -
-
- ); - } -} diff --git a/src/spectrumPlot/score/DataMini.js b/src/spectrumPlot/score/DataMini.js deleted file mode 100644 index 99ed146..0000000 --- a/src/spectrumPlot/score/DataMini.js +++ /dev/null @@ -1,16 +0,0 @@ -import { h } from "preact"; - -export default props => { - return ( -
- FCAS {props.metric.fcas} -
- {props.rank} -
-
- ); -}; diff --git a/src/spectrumPlot/score/images/icon-down.svg b/src/spectrumPlot/score/images/icon-down.svg deleted file mode 100644 index e7d1124..0000000 --- a/src/spectrumPlot/score/images/icon-down.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - icon-down - Created with Sketch. - - - - \ No newline at end of file diff --git a/src/spectrumPlot/score/images/icon-eq.svg b/src/spectrumPlot/score/images/icon-eq.svg deleted file mode 100644 index 563cc68..0000000 --- a/src/spectrumPlot/score/images/icon-eq.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - icon-eq - Created with Sketch. - - - - \ No newline at end of file diff --git a/src/spectrumPlot/score/images/icon-up.svg b/src/spectrumPlot/score/images/icon-up.svg deleted file mode 100644 index ba4e096..0000000 --- a/src/spectrumPlot/score/images/icon-up.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - icon-up - Created with Sketch. - - - - \ No newline at end of file diff --git a/src/spectrumPlot/score/index.js b/src/spectrumPlot/score/index.js deleted file mode 100644 index 5c54153..0000000 --- a/src/spectrumPlot/score/index.js +++ /dev/null @@ -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 ( -
-
- {props.icon.enabled && ( - - )} -

- - {props.name.enabled && props.metric.name} - - {props.asset && ( - {props.asset.symbol} - )} -

-
- - {props.rank.enabled && } -
- ); - } -} diff --git a/src/spectrumPlot/score/styles.scss b/src/spectrumPlot/score/styles.scss deleted file mode 100644 index e972365..0000000 --- a/src/spectrumPlot/score/styles.scss +++ /dev/null @@ -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; -} diff --git a/src/spectrumPlot/styles.scss b/src/spectrumPlot/styles.scss deleted file mode 100644 index fc1b053..0000000 --- a/src/spectrumPlot/styles.scss +++ /dev/null @@ -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; -} diff --git a/src/table/index.js b/src/table/index.tsx similarity index 85% rename from src/table/index.js rename to src/table/index.tsx index d69656c..2183d69 100644 --- a/src/table/index.js +++ b/src/table/index.tsx @@ -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 { 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 { - + User Activity {utility.value} @@ -107,7 +120,7 @@ export default class Table extends Component { - + Developer Behavior {dev.value} diff --git a/tsconfig.json b/tsconfig.json index cffde3b..371202c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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" } } diff --git a/yarn.lock b/yarn.lock index 673fd4b..c3f85c3 100644 --- a/yarn.lock +++ b/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"