0.0.94 • Published 15 days ago

@threekit-tools/treble v0.0.94

Weekly downloads
-
License
MIT
Repository
-
Last release
15 days ago

Treble React

All you need to build a Web Experience for your Threekit Configurator.

Overview

The Treble Design System is a feature-rich React library of components, hooks, and added functionality needed to build an intuitive and engaging web experience for a Threekit Configurator.

We have everything you need to get started!

Useful Links

Table of Contents

Getting Started

Installation

Run the following command using npm:

npm install @threekit-tools/treble

Or yarn:

yarn add @threekit-tools/treble

Quick Start

A basic app will include the Threekit Provider, to connect our components to the Threekit API, A Player Component, to render our 3D visuals, and a Form to let the user configure the visualized product.

To get started you can copy the code from below, populating the values in the threekitConfig object.

import { ThreekitProvider, Player, FlatForm } from '@threekit-tools/treble';

const threekitConfig = {
  credentials: {
    preview: {
      orgId: '',
      assetId: '',
      publicToken: '',
    },
  },
};

const threekitEnv = 'preview';

const ThreekitApp = () => {
  return (
    <ThreekitProvider {...threekitConfig} threekitEnv={threekitEnv}>
      <div
        style={{
          height: '100vh',
          maxWidth: '1000px',
          margin: '0 auto',
          display: 'grid',
          gridTemplateColumns: 'auto 400px',
          gridGap: '12px',
        }}
      >
        <Player />
        <FlatForm />
      </div>
    </ThreekitProvider>
  );
};

Components

Threekit Provider

The <ThreekitProvider /> initializes the Threekit API used by the various components in the Treble library. It should be wrapped around the portion of the React app where the Treble components and hooks are being used.

The Threekit Provider requires the a config object, which includes all the credentials related a the project.

import React from 'react';
import ReactDOM from 'react-dom';

import { ThreekitProvider } from '@threekit-tools/treble';
import App from './App';

const config = {
  //  The environment specific credentials should be placed
  //  in an object assigned to the name of the environment
  //  Note: The token key is 'publicToken' not 'authToken'
  preview: {
    publicToken: '3fb4asd5d-ea38-4a05-a2g3-6cf9d8dd3d48',
    assetId: 'a9a66218-bkid-4106-96fe-a0359fdc3dc1',
    orgId: '20df501b-1ef8-4bh0-sfda-2l59426624de',
  },
  'admin-fts': {
    publicToken: '3fb4asd5d-ea38-0g05-a1c3-6cf9d8dd3d48',
    assetId: 'a9a66218-bkid-2206-96fe-a0709fdc3dc1',
    orgId: '20df501b-1ef8-4bkm-sfda-2b99426624de',
  },
  //  Any additional parameters to pass to the player initialization
  //  can also be added here. For example setting the showShare
  //  property
  showShare: true,
  // We can pass overwrites to the default theme
  theme: { primaryColor: '#54AA54' },
};

const threekitEnv = 'preview';

ReactDOM.render(
  <ThreekitProvider config={config} threekitEnv={threekitEnv}>
    <App /> // All Threekit related code goes here
  </ThreekitProvider>,
  document.getElementById('root')
);

Threekit Provider Props

The Threekit Provider takes two props:

The threekitEnv sets which Threekit environment, preview | admin-fts, to use when running the app. It defaults to the preview environment.

const threekitEnv = 'admin-fts';

A config object including the Threekit environment credentials, the Player API initialization parameters and any theme overrides.

The Threekit environment credentials include all variables that are specific to the Threekit Environment you are using. These include:

const threekitEnvironmentCredentials = {
  //  The public auth token created in the settings
  //  tab in your org on the Threekit Platform. It should
  //  include the `localhost` domain for local development
  //  and any domains to include for production / deployment
  publicToken: '',
  //  The Org Id for the Threekit Org
  orgId: '',
  //  The asset id of the Catalog Item you wish to initialize
  //  in the Threekit Player
  assetId: '',
  //  (optional): The Asset Id of the Stage you wish to initialize in the
  //  Threekit Player
  stageId: '',
};

