import * as UI from '../../src/index'

import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { action } from "@storybook/addon-actions";

<Meta title="Tabs" />

export const loadTurtleDecorator = (Story) => {
  const { render, data } = Story();
  $rdf.parse(data, SolidLogic.store, location.origin, "text/turtle", (error) => {
    if (error) console.error(error);
  });
  const div = document.createElement("div");
  const pre = document.createElement("pre");
  pre.appendChild(document.createTextNode(data));
  div.appendChild(pre);
  div.appendChild(render());
  return div;
};

## tabWidget: Populating content using an RDF collection

In this first example we'll see how you can generate a tabs widget using triples that are formatted as a collection in
RDF. See [API docs](https://solidos.github.io/solid-ui/docs/api/modules/_tabs_.html#tabwidget) for more
info about how to use the tabWidget.

The triples belows shows the minimum data you need to start using the tabWidget in combination with store.

<Canvas>
  <Story name="rdf collection" decorators={[loadTurtleDecorator]}>
    {() => {
      const subject = $rdf.namedNode(location.origin + "#subject1");
      const predicate = $rdf.namedNode(location.origin + "#predicate1");
      return {
        data: `
@prefix : <#> .
:subject1
    :predicate1 ( :item1A :item1B ) .
        `,
        render: () =>
          UI.tabs.tabWidget({
            subject,
            predicate,
            renderMain: (bodyMain, subject) => {
              bodyMain.innerText = `Content of ${subject.uri}`;
            },
          }),
      };
    }}
  </Story>
</Canvas>

Note that you would probably use `$rdf.namedNode` directly from rdflib.js. (E.g. instead of
`$rdf.namedNode` you would probably make use of namedNode with
`import { namedNode } from 'rdflib'`.

## tabWidget: Populating content using unsorted triples

In this second example we'll use an unsorted set of triples instead of a collection.

This is the data we will be working with. Note that we've also added labels to the items to help the widget know how to label the tabs.

Note that we've set option ordered to false in this example.

<Canvas>
  <Story name="unsorted triples" decorators={[loadTurtleDecorator]}>
    {() => {
      const subject = $rdf.namedNode(location.origin + "#subject2");
      const predicate = $rdf.namedNode(location.origin + "#predicate2");
      return {
        data: `
@prefix :     <#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:subject2
    :predicate2 :item2A, :item2B .
:item2A
    rdfs:label "Tab 1" .
:item2B
    rdfs:label "Tab 2" .
        `,
        render: () =>
          UI.tabs.tabWidget({
            subject,
            predicate,
            ordered: false,
            renderMain: (bodyMain, subject) => {
              bodyMain.innerText = `Content of ${UI.utils.label(subject)}`;
            },
          }),
      };
    }}
  </Story>
</Canvas>

## tabWidget: Populating content using option items

Finally we can set the items manually by using option items.

We do not need to use options subject and predicate when using items.

<Canvas>
  <Story name="option items">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
      });
    }}
  </Story>
</Canvas>

ℹ For the remaining examples we'll use option items to populate our tabs.

## tabWidget: Option backgroundColor

Using option `backgroundColor` we can set a specific color (in hex value) to our tabs. It will consider how light a
color is when figuring out which color to set to the text. It will also distinguish between selected and not selected
tabs by coloring the selected tab a bit darker.

<Canvas>
  <Story
    name="background color"
    args={{ backgroundColor: "#ff0000" }}
    argTypes={{
      backgroundColor: { control: { type: "select", options: ["#ff0000", "#00ff00", "#0000ff"] } },
    }}
  >
    {({ backgroundColor }) => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        backgroundColor,
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option onClose

<Canvas>
  <Story name="on close">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        onClose: action("closed"),
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option orientation

Using option `orientation` we can set how the tabs and body should be positioned.

<Canvas>
  <Story
    name="orientation"
    args={{ orientation: "1" }}
    argTypes={{ orientation: { control: { type: "select", options: ["0", "1", "2", "3"] } } }}
  >
    {({ orientation }) => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        orientation,
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option renderTab

`renderTab` allows us to override the default behavior for how tabs are rendered, e.g. which text should be shown for each tab.

<Canvas>
  <Story name="renderTab">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
        renderTab: (tabDiv, subject) => {
          tabDiv.innerText = `Go to ${subject.uri}`;
        },
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option renderTabSettings

`renderTabSettings` functions much like `renderMain`, expect that it is triggered by holding ALT key (Option key on Mac
) and clicking on a tab.

<Canvas>
  <Story name="renderTabSettings">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
        renderTabSettings: (bodyMain, subject) => {
          bodyMain.innerText = `Settings for ${subject.uri}`;
        },
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option selectedTab

`selectedTab` allows you to set which tab should be opened by when the widget is initially rendered. It must be used
in junction with `renderTab` since it relies on `dataset.name` being set.

<Canvas>
  <Story name="selectedTab">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        items: [item1, item2],
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
        renderTab: (tabDiv, subject) => {
          tabDiv.dataset.name = subject.uri;
          tabDiv.innerText = UI.utils.label(subject);
        },
        selectedTab: item2.uri,
      });
    }}
  </Story>
</Canvas>

## tabWidget: Option startEmpty

`startEmpty` makes it so that the body of a tab isn't shown when initially rendered.

<Canvas>
  <Story name="startEmpty">
    {() => {
      const item1 = $rdf.namedNode(location.origin + "#item3A");
      const item2 = $rdf.namedNode(location.origin + "#item3B");
      return UI.tabs.tabWidget({
        items: [item1, item2],
        startEmpty: true,
        renderMain: (bodyMain, subject) => {
          bodyMain.innerText = `Content of ${subject}`;
        },
      });
    }}
  </Story>
</Canvas>
