import { Meta } from "@storybook/addon-docs";

<Meta title="Pages/Overview" />

# Glisser Elements - React Component Library

<br />

> Glisser Elements is a virtual events SDK, based on Glisser's award-winning tech platform, that allows enterprises and their agencies to create bespoke virtual and hybrid events experiences using Glisser's highly-developed components, inside their own websites. Learn more about [Glisser here](https://glisser.com) and about [Glisser Elements here](https://elements.glisser.com).

_Note:_ you need a Glisser account to use the Elements. [Sign up for free here](https://present.glisser.com/join).

<br />
<br />

### Navigate

- [How To User Glisser Elements](#how-to-use-glisser-elements)
- [Customising Elements](#customising-elements)
- [Migrating From An Earlier Version](#migrating-from-an-earlier-version)
- [Support](#support)

</br>
</br>

## How To Use Glisser Elements

<br />

### Step 1: Scaffolding Your Project

If you need help setting up a React application, [we have a guide available](/docs/integration-react--page).

<br />

### Step 2: Installation

Run the following command to install the Glisser React package:

```js
npm install @glisser/react

// or

yarn add @glisser/react
```

<br />

### Step 3: Setting-up Glisser Elements

To use Glisser Elements in your app, you first need to ensure you import the `GlsrProvider` component and `useSession` hook.

`GlsrProvider` is a wrapper for all Glisser Elements and is an instantiation of the [React Context API](https://beta.reactjs.org/apis/react/createContext).

`useSession` is a [custom hook](https://reactjs.org/docs/hooks-custom.html) used by Glisser Elements as the central source of truth for all session related state.

```js
import { GlsrProvider, useSession } from '@glisser/react'

const App = () => {
  const [session, setSession] = useSession({ code: '' })

  return (
    <GlsrProvider session={session} setSession={setSession}>
      // glisser elements
    </GlsrProvider>
  )
}

export default App
```

<br />

### Step 4: Adding Glisser Elements

Once you have the above set-up, you're ready to start importing and utilising Glisser Elements into your app:

| Component     | Props                    | Type              | Default | Description                                                                                       |
| ------------- | ------------------------ | ----------------- | ------- | ------------------------------------------------------------------------------------------------- |
| SlideFeed     | `area`                   | `main` \| `tabs`  | `main`  | TBC                                                                                               |
|               | `boarding`               | `boolean`         | `false` | Setting the value to `true` will cause this component to render the on-boarding form              |
|               | `debug`                  | `boolean`         | `false` | TBC                                                                                               |
|               | `streamComponent`        | `React.ReactNode` |         | Pass in an instance of the `<Stream />` component to allow toggling between slide and stream view |
| SlideTab\*\*  |                          |                   |         |                                                                                                   |
| AttendeeList  | `boarding`               | `boolean`         | `false` | Setting the value to `true` will cause this component to render the on-boarding form              |
|               | Optional `debug`         | `boolean`         |         | TBC                                                                                               |
| CommentFeed   | `boarding`               | `boolean`         | `false` | Setting the value to `true` will cause this component to render the on-boarding form              |
|               | Optional `debug`         | `boolean`         |         | TBC                                                                                               |
| Download\*\*  | Optional `displayHeader` | `boolean`         |         |                                                                                                   |
| NoteFeed\*\*  | Optional `displayHeader` | `boolean`         |         |                                                                                                   |
| Related\*\*   | Optional `displayHeader` | `boolean`         |         |                                                                                                   |
|               | Optional `inline`        | `boolean`         |         |                                                                                                   |
|               | `showMenu`               | `boolean`         | `false` |                                                                                                   |
| Social\*\*    | TBC                      |                   |         |                                                                                                   |
| Stream\*\*    | Optional `stream`        | TBC               |         |                                                                                                   |
|               | Optional `provider`      | TBC               |         |                                                                                                   |
| Subtitles\*\* |                          |                   |         |                                                                                                   |

<br />

\*\*_`SlideTab`, `Download`, `NoteFeed`, `Related`, `Social`, `Stream` and `Subtitles` **cannot** be used on their own as they require either `SlideFeed`, `AttendeeList` and/or `CommentFeed` for the boarding process._

An object containing a key of `code` with a property of type `string` is also **required** (an empty string is OK) by the `useSession` hook:

<br />
<div style={{ display: "flex", alignItems: "center", gap: ".5rem" }}>
  <span style={{ fontSize: "1.5rem", color: "crimson" }}>&#9746;</span> Invalid
  Usage
</div>

```js
const [session, setSession] = useSession()

return (
  <GlsrProvider>
    <SlideTab />
    <Download />
  </GlsrProvider>
)
```

<div style={{ display: "flex", alignItems: "center", gap: ".5rem" }}>
  <span style={{ fontSize: "1.5rem", color: "seagreen" }}>&#9745;</span> Valid
  Usage
</div>

```js
const [session, setSession] = useSession({ code: '' })

return (
  <GlsrProvider session={session} setSession={setSession}>
    <SlideFeed boarding={true} />
    <NoteFeed />
    <Download />
  </GlsrProvider>
)
```

<br />

### Boarding property

Note that `<SlideFeed />` has a `boarding` prop set to `true` which will load the event boarding process inside this particular component. This prop can be alternatively used with `<CommentFeed />`.

<br />

### Silent login

When adding a Glisser element, it is possible to onboard the attendee silently. This creates a seamless experience for the attendee in which they will not be prompted for a Glisser code or for their identifier (email/uniqueID etc.).
In order to do this, arguments can be passed as an object for `useSession()` which are `code`, `identifier`, and `profile`. Here's an example:

```js
const [session, setSession] = useSession({
  code: 'event-code',
  identifier: 'email@email.com',
  profile: {
    firstName: 'User first name',
    lastName: 'User last name',
    company: 'Company name',
    linkedinUrl: 'https://linkedin.com/',
    location: 'City, State, Country',
  },
})
```

Note that `profile` is only needed if intending to use Glisser's Named Q&A and Attendee List features.

<br />

## Specifications

The Elements are quite flexible in size but it's recommended to keep it not smaller than 350px both width and height.

<br />

## Quick Start

Below is a basic Glisser session layout to easily copy and paste into your app to test:

<br />

```js
import './App.css'
import {
  useSession,
  GlsrProvider,
  SlideFeed,
  SlideTab,
  Download,
} from '@glisser/react-dev'

function App() {
  const [session, setSession] = useSession({ code: 'my-code' })

  const styles = {
    main: {
      display: 'grid',
      gridTemplateColumns: '1fr auto',
      gridTemplateRows: '1fr auto',
      gap: '1rem',
      backgroundColor: '#111',
      padding: '2rem',
    },
    slide: { width: '800px' },
    slideTab: { width: '100%', height: '100%', gridRow: '1 / 3' },
    download: { justifySelf: 'flex-start' },
  }

  return (
    <main style={styles.main}>
      <GlsrProvider session={session} setSession={setSession}>
        <div style={styles.slide}>
          <SlideFeed boarding={true} />
        </div>
        <div style={styles.slideTab}>
          <SlideTab />
        </div>
        <div style={styles.download}>
          <Download />
        </div>
      </GlsrProvider>
    </main>
  )
}

export default App
```

<br />

## Customising Elements

A large number of HTML class attributes are exposed throughout Glisser Elements (with more being added as the project evolves). The current list contains the following classes:

<br />

| Component / Element    | Component Name          | Class Name (`glsr_`)                 | File                     | Notes                                      |
| ---------------------- | ----------------------- | ------------------------------------ | ------------------------ | ------------------------------------------ |
| Atom/Molecule/Organism | `BoardingContainer`     | `boarding-container`                 | `boarding-container.jsx` |                                            |
|                        | `BoardingInfoContainer` | `boarding-container__info-container` | `boarding-info.jsx`      |                                            |
|                        | `BoardingFormContainer` | `boarding-container__form-container` | `boarding-form.jsx`      |                                            |
|                        | `TextInputElement`      | `text-input`                         | `text-input.jsx`         |                                            |
|                        | `TextInputContainer`    | `text-input__container`              | `text-input.jsx`         |                                            |
|                        | `IconHolder`            | `text-input__icon-container`         | `text-input.jsx`         |                                            |
|                        | `LinkLargeIcon`         | `text-input__icon`                   | `text-input.jsx`         |                                            |
|                        | `ButtonBaseContainer`   | `btn`                                | `button-base.jsx`        |                                            |
|                        | `ButtonBaseContainer`   | `btn--primary`                       | `button-base.jsx`        |                                            |
|                        | `ButtonBaseContainer`   | `btn--{ type }`                      | `button-base.jsx`        |                                            |
|                        | `SlideTabContainer`     | `slide-tab__container`               | `slide-tab.jsx`          |                                            |
|                        | `ContentGridContainer`  | `slide-tab__grid`                    | `slide-tab.jsx`          |                                            |
|                        | `SlideThumbContainer`   | `slide-tab__thumb`                   | `slide-tab.jsx`          |                                            |
|                        | `RelatedBody`           | `related`                            | `related.jsx`            |                                            |
|                        | `RelatedHeader`         | `related__header`                    | `related-body.jsx`       |                                            |
|                        | `RelatedToggle`         | `related__toggle`                    | `related-body.jsx`       |                                            |
|                        | `InfoAlert`             | `related__info-alert`                | `related-body.jsx`       |                                            |
|                        | `RelatedLinkList`       | `related__link-list`                 | `related-links.jsx`      |                                            |
|                        | `RelatedLink`           | `related__link`                      | `related-links.jsx`      |                                            |
|                        | `ElementContainer`      | `notes`                              | `note-feed.jsx`          |                                            |
|                        | `NotesContainer`        | `notes__container`                   | `note-feed.jsx`          | `ge-slide-feed-wrapper` class still exists |
|                        | `Header`                | `notes__header`                      | `note-feed.jsx`          |                                            |
|                        | `NoteThumbsContainer`   | `notes__thumb-carousel`              | `note-thumbs.jsx`        |                                            |
|                        | `SlidesList`            | `notes__thumb-list`                  | `note-thumbs.jsx`        |                                            |
|                        | `SlidesListItem`        | `notes__thumb-list-item`             | `note-thumbs.jsx`        |                                            |
|                        | `SlideThumb`            | `notes__thumb`                       | `note-thumbs.jsx`        |                                            |
| `slide-feed`           | `ElementContainer`      | `slide-feed__wrapper`                | `slide-feed.jsx`         |                                            |
|                        | `SlideViewContainer`    | `slide-feed__view-container`         | `slide-feed.jsx`         |                                            |
|                        | `SlideContainer`        | `slide-feed__slide-container`        | `slide-feed.jsx`         | `ge-slide-feed class` still exists         |
|                        | `SlideViewInner`        | `slide-feed__view`                   | `slide-feed.jsx`         |                                            |
|                        | `SlideViewInner`        | `slide-feed__view--top`              | `slide-feed.jsx`         | Slides component                           |
|                        | `SlideViewInner`        | `slide-feed__view--bottom`           | `slide-feed.jsx`         | Stream component                           |
| `attendee-list`        | `ElementContainer`      | `attendee-list`                      | `attendee-list.jsx`      |                                            |
|                        | `SearchInput`           | `attendee-list__search`              | `attendee-list.jsx`      |                                            |
|                        | `AttendeeNavContainer`  | `attendee-list__nav`                 | `attendee-list.jsx`      |                                            |
|                        | `AttendeeNavContainer`  | `attendee-list__nav--no-attendees`   | `attendee-list.jsx`      |                                            |
|                        | `AttendeeCount`         | `attendee-list__nav-attendee-count`  | `attendee-list.jsx`      |                                            |
|                        | `AttendeePaging`        | `attendee-list__nav-attendee-paging` | `attendee-list.jsx`      |                                            |
|                        | `List`                  | `attendee-list__list`                | `attendee-list.jsx`      |                                            |
|                        | `User`                  | `attendee-list__user`                | `attendee-list.jsx`      |                                            |
|                        | `NoAttendeesContainer`  | `attendee-list__no-attendees`        | `attendee-list.jsx`      |                                            |
|                        | `Attendees`             | `attendee-list__attendees`           | `attendee-list.jsx`      |                                            |
| `comment-feed`         | `ElementContainer`      | `comment-feed`                       | `comment-feed.jsx`       |                                            |
|                        | `CommentsContainer`     | `comment-feed__container`            | `comment-feed.jsx`       |                                            |
|                        | `List`                  | `comment-list__attendee-list`        | `comment-list.jsx`       |                                            |
|                        | `CommentNav`            | `comment-list__comment-nav`          | `comment-list.jsx`       |                                            |
|                        | `TextTabsArea`          | `comment-list__text-area`            | `comment-list.jsx`       |                                            |
|                        | `ToggleSwitch`          | `comment-list__text-area-toggle`     | `comment-list.jsx`       |                                            |
|                        |                         |                                      |                          |                                            |

<br />

## Migrating From An Earlier Version

<br />

If you have been using elements, prior to the release of `1.0.2`, and wish to upgrade versions to the most current you will need to ensure you include the addition of the `GlsrProvider` into your application.

As outlined [above](#step-4-adding-glisser-elements) elements now require this context provider to share logic between themselves.

If you have an app which currently looks something like:

```js
function App() {
  const [session, setSession] = useSession()

  return (
    <main>
      <SlideFeed boarding={true} session={session} setSession={setSession} />
      <SlideTab session={session} setSession={setSession} />
      <Download session={session} setSession={setSession} />
    </main>
  )
}
```

it will now need to look something more like this:

```js
function App() {
  const [session, setSession] = useSession({ code: 'my-code' })

  return (
    <main>
      <GlsrProvider session={session} setSession={setSession}>
        <SlideFeed boarding={true} />
        <SlideTab />
        <Download />
      </GlsrProvider>
    </main>
  )
}
```

Just **make sure** than all Glisser Elements any any logic interacting with either the `session` or `setSession` values is wrapped within a **single instance** of this provider.

<br />

## Support

If you have any technical questions, please [go to our forum](https://forum.glisser.com/).

<br />