The Player API initialization parameters should be added directly to the config object. More information about parameters can be found here: Embedding the Threekit Player.

const threekitConfig = {
  playerConfig: {
    //  (optional): determines whether to use the 3D Player (webgl) or
    //  the 2D Player (image).
    display: 'webgl' | 'image',
    //  The caching options for the player. It contains the maxAge
    //  and scope for assets caching.
    cache,
    //  (optional): Determines if we render the default Threekit
    //  configurator.
    showConfigurator: true | false,
    //  (optional): An override for the configuration to initialize
    //  our asset with.
    initialConfiguration: {},
    //  (optional): parameter to display a snapshot while the player
    //  is loading. Default value is false
    showLoadingThumbnail: true | false,
    //  (optional): Determines if we show the progress bar during
    //  load. Default value is true.
    showLoadingProgress: true | false,
    //  Takes a callback as its value. The callback's only argument
    //  is a number, representing the progress ratio ( from 0.0
    //  to 1.0 ). The callback will be called whenever the loading
    //  progresses. The progress ratio is only approximate.
    onLoadingProgress: progress =>
      console.log(`Progress ${parseInt(progress * 100)}`),
    //  (optional): Parameter to show/hide the built-in AR Button.
    //  Default value is false.
    showAR,
    //  (optional): Parameter to show/hide the built-in Share
    //  Button. Default value is false.
    showShare,
    //  (optional): toggles vertical orbit on mobile devices on or
    //  off. Default value is false.
    allowMobileVerticalOrbit: true | false,
    //  (optional): Override organization's compression setting for
    //  renders in 2D player.
    compression,
  },
};

The theme is used to style all the component available in the Treble library. You can override any of the default values by passing in your own value for a parameter into the theme object. The default values for the theme are:

const theme = {
  primaryColor: '#1890ff',
  linkColor: '#1890ff',
  successColor: '#52c41a',
  warningColor: '#faad14',
  errorColor: '#f5222d',
  fontBaseSize: '14px',
  headingColor: 'rgba(0, 0, 0, 0.85)',
  textColor: 'rgba(0, 0, 0, 0.65)',
  textColorSecondary: 'rgba(0, 0, 0, 0.45)',
  disabledColor: 'rgba(0, 0, 0, 0.25)',
  borderRadius: '2px',
  borderColorBase: '#d9d9d9',
  boxShadowBase:
    '0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);',
  widgetSize: '36px',
  fontFamily: '"Open Sans", sans-serif',
};

Player

The <Player /> component renders the Threekit Player.

import { ThreekitProvider, Player } from '@threekit-tools/treble';

const ThreekitApp = () => {
  return (
    <ThreekitProvider>
      <Player />
    </ThreekitProvider>
  );
};

Player Widgets

The Player Component also comes with widget containers that can be used to position widgets or any component in pre-defined locations around the player.

import { ThreekitProvider, Player } from '@threekit-tools/treble';

//  We can separate out the widget container component
//  or use the component directly from the Player component
const { TopRightWidgets } = Player;

const ThreekitApp = () => {
  return (
    <ThreekitProvider {...threekitConfig}>
      <Player>
        <TopRightWidgets>
          <div>This will show up in the top-right of the player</div>
        </TopRightWidgets>

        <Player.BottomRightWidgets>
          <div>This will show up in the bottom-right of the player</div>
        </Player.BottomRightWidgets>
      </Player>
    </ThreekitProvider>
  );
};

Forms

Forms can be used to render out complete configurators as a single component.

Flat Form

The <FlatForm> component is used to render out the configurator for the initialized asset.

import { ThreekitProvider, FlatForm } from '@threekit-tools/treble';

