# Visualizer UI Documentation

## Get Started

    <html>
      <head>
        <link href="https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/index.css" rel="stylesheet" />
      </head>
      <body>
        <div
          class="visualizer"
          data-role="visualizer"
          experienceId="<your experience id, optional if using hashExperienceId>"
          hashExperienceId="<your hashed experience id, optional if using experienceId>"
          sceneConfigurationLabel="<optional, the maximum width image size to use on mobile, a number from 0 to 2048>"
          sceneId="<optional, will lunch a scene by scene id>"
          defaultProduct="<optional, product sku, will display the product on all available supported application>"
          defaultProducts="<optional, a stringified key vale pair, key: application, value: product sku, will present those as defaults >"
        ></div>
        <script>
          const containerElement = document.querySelector('[data-role="visualizer"]')
          containerElement.addEventListener('visualizerLoaded', (event) => {
            const visualizer = event.detail.visualizer
          })
        </script>
        <script src="https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/index.js"></script>
      </body>
    </html>

## Customization, Theming Supported & css variables

It can be given as a configuration linked to the experienceId Otherwise as a HTML and CSS as in the examples bellow..

To override a css rules add a css file like in the example https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/examples/globalVariables.css

### Changing constant titles labels and icons

pass a stringified object as an attribute into the base div element

#### example

    <body>
      <div
        class="visualizer"
        data-role="visualizer"
        experienceId="<your experience id here>"
        constants='{"menu":{"hotspots":{"label":"Hotspots"}}}'
      ></div>
    </body>

#### a full Documentation of custom labels titles and icons can be found under the Constants section

https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/doc/modules/src_app_iconstants.html"

#### an example for a constant object can be found at

https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/examples/Constants.json"

### Client API

It is accessed through an object that is attached to the visualizer container:

    const container = document.querySelector('[data-role="visualizer"]')
    container.visualizerUI.showAddToCart('sku')

Documentation of the methods available on that object: https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/doc/modules/src_app_clientapitypes.html

## Launcher

Documentation: https://visualizer.byondxr.com/releases/visualizer-ui/3.0.95/doc/modules/generated_doc_launchertypes.html

    export type IFavoriteScene = {
        id: string;
        image: string;
        favorites: IFavorite[];
        scene: IScene;
    };
    export type IFavoriteSceneList = IFavoriteScene[];

    export type IProduct = {
        sku: string;
        name?: string;
        title: string;
        description?: string;
        application: string;
        image: string;
        price?: string;
        facets?: IFacet[];
        badges?: string[];
        applications?: string[];
        _id: string;
    };
    export type IFavorite = {
        product: IProduct;
    };
    export type IFavoriteProductList = IFavorite[];

    export type IProductSkuAndApplication = {
        sku: string;
        application: string;
    };
    export type IFavoriteProductSkuAndApplication = {
        product: IProductSkuAndApplication;
    };
    export type IFavoriteProductSkuAndApplicationList = IFavoriteProductSkuAndApplication[];

    type TLaunchParam = {
        selector?: string
        sceneId?: string
        defaultApplication?: string
        defaultProduct?: string | number
        scene_configuration?: string
        experienceId?: string
        hashExperienceId?: string
        maxProductMapSize?: string | number
        maxProductMapSizeMobile?: string | number
        maxMapSize?: string | number
        maxMapSizeMobile?: string | number
        defaultProducts?: { [index: string]: string | number }
        productsList?: (string | number)[]
        favoriteScenes?: IFavoriteSceneList
        favoriteProducts?:  IFavoriteProductList | IFavoriteProductSkuAndApplicationList
    }

    type TVisualizerContainer: Element

    window.launchVisualizer(params: TLaunchParams): Promise<TVisualizerContainer>

### Launcher example

            <button
                onClick={() => {
                    window.launchVisualizer({
                        experienceId: 'G2GcP2',
                        defaultProducts: { Countertop: '1200302000' },
                        defaultProduct: '1200302000',
                        productsList: ['1200302000', '334442000']
                        sceneId: '6',
                        scene_configuration: 'US-EN',
                    }).then((visualizerContainer)=>{
                        // Here the visualizer is loaded and you can do with it whatever you need such as:
                        visualizerContainer.visualizerUI.showAddToCart('sku')
                        visualizerContainer.visualizer.setFavoriteProducts([ {product: {application: 'Backsplash', sku: '1040502005'}} ])
                    })
                }}
            >
                Launch
            </button>

## Favorites

        /** set favorite scenes */
        abstract setFavoriteScenes(favoriteScenes: IFavoriteSceneList);

        /** set favorite products */
        abstract setFavoriteProducts(favoriteProducts: IFavoriteProductList | IFavoriteProductShortList);

Code example:

    // subscribe to events that save favorites to localstorage
    let subscribe = (container) => {
      const saveProducts = (param) => {
        localStorage.setItem('favoriteProducts', JSON.stringify(param.favorites))
      }
      const saveScenes = (param) => {
        localStorage.setItem('favoriteScenes', JSON.stringify(param.favoriteScenes))
      }
      container.Visualizer.addListener('productAddedToFavorites', saveProducts)
      container.Visualizer.addListener('productRemovedFromFavorites', saveProducts)
      container.Visualizer.addListener('sceneAddedToFavorites', saveScenes)
      container.Visualizer.addListener('sceneRemovedFromFavorites', saveScenes)

      // upon new start of application - read from localstorage
      container.Visualizer.setFavoriteProducts(JSON.parse(localStorage.getItem('favoriteProducts')))
      container.Visualizer.setFavoriteScenes(JSON.parse(localStorage.getItem('favoriteScenes')))
    }

