# 6551 Display Widget

## **Current Version**

`0.0.1`

#### **Javascript Library**

<https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.umd.js>

#### Base CSS Library

<https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.css>

#### Additional CSS Themes

The examples below show how to reskin this Widget by using a CSS overrides. We've created an example light and dark mode skin for you.

<https://6551display.manifoldxyz.dev/0.0.1/main.dark.css>

<https://6551display.manifoldxyz.dev/0.0.1/main.light.css>

## ERC 6551 Specification

<https://docs.tokenbound.org/>

<https://eips.ethereum.org/EIPS/eip-6551>

## Configuration

#### Required Properties

* **data-widget**: `"m-6551-display-widget"`
* **data-network**: `1 or 5`
* **data-token-id:** any token id
* **data-token-contract:** any NFT contract address
* **data-implementation:** [see ERC6551 spec](https://eips.ethereum.org/EIPS/eip-6551)
* **data-salt:** [see ERC6551 spec](https://eips.ethereum.org/EIPS/eip-6551)

#### Optional Properties

* **data-layout:** see [#layout](#layout "mention")
* **data-query-filters:** see [#query-filters](#query-filters "mention")
* **data-on-populate:** see [#on-populate-callback](#on-populate-callback "mention")
* **data-on-call-to-action:** see [#call-to-action-callback-and-ux-text](#call-to-action-callback-and-ux-text "mention")
* **data-only-owner-can-call-to-action:** see [#call-to-action-callback-and-ux-text](#call-to-action-callback-and-ux-text "mention")
* **data-call-to-action-text:** see [#call-to-action-callback-and-ux-text](#call-to-action-callback-and-ux-text "mention")

#### Minimum Viable Example

<pre class="language-html"><code class="lang-html">
&#x3C;script src="https://connect.manifoldxyz.dev/2.2.7/connect.umd.min.js">&#x3C;/script>
&#x3C;script src="https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.umd.js">&#x3C;/script>
<strong>&#x3C;link rel="stylesheet" href="https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.css">
</strong><strong>&#x3C;div
</strong>    data-widget="m-6551-display-widget"
    data-network="5"
    data-token-id="261"
    data-token-contract="0x7a77F2cFB02546F217d39157471d5B5914DD7644"
    data-implementation="0x2d25602551487c3f3354dd80d76d54383a243358"
    data-salt="0"
/>
</code></pre>

#### Maximum Viable Example

<pre class="language-html"><code class="lang-html">
&#x3C;script src="https://connect.manifoldxyz.dev/2.2.7/connect.umd.min.js">&#x3C;/script>
&#x3C;script src="https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.umd.min.js">&#x3C;/script>
&#x3C;link rel="stylesheet" href="https://6551display.manifoldxyz.dev/0.0.1/6551-display-widget.css">
&#x3C;link rel="stylesheet" href="https://6551display.manifoldxyz.dev/0.0.1/main.dark.css">
<strong>&#x3C;div
</strong>    data-widget="m-6551-display-widget"
    data-fallback-provider="https://...someprc"
    data-transferrable="true"
    data-network="5"
    data-layout="backpack"
    data-token-id="261"
    data-token-contract="0x7a77F2cFB02546F217d39157471d5B5914DD7644"
    data-implementation="0x2d25602551487c3f3354dd80d76d54383a243358"
    data-salt="0"
    data-query-filters=exampleQueryFilter
    data-on-populate=exampleOnPopulate
    data-on-call-to-action=exampleOnCallToAction
    data-only-owner-can-call-to-action="true"
    data-call-to-action-text="Dress Up"
  />

</code></pre>

## Optional Parameters

### Layout

```javascript
type: String, // 'backpack' or 'photoalbum'
default: 'backpack'
// ex
data-layout="photoalbum"
```

Allows for changing of the overall UX of the widget. Default is `photoalbum`, and `backpack` is another option. We may have more layouts soon.

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FpuWxs4XkjWpX0jpOnJB1%2Fimage.png?alt=media&#x26;token=d5470574-710c-4d1c-8716-14da76837ef2" alt=""><figcaption><p>photoalbum example</p></figcaption></figure>

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FKuG8dRMADdvaZbvQfzR7%2Fimage.png?alt=media&#x26;token=654d8a7f-4f1f-4d4b-8e9c-08daa09767fe" alt=""><figcaption><p>backpack layout</p></figcaption></figure>

### Tranferrable

```javascript
type: Boolean,
default: false
// ex
data-transferrable="true"
```

When set to `true`, the widget will display a Connect Widget to login with, and then a transfer button next to every NFT your ERC6551 NFT owns.

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FZZqk5iOtwNcbhXjm4uhV%2FScreen%20Shot%202023-05-31%20at%203.16.14%20PM.png?alt=media&#x26;token=b2d5f990-add8-4cbf-99b6-59367148ba15" alt=""><figcaption><p>The connect button shows when <code>data-transferrable</code> or <code>only-owner-can-call-to-action</code> is <code>true</code></p></figcaption></figure>

Once logged in, the user will be able to transfer NFTs in and out of their 6551 Account *as long as they are the owner of the original ERC6551 NFT.*

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FQPtOom1r5irXIWFMMiMq%2FScreen%20Shot%202023-05-31%20at%203.02.09%20PM.png?alt=media&#x26;token=2a0d7446-00a6-43e2-972d-478e0ea4644e" alt=""><figcaption><p>A "selected" asset when <code>selectable</code> is true for its Group</p></figcaption></figure>

### Query Filters

```typescript
export interface TokenFilter {
    contractAddress: string;
    tokenId?: string;
    tokenIds?: Array<string>;
    minTokenId?: string;
    maxTokenId?: string;
    attributes?: Array<TokenAttribute>;
}

export interface TokenAttribute {
    traitType?: string;
    value: string;
}
```

```javascript
type: (): TokenFilter[],
default: (): TokenFilter[] => [],
// ex
function yourQueryFilterFunction (...) {...}
data-query-filters=yourQueryFilterFunction
```

Allows for filtering of the initial request for all NFTs owned by the ERC6551 NFT in its 6551 Account. Set this to a function reference.

[See filtering information here](https://docs.manifold.xyz/v/manifold-for-developers/resources/widgets/connect-widget/data-client/nft-information-retrieval)

### On Populate Callback

<pre class="language-typescript"><code class="lang-typescript"><strong>export type DataClientNFT = {
</strong>  contractAddress: string;
  tokenId: string;
  ownerAddress: string;
  name: string;
  image: string;
  spec: string;
  count: string;
  assets?: {
    nfts: DataClientNFT[];
  }
  metadata: {
    image?: string;
    image_url?: string;
    animation_url?: string;
  }
}

type Groups = {
  [key:string]: GroupDefinition
}

type GroupDefinition {
  items: DataClientNFT[],
  selectable?: boolean
  selectableLimit?: number
  selectedIndices?: number[]
}
</code></pre>

```javascript
type: (nft: DataClientNFT, groups: Groups): { nft: DataClientNFT, groups: Groups },
default: (nft: DataClientNFT, groups: Groups): Groups  => {
  // these assets are what will display next to the `nft`
  // feel free to sort them, or split them into new Groups
  return { nft,  groups };
}
// ex
function yourOnPopulateFunction (...) {...}
data-on-populate=yourOnPopulateFunction
```

Allows for sorting of the `assets` returned by the Data Client into specified groups, and allows for inspection of the core ERC6551 NFT as `nft`.

The `assets` can be returned as is, or modified in order to sort and regroup the NFTs.&#x20;

You may also customize whether the NFTs in each group are `selectable` and the max `selectableLimit` of each group.&#x20;

This data is updated as the user interacts with the widget, and returned into the `on-call-to-action` callback for your usage.

The `backpack` layout will automatically create a headline for each of the returned`Groups` and break up the grid into sections based on said headline.

You may optional give `selectedIndices` an initial value in order to have the widget preselect those NFTs on initial render.

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FL6J6Ofi06GlPADcdUJYT%2FScreen%20Shot%202023-05-31%20at%203.00.16%20PM.png?alt=media&#x26;token=ebc1a81b-6c1f-4420-9ea6-ca2d955da14a" alt=""><figcaption><p>When selected, we give a basic skinnable UX to signify which ones are selected. We disable the rest once the <code>maxSelectableLimit</code> for the group is reached.</p></figcaption></figure>

### Call To Action Callback and UX Text

```typescript
export type DataClientNFT = {
  contractAddress: string;
  tokenId: string;
  ownerAddress: string;
  name: string;
  image: string;
  spec: string;
  count: string;
  assets?: {
    nfts: DataClientNFT[];
  }
  metadata: {
    image?: string;
    image_url?: string;
    animation_url?: string;
  }
}

type Groups = {
  [key:string]: GroupDefinition
}

type GroupDefinition {
  items: DataClientNFT[],
  selectable?: boolean
  selectableLimit?: number
  selectedIndices?: number[]
}
```

```javascript
type: (nft: DataClientNFT, groups: Groups): Promise<void | {
  nft: DataClientNFT,
  groups: Groups
}>
default: (nft: DataClientNFT, groups: Groups): Promise<void | {
  nft: DataClientNFT,
  groups: Groups
}> => {
  return;
}
// ex
function yourOnCallToActionFunction (...) {...}
data-on-call-to-action=yourOnCallToActionFunction
```

```javascript
type: String
default: ''
// ex
data-call-to-action-text="Dress Up"
```

```javascript
type: Boolean
default: true
// ex
data-only-owner-can-call-to-action="false"
```

When both `data-on-call-to-action` and `data-call-to-action-text`are defined, a call to action button will appear in the top right of the UX with your specifed text inside of it.

<figure><img src="https://268636785-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8n4plerMUJrsrAiaKpc2%2Fuploads%2FE7zx5eQtsOxGpewLmR3q%2FScreen%20Shot%202023-05-31%20at%203.18.06%20PM.png?alt=media&#x26;token=3cc08fd8-75a2-47d0-bd4d-522a38a15572" alt=""><figcaption><p>An example where the <code>data-call-to-action-text</code> is Dress Up and <code>data-only-owner-can-call-to-action</code> is set to <code>true</code></p></figcaption></figure>

When clicked, it will perform you call to action callback. The UX will disable while your callback executes asynchronously.

The `data-only-owner-can-call-to-action` option will cause a Connect Widget to appear, and cause the CTA button to disable unless the user is the owner of the ERC6551 NFT.

One example usage for this would be PFPs and 3D Avatars that could potentially execute a "Dress Up" call to action whenever the owner is done selecting NFTs from each Group to "wear", you can then modify the `nft` data before passing it back in order to show the updates!

## CSS Theme'ing and Overriding

#### Manifold CSS Vars Overriding

```css
--manifold-theme--color--primary
--manifold-element--color--background
--manifold-page--color--background
--manifold-text--color--muted
--manifold-element--color-blurry
--manifold-theme--color--info
--manifold-theme--color--success
--manifold-theme--color--error
--manifold-text--color--body
--manifold-text--font-family--body
--manifold-text--font-size--body
--manifold-text--font-size--header
--manifold-text--font-size--info
--manifold-theme--border
--manifold-theme--border-radius
```

#### Toastify CSS

```css
/*!
 * Toastify js 1.12.0
 * https://github.com/apvarun/toastify-js
 * @license MIT licensed
 *
 * Copyright (C) 2018 Varun A P
 */

// Here are the defaults so you know what's already defined and what you might 
// want to override.

// These are the little toast that show up in the top right during transefr tx.

.toastify {
    padding: 12px 20px;
    color: #ffffff;
    display: inline-block;
    box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);

    position: fixed;
    opacity: 0;
    transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
    max-width: calc(50% - 20px);
    z-index: 2147483647;
}

.toast-close {
    background: transparent;
    border: 0;
    color: white;
    cursor: pointer;
    font-family: inherit;
    font-size: 1em;
    opacity: 0.4;
    padding: 0 5px;
}

.toastify-rounded {
    border-radius: 25px;
}
```