const App = () => {
  return (
    <ThreekitProvider {...threekitConfig}>
      <FlatForm />
    </ThreekitProvider>
  );
};

Flat Form Props

const flatFormProps = {
  //  Override title for the form
  title: 'Form Title',
  //  Override the description for the form
  description: 'This is a description for the form',
  //  Alignment for the title. Options include left | center | right
  alignTitle: 'center',
  //  Whether to include reserved Attributes.
  //  i.e. _camera (Camera Attribute)
  includeReservedAttributes: false,
  //  The Attributes object allows us to define component selections
  //  and props for the individual Attributes
  attributes: {
    //  This will render out 'Attribute 1' using the Buttons component
    'Attribute 1': { component: 'swatch' },
    //  This will prevent 'Attribute 2' from being rendered.
    'Attribute 2': undefined,
  },
};

The Flat Form can take a prop of attributes that allow us to specify, which component to use for an attribute or if we want to hide any attributes.

By default, the title and description will be sourced from the initialized item, however, we can also explicitly pass in values for these props.

We can also specify the horizontal alignment for the title by passing in one of left, right and center to the alignTitle prop.

By default the Form will not render reserved attributes. This can be controlled/over-written by using the prop includeReservedAttributes={false}.

import { ThreekitProvider, FlatForm } from '@threekit-tools/treble';

const App = () => {
  const attributes = {
    //  This will render out 'Attribute 1' using the Buttons component
    'Attribute 1': { component: 'swatch' },
    //  This will prevent 'Attribute 2' from being rendered.
    'Attribute 2': undefined,
  };

  return (
    <ThreekitProvider {...threekitConfig}>
      <FlatForm attributes={attributes} />
    </ThreekitProvider>
  );
};

Widgets

The Widgets offer a wide range of functionality and interactivity for the user to engage with including Downloadable Snapshots, Zoom Buttons, Save-to-Wishlist etc.

All the widgets are designed to be buttons that can be placed on and around the Threekit Player. Placing the Widgets on the Player component enhances their visibility for the end user, builds consistent experiences with our player and minimizes/simplifies the Threekit UI footprint when embedding into an existing page.

Snapshots

The <Snapshots /> is a button that will trigger the window.threekit.treble.takeSnapshot() when pressed and download the specified snapshots.

import { ThreekitProvider, Player, Snapshots } from '@threekit-tools/treble';

const Component = () => {
  return (
    <ThreekitProvider>
      <Player>
        <Player.TopRightWidgets>
          <Snapshots
            cameras={[undefined, 'birdsey-camera']}
            config={{ format: 'jpeg' }}
          />
        </Player.TopRightWidgets>
      </Player>
    </ThreekitProvider>
  );
};

The Snapshot takes two props: camerasList and snapshotsConfig.

The camerasList take a list of cameras to take snapshots from. It can be a single string or an array of strings depending on how many cameras are to be used for the snapshot. To take a snapshot from the user's current view, we specify that camera as undefined, both as an individual camera value or as part of the array of cameras. e.g. const cameras = [undefined, 'snapshot-camera-alt']

The snapshotConfig allows us to define the following values:

const snapshotsConfig = {
  format: 'png' | 'jpeg',
  filename: 'snapshot-filename',
};

Note: These cameras must be setup to the configurator using the reserved camera attribute.

Zoom

The <Zoom /> widget allows the user to control the zoom property of the Threekit Player.

The component is built using the useZoom hook. It provides a pair of + and - buttons the user can click to update the zoom.

It defaults to single increments changes but also accepts increment values to use instead.

import { ThreekitProvider, Player, Zoom } from '@threekit-tools/treble';

const Component = () => {
  return (
    <ThreekitProvider>
      <Player>
        <Player.MiddleRightWidgets>
          <Zoom orientation="vertical" />
        </Player.MiddleRightWidgets>
      </Player>
    </ThreekitProvider>
  );
};

