Skip to content

Commit

Permalink
loading spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
Vaz-Tiago committed May 16, 2022
1 parent 4e4e845 commit 099b248
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 8 deletions.
13 changes: 13 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export namespace Components {
"opened": boolean;
"titleMenu": string;
}
interface VazSpinner {
}
interface VazStockFinder {
}
interface VazStockPrice {
Expand All @@ -29,6 +31,12 @@ declare global {
prototype: HTMLVazSideDrawerElement;
new (): HTMLVazSideDrawerElement;
};
interface HTMLVazSpinnerElement extends Components.VazSpinner, HTMLStencilElement {
}
var HTMLVazSpinnerElement: {
prototype: HTMLVazSpinnerElement;
new (): HTMLVazSpinnerElement;
};
interface HTMLVazStockFinderElement extends Components.VazStockFinder, HTMLStencilElement {
}
var HTMLVazStockFinderElement: {
Expand All @@ -49,6 +57,7 @@ declare global {
};
interface HTMLElementTagNameMap {
"vaz-side-drawer": HTMLVazSideDrawerElement;
"vaz-spinner": HTMLVazSpinnerElement;
"vaz-stock-finder": HTMLVazStockFinderElement;
"vaz-stock-price": HTMLVazStockPriceElement;
"vaz-tooltip": HTMLVazTooltipElement;
Expand All @@ -59,6 +68,8 @@ declare namespace LocalJSX {
"opened"?: boolean;
"titleMenu"?: string;
}
interface VazSpinner {
}
interface VazStockFinder {
"onVazSymbolSelect"?: (event: CustomEvent<string>) => void;
}
Expand All @@ -71,6 +82,7 @@ declare namespace LocalJSX {
}
interface IntrinsicElements {
"vaz-side-drawer": VazSideDrawer;
"vaz-spinner": VazSpinner;
"vaz-stock-finder": VazStockFinder;
"vaz-stock-price": VazStockPrice;
"vaz-tooltip": VazTooltip;
Expand All @@ -81,6 +93,7 @@ declare module "@stencil/core" {
export namespace JSX {
interface IntrinsicElements {
"vaz-side-drawer": LocalJSX.VazSideDrawer & JSXBase.HTMLAttributes<HTMLVazSideDrawerElement>;
"vaz-spinner": LocalJSX.VazSpinner & JSXBase.HTMLAttributes<HTMLVazSpinnerElement>;
"vaz-stock-finder": LocalJSX.VazStockFinder & JSXBase.HTMLAttributes<HTMLVazStockFinderElement>;
"vaz-stock-price": LocalJSX.VazStockPrice & JSXBase.HTMLAttributes<HTMLVazStockPriceElement>;
"vaz-tooltip": LocalJSX.VazTooltip & JSXBase.HTMLAttributes<HTMLVazTooltipElement>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/side-drawer/side-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class SideDrawer {
}

@Method()
open() {
async open() {
this.opened = true;
}

Expand Down
46 changes: 46 additions & 0 deletions src/components/spinner/spinner.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.lds-ripple {
display: inline-block;
position: relative;
width: 40px;
height: 40px;
}
.lds-ripple div {
position: absolute;
border: 4px solid #fff;
opacity: 1;
border-radius: 50%;
animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
.lds-ripple div:nth-child(2) {
animation-delay: -0.5s;
}
@keyframes lds-ripple {
0% {
top: 18px;
left: 18px;
width: 0;
height: 0;
opacity: 0;
}
4.9% {
top: 18px;
left: 18px;
width: 0;
height: 0;
opacity: 0;
}
5% {
top: 18px;
left: 18px;
width: 0;
height: 0;
opacity: 1;
}
100% {
top: 0px;
left: 0px;
width: 36px;
height: 36px;
opacity: 0;
}
}
17 changes: 17 additions & 0 deletions src/components/spinner/spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Component, h } from '@stencil/core';

@Component({
tag: 'vaz-spinner',
styleUrl: './spinner.css',
shadow: true,
})
export class Spinner {
render() {
return (
<div class="lds-ripple">
<div></div>
<div></div>
</div>
);
}
}
20 changes: 14 additions & 6 deletions src/components/stock-finder/stock-finder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ export class StockFinder {
stockNameInput: HTMLInputElement;

@State() searchResults: { symbol: string; name: string }[] = [];
@State() loading = false;

@Event({ bubbles: true, composed: true }) vazSymbolSelect: EventEmitter<string>;

async onFindStock(event: Event) {
event.preventDefault();
this.loading = true;
const stockName = this.stockNameInput?.value;
try {
const apiResponse = await fetch(`https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=${stockName}&apikey=${process.env.AV_TOKEN}`);
Expand All @@ -24,6 +26,8 @@ export class StockFinder {
}));
} catch (err) {
console.error('API ERROR: ', err);
} finally {
this.loading = false;
}
}

Expand All @@ -32,18 +36,22 @@ export class StockFinder {
}

render() {
return [
<form onSubmit={this.onFindStock.bind(this)}>
<input id="stock-symbol" ref={el => (this.stockNameInput = el)} />
<button type="submit">Find!</button>
</form>,
let content = (
<ul>
{this.searchResults.map((item, index) => (
<li key={`search-${index}`} onClick={this.onSelectSymbol.bind(this, item.symbol)}>
<strong>{item.symbol}</strong> - {item.name}
</li>
))}
</ul>,
</ul>
);
if (this.loading) content = <vaz-spinner />;
return [
<form onSubmit={this.onFindStock.bind(this)}>
<input id="stock-symbol" ref={el => (this.stockNameInput = el)} />
<button type="submit">Find!</button>
</form>,
<div>{content}</div>,
];
}
}
5 changes: 4 additions & 1 deletion src/components/stock-price/stock-price.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export class StockPrice {
try {
const apiResponse = await fetch(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${stockSymbol}&apikey=${process.env.AV_TOKEN}`);
const parsedRes = await apiResponse.json();
if (parsedRes?.Note) throw new Error('API limit, wait a minute to call again!');
if (!parsedRes['Global Quote']['05. price']) throw new Error('Invalid stock symbol');

this.fetchedPrice = +parsedRes['Global Quote']['05. price'];
this.error = null;
} catch (err) {
Expand All @@ -76,14 +78,15 @@ export class StockPrice {
let dataContent = <p>Pleas enter a symbol</p>;
if (this.error) dataContent = <p>{this.error}</p>;
if (this.fetchedPrice) dataContent = <p>Price: ${this.fetchedPrice}</p>;
if (this.loading) dataContent = <vaz-spinner></vaz-spinner>;
return [
<form onSubmit={this.onFetchStockPrice.bind(this)}>
<input id="stock-symbol" ref={el => (this.stockInput = el)} value={this.stockUserInput} onInput={this.onStockUserInput.bind(this)} />
<button type="submit" disabled={!this.stockInputValid || this.loading}>
Fetch
</button>
</form>,
<div>{this.loading ? <p>Fetching Data...</p> : dataContent}</div>,
<div>{dataContent}</div>,
];
}
}

0 comments on commit 099b248

Please sign in to comment.