embeddable-nfts
Advanced tools
Comparing version
{ | ||
"name": "embeddable-nfts", | ||
"version": "0.3.0", | ||
"version": "0.4.1", | ||
"description": "Resuable, embeddable webcomponent for OpenSea assets.", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -17,3 +17,3 @@ import { LitElement, html, customElement, property, css } from 'lit-element' | ||
const RANK_HEIGHT = 40 | ||
const RANK_MARGIN = 8 | ||
const RANK_MARGIN = 10 | ||
const rankStyle = { | ||
@@ -36,4 +36,2 @@ height: RANK_HEIGHT + 'px', | ||
height: BOOST_HEIGHT + 'px', | ||
marginBottom: BOOST_MARGIN + 'px', | ||
paddingBottom: BOOST_MARGIN + 'px' | ||
} | ||
@@ -84,2 +82,4 @@ | ||
box-sizing: border-box; | ||
font-size: 15px; | ||
font-weight: 400; | ||
} | ||
@@ -93,3 +93,2 @@ .card-back p { | ||
column-gap: 10px; | ||
height: 100%; | ||
@@ -110,3 +109,2 @@ } | ||
display: flex; | ||
font-size: 14px; | ||
color: rgba(0, 0, 0, 0.87); | ||
@@ -118,3 +116,3 @@ font-weight: 700; | ||
line-height: 20px; | ||
margin-bottom: 8px; | ||
margin-bottom: 10px; | ||
} | ||
@@ -133,3 +131,2 @@ .trait-header p { | ||
box-sizing: border-box; | ||
cursor: pointer; | ||
text-align: center; | ||
@@ -144,3 +141,2 @@ border: 1px solid #2d9cdb; | ||
font-weight: 400; | ||
font-size: 15px; | ||
color: rgba(0, 0, 0, 0.87); | ||
@@ -162,3 +158,2 @@ } | ||
color: rgba(0,0,0,.87); | ||
font-size: 15px; | ||
} | ||
@@ -182,2 +177,3 @@ .trait_ranking { | ||
font-size: 11px; | ||
text-transform: none; | ||
} | ||
@@ -203,3 +199,5 @@ .trait_ranking .trait_ranking-bar { | ||
} | ||
.trait-header-stats { | ||
margin-bottom: 0; | ||
} | ||
.stat { | ||
@@ -210,7 +208,5 @@ display: grid; | ||
align-items: center; | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.2); | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | ||
} | ||
.stat-name { | ||
font-size: 20px; | ||
font-weight: 100; | ||
text-transform: capitalize; | ||
@@ -221,4 +217,4 @@ margin-left: 5px; | ||
color: #2d9cdb; | ||
font-size: 28px; | ||
font-weight: 100; | ||
font-size: 25px; | ||
font-weight: 300; | ||
margin-left: 5px; | ||
@@ -230,4 +226,2 @@ } | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | ||
margin-bottom: 8px; | ||
padding-bottom: 8px; | ||
} | ||
@@ -237,3 +231,3 @@ .trait_boost .trait_boost-value { | ||
height: 30px; | ||
background-color: #2d9cdb; | ||
background-color: transparent; | ||
border-radius: 50%; | ||
@@ -246,5 +240,11 @@ display: flex; | ||
.trait_boost .trait_boost-value p { | ||
font-size: 12px; | ||
color: #ffffff; | ||
font-size: 16px; | ||
color: #2d9cdb; | ||
} | ||
.remaining-traits { | ||
text-transform: none; | ||
font-weight: bold; | ||
margin-top: 10px; | ||
display: block; | ||
} | ||
` | ||
@@ -316,3 +316,3 @@ } | ||
return html` | ||
<div class="trait-header"> | ||
<div class="trait-header trait-header-stats"> | ||
<div class="trait-icon"> | ||
@@ -336,3 +336,3 @@ <svg | ||
({trait_type, value}) => html` | ||
<div class="trait_boost" style="${styleMap(boostStyle)}" > | ||
<div class="trait_boost" style=${styleMap(boostStyle)} > | ||
<div class="trait_boost-value"> | ||
@@ -358,3 +358,3 @@ <p>+${value}</p> | ||
return html` | ||
<div class="trait-header"> | ||
<div class="trait-header trait-header-stats"> | ||
<div class="trait-icon"> | ||
@@ -378,3 +378,3 @@ <svg | ||
html` | ||
<div class="stat" style="${styleMap(statStyle)}"> | ||
<div class="stat" style=${styleMap(statStyle)}> | ||
<div class="stat-value">${stat.value}</div> | ||
@@ -416,3 +416,3 @@ <div class="stat-name"> | ||
({trait_type, value, max}) => html` | ||
<div class="trait_ranking" style="${styleMap(rankStyle)}"> | ||
<div class="trait_ranking" style=${styleMap(rankStyle)}> | ||
<div class="trait_ranking-header"> | ||
@@ -427,3 +427,2 @@ <div class="trait_ranking-header-name"> | ||
class="trait_ranking-bar-fill" | ||
<!-- if no max then just render full bar --> | ||
style=${styleMap({width: `${(+value / +(max || 1 )) * 100}%`})} | ||
@@ -508,3 +507,3 @@ ></div> | ||
} else { | ||
return html`<a class="remainingTraits" href="${this.openseaLink}" target="_blank">+${numRemaining} more</a>` | ||
return html`<a class="remaining-traits" href="${this.openseaLink}" target="_blank">+${numRemaining} more</a>` | ||
} | ||
@@ -511,0 +510,0 @@ } |
@@ -6,3 +6,8 @@ import { css, customElement, html, LitElement, property } from 'lit-element' | ||
import { OpenSeaAsset, OpenSeaFungibleToken } from 'opensea-js/lib/types' | ||
import { | ||
Network, | ||
OpenSeaAsset, | ||
OpenSeaCollection, | ||
OpenSeaFungibleToken | ||
} from 'opensea-js/lib/types' | ||
/* lit-element classes */ | ||
@@ -16,10 +21,10 @@ import './info-button' | ||
export class NftCardFrontTemplate extends LitElement { | ||
@property({type: Object}) public asset?: OpenSeaAsset | ||
@property({type: Boolean}) public isOwnedByAccount!: boolean | ||
@property({type: String}) public account!: string | ||
@property({type: Boolean}) public horizontal!: boolean | ||
@property({type: Object}) public state!: State | ||
@property({type: Object}) public asset?: OpenSeaAsset | ||
@property({type: Boolean}) public isOwnedByAccount!: boolean | ||
@property({type: String}) public account!: string | ||
@property({type: Boolean}) public horizontal!: boolean | ||
@property({type: Object}) public state!: State | ||
static get styles() { | ||
return css` | ||
static get styles() { | ||
return css` | ||
.card-front { | ||
@@ -38,3 +43,3 @@ position: absolute; | ||
.is-vertical { | ||
grid-template-columns: 1fr; | ||
grid-template-columns: 100%; | ||
grid-template-rows: 60% 40%; | ||
@@ -87,3 +92,3 @@ } | ||
.asset-detail-name { | ||
font-weight: 300; | ||
font-weight: 400; | ||
text-align: left; | ||
@@ -100,3 +105,3 @@ } | ||
justify-content: flex-end; | ||
align-items: center; | ||
align-items: baseline; | ||
} | ||
@@ -140,14 +145,23 @@ .asset-detail-price img { | ||
` | ||
} | ||
} | ||
public getAssetPriceTemplate() { | ||
const sellOrder = this.asset?.sellOrders && this.asset?.sellOrders.length > 0 ? this.asset.sellOrders[0] : null | ||
const currentPriceTemplate = sellOrder && sellOrder?.paymentTokenContract ? | ||
this.getPriceTemplate(PriceType.Current, sellOrder?.paymentTokenContract, sellOrder?.currentPrice?.toNumber() || 0) : null | ||
private static getAssetImageStyles(collection: OpenSeaCollection) { | ||
// @ts-ignore - since card_display_style is not serialized by opensea sdk yet | ||
const cardDisplayStyle = collection.displayData.card_display_style | ||
return { | ||
'padding': cardDisplayStyle === 'padded' ? '10px' : '', | ||
'background-size': `${cardDisplayStyle}` | ||
} | ||
} | ||
const prevPriceTemplate = this.asset?.lastSale?.paymentToken ? | ||
this.getPriceTemplate(PriceType.Previous, this.asset?.lastSale?.paymentToken, | ||
+this.asset?.lastSale?.totalPrice) : null | ||
public getAssetPriceTemplate() { | ||
const sellOrder = this.asset?.sellOrders && this.asset?.sellOrders.length > 0 ? this.asset.sellOrders[0] : null | ||
const currentPriceTemplate = sellOrder && sellOrder?.paymentTokenContract ? | ||
this.getPriceTemplate(PriceType.Current, sellOrder?.paymentTokenContract, sellOrder?.currentPrice?.toNumber() || 0) : null | ||
return (html` | ||
const prevPriceTemplate = this.asset?.lastSale?.paymentToken ? | ||
this.getPriceTemplate(PriceType.Previous, this.asset?.lastSale?.paymentToken, | ||
+this.asset?.lastSale?.totalPrice) : null | ||
return (html` | ||
<div class="asset-detail-price"> | ||
@@ -160,12 +174,17 @@ <a class="asset-link" href="${this.asset?.openseaLink}" target="_blank"> | ||
`) | ||
} | ||
} | ||
/** | ||
* Implement `render` to define a template for your element. | ||
*/ | ||
public render() { | ||
if (!this.asset) { | ||
return undefined // If there is no asset then we can't render | ||
} | ||
return html` | ||
/** | ||
* Implement `render` to define a template for your element. | ||
*/ | ||
public render() { | ||
if (!this.asset) { | ||
return undefined // If there is no asset then we can't render | ||
} | ||
const {openseaLink, collection, assetContract, name} = this.asset | ||
const {network} = this.state | ||
return html` | ||
<div class="card-front ${classMap({'is-vertical': !this.horizontal})}"> | ||
@@ -182,8 +201,10 @@ <info-button | ||
<div class="asset-detail-type"> | ||
<pill-element | ||
.imageUrl=${this.asset.assetContract.imageUrl} | ||
.label=${this.asset.assetContract.name} | ||
textColor="#828282" | ||
border="1px solid #E2E6EF" | ||
></pill-element> | ||
<a class="asset-link" href="http://${network === Network.Rinkeby ? 'rinkeby.' : ''}opensea.io/assets/${collection.slug}" target="_blank"> | ||
<pill-element | ||
.imageUrl=${assetContract.imageUrl} | ||
.label=${assetContract.name} | ||
textColor="#828282" | ||
border="1px solid #E2E6EF" | ||
></pill-element> | ||
</a> | ||
</div> | ||
@@ -201,3 +222,3 @@ <!-- This badge is optional and must be rendered programmatically --> | ||
<div class="asset-detail-name"> | ||
<a class="asset-link" href="${this.asset.openseaLink}" target="_blank">${this.asset.name}</a> | ||
<a class="asset-link" href="${openseaLink}" target="_blank">${name}</a> | ||
</div> | ||
@@ -211,25 +232,25 @@ ${this.getAssetPriceTemplate()} | ||
` | ||
} | ||
} | ||
/* | ||
* EventHandler - Dispatch event allowing parent to handle click event | ||
* '_event' isn't used here but it's needed to call the handler | ||
*/ | ||
public eventHandler(_event: any, type: string) { | ||
const buttonEvent = new CustomEvent('button-event', { | ||
detail: { | ||
type | ||
} | ||
}) | ||
this.dispatchEvent(buttonEvent) | ||
} | ||
/* | ||
* EventHandler - Dispatch event allowing parent to handle click event | ||
* '_event' isn't used here but it's needed to call the handler | ||
*/ | ||
public eventHandler(_event: any, type: string) { | ||
const buttonEvent = new CustomEvent('button-event', { | ||
detail: { | ||
type | ||
} | ||
}) | ||
this.dispatchEvent(buttonEvent) | ||
} | ||
private getPriceTemplate(priceType: PriceType, paymentToken: OpenSeaFungibleToken, price: number) { | ||
return html` | ||
private getPriceTemplate(priceType: PriceType, paymentToken: OpenSeaFungibleToken, price: number) { | ||
return html` | ||
<div class="asset-detail-price"> | ||
${priceType === PriceType.Previous ? html`<div class="previous-value">Prev. </div>` : null} | ||
${ paymentToken.imageUrl ? | ||
html`<img src="${paymentToken.imageUrl}" alt="" ></img>` | ||
: html`<div class="previous-value">${paymentToken.symbol === 'ETH' ? 'Ξ' : paymentToken.symbol}</div>` | ||
} | ||
${paymentToken.imageUrl ? | ||
html`<img src="${paymentToken.imageUrl}" alt="" ></img>` | ||
: html`<div class="previous-value">${paymentToken.symbol === 'ETH' ? 'Ξ' : paymentToken.symbol}</div>` | ||
} | ||
<div class="asset-detail-price value ${priceType}-value"> | ||
@@ -240,11 +261,19 @@ ${toBaseDenomination(price, paymentToken.decimals)} | ||
` | ||
} | ||
} | ||
private getAssetImageTemplate() { | ||
return (html` | ||
private getAssetImageTemplate() { | ||
if (!this.asset) { | ||
return undefined | ||
} | ||
const {openseaLink, imageUrl, collection} = this.asset | ||
return (html` | ||
<div class="asset-image-container"> | ||
<a href="${this.asset?.openseaLink}" target="_blank"> | ||
<a href="${openseaLink}" target="_blank"> | ||
<div | ||
class="asset-image" | ||
style=${styleMap({'background-image': `url(${this.asset?.imageUrl})`})} | ||
style=${styleMap({ | ||
'background-image': `url(${imageUrl})`, | ||
...NftCardFrontTemplate.getAssetImageStyles(collection) | ||
})} | ||
></div> | ||
@@ -254,6 +283,6 @@ </a> | ||
`) | ||
} | ||
} | ||
private getButtonTemplate() { | ||
return html` | ||
private getButtonTemplate() { | ||
return html` | ||
<button | ||
@@ -265,39 +294,42 @@ @click="${(e: any) => this.eventHandler(e, 'view')}" | ||
` | ||
} | ||
} | ||
// @ts-ignore | ||
private _getButtonTemplate() { | ||
// @ts-ignore | ||
private _getButtonTemplate() { | ||
let btnType: ButtonType | ||
let btnType: ButtonType | ||
if (this.state.hasWeb3) { | ||
if (this.state.isUnlocked) { | ||
if (this.state.isMatchingNetwork) { | ||
if (this.state.isOwnedByAccount) { | ||
// The account owns asset | ||
btnType = ButtonType.Manage | ||
} else { | ||
// Asset is for sale and not owned by currently selected account | ||
btnType = ButtonType.Buy | ||
} | ||
if (this.state.hasWeb3) { | ||
if (this.state.isUnlocked) { | ||
if (this.state.isMatchingNetwork) { | ||
if (this.state.isOwnedByAccount) { | ||
// The account owns asset | ||
btnType = ButtonType.Manage | ||
} else { | ||
// Asset is for sale and not owned by currently selected account | ||
btnType = ButtonType.Buy | ||
} | ||
} else { | ||
// Network does not match or connected to unsupported network | ||
btnType = ButtonType.SwitchNetwork // "switchNetwork" + this.state.network | ||
} | ||
} else { | ||
// Wallet is locked or access not granted | ||
btnType = ButtonType.Unlock | ||
} | ||
} else { | ||
// Network does not match or connected to unsupported network | ||
btnType = ButtonType.SwitchNetwork // "switchNetwork" + this.state.network | ||
// No injected web3 found | ||
btnType = ButtonType.View | ||
} | ||
} else { | ||
// Wallet is locked or access not granted | ||
btnType = ButtonType.Unlock | ||
} | ||
} else { | ||
// No injected web3 found | ||
btnType = ButtonType.View | ||
} | ||
// If we are informing the user to switch networks we need to append the | ||
// network on which the asset resides | ||
const btnText: string = btnType === ButtonType.SwitchNetwork ? BTN_TEXT[btnType] + this.state.network : BTN_TEXT[btnType] | ||
const btnStyle = btnType === ButtonType.SwitchNetwork ? styleMap({'background': 'rgb(183, 183, 183)', 'cursor': 'not-allowed'}) : '' | ||
// If we are informing the user to switch networks we need to append the | ||
// network on which the asset resides | ||
const btnText: string = btnType === ButtonType.SwitchNetwork ? BTN_TEXT[btnType] + this.state.network : BTN_TEXT[btnType] | ||
const btnStyle = btnType === ButtonType.SwitchNetwork ? { | ||
'background-color': 'rgb(183, 183, 183)', | ||
'cursor': 'not-allowed' | ||
} : null | ||
return html` | ||
return html` | ||
<button | ||
style=${btnStyle} | ||
style=${btnStyle ? styleMap(btnStyle) : ''} | ||
@click="${(e: any) => this.eventHandler(e, btnType)}" | ||
@@ -308,3 +340,3 @@ > | ||
` | ||
} | ||
} | ||
} |
@@ -26,6 +26,7 @@ import { css, customElement, html, LitElement, property } from 'lit-element' | ||
const VERT_CARD_WIDTH_MOBILE = '90vw' | ||
const VERT_CARD_WIDTH_MOBILE = '80vw' | ||
const HORIZONTAL_CARD_HEIGHT = '200px' | ||
const HORIZONTAL_CARD_WIDTH = '670px' | ||
const HORIZONTAL_CARD_HEIGHT = '210px' | ||
const HORIZONTAL_CARD_WIDTH = '80vw' | ||
const HORIZONTAL_CARD_MAX_WIDTH = '670px' | ||
@@ -57,2 +58,3 @@ enum OrientationMode { | ||
@property({type: String}) public minHeight: string = '' | ||
@property({type: String}) public maxWidth: string = '' | ||
@property({type: String}) public network: Network = Network.Main | ||
@@ -83,3 +85,4 @@ | ||
background-color: transparent; | ||
font-family: Avenir Next, Avenir, Helvetica Neue, sans-serif; | ||
font-family: 'Roboto', sans-serif; | ||
-webkit-font-smoothing: antialiased; | ||
font-style: normal; | ||
@@ -100,3 +103,2 @@ font-weight: normal; | ||
border-radius: 5px; | ||
/* min-height: 260px; */ | ||
} | ||
@@ -146,2 +148,3 @@ .flipped-card .card-inner { | ||
this.minHeight = this.horizontal ? HORIZONTAL_MIN_CARD_HEIGHT : VERT_MIN_CARD_HEIGHT | ||
this.maxWidth = this.horizontal ? HORIZONTAL_CARD_MAX_WIDTH : '' | ||
@@ -237,3 +240,3 @@ this.hasWeb3 = !!window.web3 | ||
class="card ${this.flippedCard ? 'flipped-card' : ''}" | ||
style=${styleMap({width: this.width, height: this.height, minHeight: this.minHeight})} | ||
style=${styleMap({width: this.width, height: this.height, minHeight: this.minHeight, maxWidth: this.maxWidth})} | ||
> | ||
@@ -255,3 +258,3 @@ | ||
private async eventHandler(event: ButtonEvent) { | ||
const {detail} = event | ||
const { detail } = event | ||
@@ -258,0 +261,0 @@ switch (detail.type) { |
@@ -71,7 +71,7 @@ import { LitElement, html, customElement, property, css } from 'lit-element' | ||
class="pill ${this.imageUrl ? '' : 'no-img'}" | ||
style="${styleMap({ | ||
style=${styleMap({ | ||
backgroundColor: this.backgroundColor, | ||
color: this.textColor, | ||
border: this.border | ||
})}" | ||
})} | ||
> | ||
@@ -78,0 +78,0 @@ ${this.imageUrl ? html`<img src="${this.imageUrl}" alt=""/>` : ''} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
7398626
0.06%7790
0.48%