Displays

Display components can be used to display specific information anywhere in the UI.

Product Title

The <ProductTitle /> component will display the value of the metadata key _title on the Catalog Item used to initialize the Player.

The title can also be overwritten by passing in your own title in as a prop.

import { ProductTitle } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <ProductTitle />
      // With a custom title
      <ProductTitle title="Custom Title" />
    </div>
  );
};

Product Description

The <ProductDescription /> component will display the value of the metadata key _description on the Catalog Item used to initialize the Player.

The description can also be overwritten by passing in your own description in as a prop.

It is built using the useMetadata() hook.

import { Description } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <ProductDescription />
      // With a custom description
      <ProductDescription description="This is a custom description." />
    </div>
  );
};

Attribute Title

The <AttributeTitle> will display the translated attribute name of an attribute.

It is built using the useName() hook.

import { AttributeTitle } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <AttributeTitle attribute="Attribute Name" />
    </div>
  );
};

Attribute Value

The <AttributeValue> will display the translated selected value of an attribute.

import { AttributeValue } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <AttributeValue attribute="Attribute Name">
    </div>
  );
};

Total Price

The <Price> component will display the total price of your configuration. It is calculated using the first Pricebook in the Org, and the first currency in that Pricebook.

It is built using the usePrice() hook.

Support for multiple Pricebooks and Currencies coming soon

import { TotalPrice } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <TotalPrice />
    </div>
  );
};

Wrappers

Await Threekit Load

The <AwaitThreekitLoad> wrapper, is used to wrap any content that we don't want to render until the Threekit Player initialization process is complete.

import { AwaitThreekitLoad } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <div>Content here will be rendered as normal</div>
      <AwaitThreekitLoad>
        This content will only be rendered after the Threekit Player
        intialization is complete
      </AwaitThreekitLoad>
    </div>
  );
};

Portal to Element

The <PortalToElement> wrapper can be used to place its content in any div anywhere in the DOM. This is can be very useful when embedding the app in an existing eCommerce page or Website, where you can split the app up into sections to be rendered independently within the page's existing html structure.

The wrapper requires an elementId prop to specify the id of the div to render its contents into. It also optionally takes a strict prop, which determines the behavior if the element to render the content into is not found. strict={true} will only render the contents in the HTML element matching the provided element ID, while strict={false} (default) will render out its contents as part of the regular React flow, if the specified element is not found.

import { AwaitThreekitLoad } from '@threekit-tools/treble';

const Component = () => {
  return (
    <div>
      <div>Content here will be rendered as normal</div>
      <PortalToElement elementId="form-container">
        This content will only be rendered in a div with the id 'form-container'
      </PortalToElement>
    </div>
  );
};

Layouts

Layouts are design organization components that we can use to introduce structure and visual hierarchy to our configurator and application. Most Layout components have no inherent connection to the Threekit API and can be used freely outside of the ThreekitProvider if needed.

Modal

A Modal is used to present an actionable pop-up to the user.

import { useState } from 'react';
import { Modal } from '@threekit-tools/treble';

const App = () => {
  const [showModal, setShowModal] = useState(false);

  const handleClose = () => setShowModal(false);

  return (
    <Modal show={showModal} handleClose={handleClose}>
      <div>
        Content to be placed in the modal is added as an HTML child element.
      </div>
    </Modal>
  );
};

Drawer

A Drawer can be used to present an actionable slide-out drawer to the user.

import { useState } from 'react';
import { Drawer } from '@threekit-tools/treble';

const App = () => {
  const [showDrawer, setShowDrawer] = useState(false);

  const handleClose = () => setShowDrawer(false);

  return (
    <Drawer show={showDrawer} handleClose={handleClose}>
      <div>
        Content to be placed in the drawer is added as an HTML child element.
      </div>
    </Drawer>
  );
};

Hooks

Use Attribute

The useAttribute hook allows us to connect a component to an Attribute in our configurator.

