{/* prettier-ignore */}
{/*
Copyright 2023 Comcast Cable Communications Management, LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache-2.0
\*/}

import { Meta } from '@storybook/blocks';

<Meta title="Docs/Storybook Structure" />

# LUI Storybook Code Organization

`apps/lightning-ui-docs/.storybook`

| Folder            |          File           | Purpose                                                           |
| ----------------- | :---------------------: | :---------------------------------------------------------------- |
| addons            |                         |                                                                   |
|                   |      constants.js       | constants for addons                                              |
| addons/components |                         |                                                                   |
|                   |        index.js         |                                                                   |
|                   |      NumberRow.js       |                                                                   |
|                   |        Table.js         |                                                                   |
|                   |       TableRow.js       |                                                                   |
| addons/decorators |                         |                                                                   |
|                   |    withLightning.js     | decorator for Lightning to work in Storybook                      |
| addons/panels     |                         |                                                                   |
|                   | ComponentStylesPanel.js | Lightning Custom Component Style Panel                            |
|                   |   GridOverlayPanel.js   | Lighting Custom Grid Overlay Panel                                |
|                   |      ThemePanel.js      | Lightning Custom Theme Panel                                      |
| addons/toolbars   |                         |                                                                   |
|                   |       Announce.js       | turn on Announce feature                                          |
|                   |      StageColor.js      | stage color toggle                                                |
|                   |    ThemeDownload.js     | download a theme                                                  |
|                   |     ThemePicker.js      | select a theme                                                    |
| utils             |                         |                                                                   |
|                   |       helpers.js        | helper functions for Storybook config                             |
|                   |    registerEvent.js     | event listeners for Storybook config                              |
|                   |      themeUtils.js      | utility functions for Lightning Theming to work in Storybook      |
| /                 |                         |                                                                   |
|                   |        brand.png        | Lightning logo for Storybook theme                                |
|                   |         main.js         | controls server behavior                                          |
|                   |    manager-head.html    |                                                                   |
|                   |        manger.js        | sets Storybook UI options and themes, and registers custom addons |
|                   |    preview-head.html    |                                                                   |
|                   |       preview.js        | controls rendering of stories                                     |
|                   |        theme.js         | theme for Storybook UI                                            |

### useArgs

There may be cases throughout our Stories where we want one control to affect the value of another control, or a user interaction with the component to update the value of a control.

This can be achieved through Storybook's `useArgs` hook and `updateArgs` method. For more information, check out the documentation [here](https://storybook.js.org/docs/vue/addons/addons-api#useargs).

`useArgs` is a hook that is a part of the Storybook API that allows **args** to be read or updated.

Specifically, `useArgs` has a method called `updateArgs` that can be used to update an arg when it changes value.

Below is an example of how to use `updateArgs` along with the value property:

```js
import { useArgs } from '@storybook/client-api';

const [{ value }, updateArgs] = useArgs();

// update arg control when value changes
onChange(value) {
  updateArgs({ value });
}
```

For example, in our [Slider component](?path=/docs/components-slider--docs), when in the `focused` mode, if a user hits left or right on their keyboard, the value of the Slider changes accordingly. However, the Storybook control for the current `value` never updates. This puts the component and the control out of sync. The next time the user updates a control, the value will be reapplied, wiping out whatever was set via the keyboard interaction.

To keep the Slider control in sync, we used the `updateArgs` method. In Slider.js, the component emits a signal called "onChange" whenever its value is updated:

```js
this.signal('onChange', this.value, this);
```

In Slider.stories.js, our component intercepts the signal:

```js
Slider: {
  type: Slider,
  value: value,
  signals: {
    onChange: true
  }
}
```

That signal gets mapped to a new method local to our story that then calls the `updateArgs` method

```js
onChange(value) {
  updateArgs({ value })
}
```

This `updateArgs` method is what then updates the value control in Storybook to match the value of the component (the one set by the user when hitting left and right).