Subscribe to the Visualizer by acquiring its container. Example:

    container = document.querySelector('[data-role="visualizer"]')
    subscribe(container)

If the container is not there beause it will be launched, then use the launchVisualizer promise to acquire the container

            <button onclick="
                const productsInitExampleSkus = ()=> {
                    const products = [   {product: {application: 'Backsplash', sku: '1040502005'}},
                            {product: {application: 'Countertop', sku: '1400402005'}},
                            {product: {application: 'Countertop', sku: '1401102015'}},
                            {product: {application: 'Countertop', sku: '1400302005'}} ]
                    localStorage.setItem('favoriteProducts', JSON.stringify(products))
                }

                productsInitExampleSkus()

            ">
                example - saves favorite product sku/application pairs to localstorage
            </button>
            <button
                onClick={() => {
                    window.launchVisualizer({
                        experienceId: 'G2GcP2',
                        defaultProducts: { Countertop: '1200302000' },
                        defaultProduct: '1200302000',
                        sceneId: '6',
                        scene_configuration: 'US-EN',
                    }).then((visualizerContainer)=>{
                        // Here the visualizer is loaded and you can do with it whatever you need
                        subscribe(visualizerContainer)
                    })
                }}
            >
                Launch
            </button>

## Badges

### Badges look

- the badges are absolute pusition relative to the image of the product

    "theme": {
      "catalogBadges": {
            "badgeField": "__FilterSize",
            "badges": [
              {
                "name": "new",
                "label": "New",
                "bgcolor": "red",
                "icon": {
                  "url": "https://web-apps.byondxr.com/assets/alony/icons/photo-camera.svg"
                }
              },
              {
                "style": {
                  "right": "0",
                  "left": "auto",
                  "borderRadius": "3px 0px 0px 3px"
                },
                "name": "sale",
                "label": "30% SALE",
                "bgcolor": "C58"
              }
            ]
         }
    }

### First option

Definitions (badges) are read from the catalog custom fields.

### Second option

Badges are provided on client . First client will receive event: 'productsListed' with this eventData: { detail: { products: { sku: string }[] } } Then, on his own time, he will call client-api function provided with badges:

    const elm = document.querySelector('[data-role="visualizer"]')
    elm.addEventListener('productsListed', (event) => {
      let products = event.detail.products
      console.log(products)
      products[0].badges = ['sale']
      products[1].badges = ['new']
      elm.visualizerUI.setProductsBadges({ products })
    })

    export type TSetProductsBadgesParams = {
        products: {
            sku: string
            badges: string[]
        }[]
    }

    setProductsBadges: (params: TSetProductsBadgesParams) => void

## Product details dialog

### Additional Product fields

detailsText:

- it will show in the dialog as an additonal text
- this name is not final, is just an example (till then, the string shows just an example )

### Theme settings

- Modify launch button text and visibility (which is always add-to-cart)
- Modify product details dialog button

    {
      "theme": {
        "buttons": {
          "add_to_cart": {
            "label": "More Details",
            "visible": true
          },
          "productDetails": {
            "add_to_cart": {
              "label": "Add to cart",
              "visible": true
            }
          }
        }
      }
    }

### Per application settings in the publisher config

- existense of productDetails config under application object as bellow - will enable the Launch button to open the dialog

#### PD example

    {
      "applications": [
        {
          "application": "application-name",
          "productDetails": {
            "model": {
              "edges": [
                {
                  "imageUrl": "https://i.ibb.co/bX6N02D/edge1.png",
                  "label": "edgeccccc text 1 QA TEST",
                  "animationName": "",
                  "id": "edge1"
                },
                {
                  "imageUrl": "https://i.ibb.co/bX6N02D/edge1.png",
                  "label": "edge text 2",
                  "animationName": "CT 02",
                  "id": "edge2"
                },
                {
                  "imageUrl": "https://i.ibb.co/bgZmztN/edge2.png",
                  "label": "edge text 3",
                  "animationName": "CT 03",
                  "id": "edge3"
                }
              ],
              "modelUrl": "https://drive.google.com/uc?export=download&id=1z2LzIw_iJuif2huNdFxCRskR_HzIDZVC",
              "distance": "4.1",
              "yRotate": "60",
              "xRotate": "50"
            },
            "fields": {
              "detailsText": {
                "visible": true
              },
              "description": {
                "visible": true
              },
              "price": {
                "visible": true
              },
              "title": {
                "visible": true
              }
            },
            "buttons": {
              "addToCart": {
                "visible": true
              }
            }
          }
        }
      ]
    }

#### PD Types

    export interface IButtonConfiguration {
      visible?: boolean
    }
    export interface IFieldConfiguration {
      visible?: boolean
    }
    export interface IProductDetailsButtonsConfiguration {
      addToCart?: IButtonConfiguration
    }

    export interface IProductDetailsFieldsConfiguration {
      price?: IFieldConfiguration
      title?: IFieldConfiguration
      description?: IFieldConfiguration
      detailsText?: IFieldConfiguration
    }
    export interface IProductDetailsEdgeConfiguration {
      id: string
      animationName: string
      label: string
      imageUrl: string
    }

    export interface IProductDetailsModelConfiguration {
      modelUrl: string
      xRotate?: number
      yRotate?: number
      distance?: number
      edges: IProductDetailsEdgeConfiguration[]
    }

    export interface IProductDetails {
      buttons?: IProductDetailsButtonsConfiguration
      fields?: IProductDetailsFieldsConfiguration
      model: IProductDetailsModelConfiguration
    }

    export interface IApplication {
      application: string
      title: string
      image?: string
      productDetails?: IProductDetails
      buttons?: IApplicationButtonsConfiguration
      fields?: IApplicationFieldsConfiguration
    }

Generated using TypeDoc