It takes the name of the attribute that you want to interact with and returns an array where the first element is the data for that attribute, as returned by the getDisplayAttributes() function, and the second element is a function that can be used to update the value of that attribute, by prepping and passing the value on to setConfiguration().

import { useAttribute } from '@threekit-tools/treble';

const AttributeComponent = () => {
  const [attribute, setAttribute] = useAttribute('Attribute Name');

  const selected = attribute.value;

  return (
    <div>
      <div>{attribute.label}</div>
      <div>
        {attribute.values.map((option, i) => (
          <div key={i} onClick={setAttribute(option.assetId)}>
            {option.label}
          </div>
        ))}
      </div>
    </div>
  );
};

Use Configurator

The useConfigurator hook allows us to connect to all our attributes in the initialized item's configurator.

The hook returns an array of two items. The first item is almost identical to the value returned by getDisplayAttributes(). The second item is a change handler function that passes the value passed in straight through to setConfiguration().

import { useConfigurator } from '@threekit-tools/treble';

const AttributeComponent = () => {
  const [attributes, setConfiguration] = useConfigurator();
  return <div>Attributes Component example</div>;
};

Use Threekit Init Status

import { useThreekitInitStatus } from '@threekit-tools/treble';

const Component = () => {
  const hasLoaded = useThreekitInitStatus();
  return (
    <div>
      {hasLoaded ? 'Threekit API has loaded' : 'Loading in progress...'}
    </div>
  );
};

Use Player Loading Status

import { usePlayerLoadingStatus } from '@threekit-tools/treble';

const Component = () => {
  const hasLoaded = usePlayerLoadingStatus();
  return (
    <div>
      {hasLoaded
        ? 'Threekit Player has rendering'
        : 'Player rendering in progress...'}
    </div>
  );
};

Use Metadata

The useMetadata hook provides the metadata present on the item used to initialize the player.

The hook returns an object with the metadata.

It is used to build the Description Display component

import { useMetadata } from '@threekit-tools/treble';

const MetadataComponent = () => {
  const metadata = useMetadata();
  return (
    <div>
      {Object.entries(metadata).map(([key, value], i) => (
        <div>
          {key}: {value}
        </div>
      ))}
    </div>
  );
};

Use Name

The useName hook provides the name of the item used to initialize the player.

The hook a single string value.

It is used to build the Title Display component

import { useName } from '@threekit-tools/treble';

const TitleComponent = () => {
  const name = useName();
  return <div>{name}</div>;
};

Use Price

The usePrice hook provides the total price of the current configuration calculated based on the pricing set on the Threekit Platform.

import { usePrice } from '@threekit-tools/treble';

const PriceComponent = () => {
  const price = usePrice();
  return <div>${price}</div>;
};

Use Snapshot

The useSnapshot should provides functionality to takeSnapshots of the view in the Threekit Player.

import { useSnapshot } from '@threekit-tools/treble';

const SnapshotComponent = () => {
  const takeSnapshots = useSnapshot();

  const handleClickSnapshot = () => {
    takeSnapshots(undefined, { output: 'download' });
  };

  return (
    <button onClick={() => handleClickSnapshot()}>Download Snapshot</button>
  );
};

Use Zoom

The useZoom hook provides functionality to control the zoom property in the Threekit Player.

The hook returns an array of 2 functions: zoom-in and zoom-out. Both functions accept a single argument: the zoom increment step.

The default increment value is 1.

It is used to build the Zoom Widget.

import { useZoom } from '@threekit-tools/treble';

const ZoomComponent = () => {
  const [zoomIn, zoomOut] = useZoom();
  return (
    <div>
      // Changes zoom by +1
      <button onClick={zoomIn}>Zoom In</button>
      // Changes zoom -3
      <button onClick={() => zoomOut(3)}>Zoom Out</button>
    </div>
  );
};
0.0.94

15 days ago

0.0.93

3 months ago

0.0.91-next-02

10 months ago

0.0.91-next-03

10 months ago

0.0.92

8 months ago

0.0.92-next-01

7 months ago

0.0.90-next-09

1 year ago

0.0.91-next-01

12 months ago

0.0.91

1 year ago

0.0.90-next-08

1 year ago

0.0.90-next-07

1 year ago

0.0.90-next-04

1 year ago

0.0.90-next-05

1 year ago

0.0.90-next-06

1 year ago

0.0.90-next-01

1 year ago

0.0.90-next-02

1 year ago

0.0.90-next-03

1 year ago

0.0.89-next-006

1 year ago

0.0.90

1 year ago

0.0.89-next-003

1 year ago

0.0.89-next-004

1 year ago

0.0.89-next-005

1 year ago

0.0.89-next-002

1 year ago

0.0.89-next-001

1 year ago

0.0.88

2 years ago

0.0.89

1 year ago

0.0.87

2 years ago

0.0.86

2 years ago

0.0.84

2 years ago

0.0.85

2 years ago

0.0.80

2 years ago

0.0.81

2 years ago

0.0.82

2 years ago

0.0.83

2 years ago

0.0.75

2 years ago

0.0.76

2 years ago

0.0.77

2 years ago

0.0.78

2 years ago

0.0.79

2 years ago

0.0.85-next-1

2 years ago

0.0.85-next-5

2 years ago

0.0.85-next-4

2 years ago

0.0.85-next-3

2 years ago

0.0.85-next-2

2 years ago

0.0.85-next-6

2 years ago

0.0.73

2 years ago

0.0.74

2 years ago

0.0.70

2 years ago

0.0.71

2 years ago

0.0.72

2 years ago

0.0.69

2 years ago

0.0.67

2 years ago

0.0.68

2 years ago

0.0.60-next.2

2 years ago

0.0.60-next.1

2 years ago

0.0.62

2 years ago

0.0.63

2 years ago

0.0.64

2 years ago

0.0.65

2 years ago

0.0.66

2 years ago

0.0.60

2 years ago

0.0.61

2 years ago

0.0.59

2 years ago

0.0.41

2 years ago

0.0.42

2 years ago

0.0.43

2 years ago

0.0.44

2 years ago

0.0.45

2 years ago

0.0.46

2 years ago

0.0.47

2 years ago

0.0.57-animation

2 years ago

0.0.51

2 years ago

0.0.52

2 years ago

0.0.53

2 years ago

0.0.54

2 years ago

0.0.55

2 years ago

0.0.56

2 years ago

0.0.57

2 years ago

0.0.58

2 years ago

0.0.50

2 years ago

0.0.48

2 years ago

0.0.49

2 years ago

0.0.40

2 years ago

0.0.39

2 years ago

0.0.38

2 years ago

0.0.37-codepen-0

2 years ago

0.0.37

2 years ago

0.0.36

2 years ago

0.0.35

2 years ago

0.0.34-codepen-0

2 years ago

0.0.34

2 years ago

0.0.33

2 years ago

0.0.32

2 years ago

0.0.31

2 years ago

0.0.30

2 years ago

0.0.29

2 years ago

0.0.28

2 years ago

0.0.27

2 years ago

0.0.26

2 years ago

0.0.25

2 years ago

0.0.24

2 years ago

0.0.23

2 years ago

0.0.22

2 years ago

0.0.21

2 years ago

0.0.20

2 years ago

0.0.19

2 years ago

0.0.18

2 years ago

0.0.17

2 years ago

0.0.16

2 years ago

0.0.15

2 years ago

0.0.14

2 years ago

0.0.13

2 years ago

0.0.12

2 years ago

0.0.10-alpha.17

2 years ago

0.0.10-alpha.16

2 years ago

0.0.10-alpha.14

2 years ago

0.0.10-alpha.13

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago