[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/docs/README.md from the store-header VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/vtex-apps/store-header) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).
<!-- ALL-CONTRIBUTORS-BADGE:START - Don't remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

# Header

[<i class="fa-brands fa-github"></i> Source code](https://github.com/vtex-apps/store-header)

The Header app displays a navigation bar at the top of your store pages. It serves as the central hub for essential navigation elements, such as your store [logo](https://developers.vtex.com/docs/apps/vtex.store-components/logo), the [minicart](https://developers.vtex.com/docs/apps/vtex.minicart), user [login](https://developers.vtex.com/docs/apps/vtex.login), and the [search bar](https://developers.vtex.com/docs/apps/vtex.store-components/searchbar).

![header](https://user-images.githubusercontent.com/52087100/74090325-b6235d00-4a88-11ea-8227-317f93204d8f.png)

## Installation

1. Add the `store-header` app to your theme's dependencies in the `manifest.json` file:

```json
  dependencies: {
    "vtex.store-header": "2.x"
  }
```

You can now use all the blocks exported by the `store-header` app. The following table lists the available blocks:

| Block name | Description |
| --------  | ------------ |
| `header-layout.desktop` | ![https://img.shields.io/badge/-Mandatory-red](https://img.shields.io/badge/-Mandatory-red) Defines the Header layout for desktop devices through `header-row` blocks. |
| `header-layout.mobile`| Defines the Header layout for mobile devices through `header-row` blocks. |
| `header-row` | ![https://img.shields.io/badge/-Mandatory-red](https://img.shields.io/badge/-Mandatory-red) Create Header lines according to your store needs. |
| `header-border` | Adds a `1px` margin to a Header row. |
| `header-force-center` | Centralizes its children blocks in a Header row. |
| `header-spacer` | Adds spacing between blocks throughout a Header row. |

## Configuration

1. Declare the `header-layout.desktop` and `header-layout.mobile` blocks in your `header.jsonc` file. This allows you to define different header structures for desktop and mobile devices.

```json
{
  "header": {
    "blocks": [
      "header-layout.desktop",
      "header-layout.mobile"
    ]
  },
```

>ℹ The Header is a default store interface element defined in the `interfaces.json` file, so you don't need to declare it in every template. Store Framework automatically applies your configuration across all store pages. To customize the header for specific pages, see the [Advanced configuration](#advanced-configuration) section.

2. In your `header.jsonc` file, define `header-row` blocks inside `header-layout.desktop` and `header-layout.mobile`. The number of rows depends on your store design.

```json
{
  "header": {
    "blocks": [
      "header-layout.desktop",
      "header-layout.mobile"
    ]
  },
  "header-layout.desktop": {
    "children": [
      "header-row#1-desktop",
      "header-row#2-desktop",
      "header-row#3-desktop",
      "header-row#4-desktop"
    ]
  },
```

>⚠ The example above uses four rows for the desktop header. This setup allows replicating the header to include telemarketing functionalities (when activated), notifications, page links, and other blocks, such as a logo and menu.

3. Configure each `header-row` by adding props and declaring the desired blocks as children. The most commonly used blocks are [Logo](https://developers.vtex.com/docs/apps/vtex.store-components/logo), [Minicart](https://developers.vtex.com/docs/apps/vtex.minicart), and [Menu](https://developers.vtex.com/docs/apps/vtex.menu).

In the example below, we'll add a [Telemarketing](https://developers.vtex.com/docs/apps/vtex.telemarketing) bar to the first row:

```json
"header-row#1-desktop": {
  "children": [
    "telemarketing"
  ],
  "props": {
    "fullWidth": true
  }
},
```

- `header-row` props:

| Prop name  | Type      | Description                                                                                | Default value |
| ---------- | --------- | ------------------------------------------------------------------------------------ | ------------- |
| `zIndex` | `Number` | Controls the vertical stacking order of elements for overlapping.                                                                      | `0`         |
| `sticky` | `Boolean` | Determines if the header row remains fixed at the top of the screen during scroll (true) or not (false).                                                                  | `false`          |
| `fullWidth` | `Boolean` | Determines if the header row should span the full width of the screen.                                                                  | `true`          |
| `inverted` | `Boolean` | If true, the row uses the inverted base color defined in styles.json.                                                                  | `false`          |

⚠ Repeat this process for all `header-row` blocks in both `header-layout.desktop` and `header-layout.mobile`, configuring each block with the necessary props.

### Layout customization blocks

You can use the `header-border`, `header-force-center`, and `header-spacer` blocks as children of `header-row` to customize your header layout.

- **`header-border`**

Adds a `1px` margin to a header row.

```json
"header-row#2-desktop": {
  "children": [
    "header-border",
    "notification.bar#home"
  ],
  "props": {
    "fullWidth": "true"
  }
},
"notification.bar#home": {
  "props": {
    "content": "SELECTED ITEMS ON SALE! CHECK IT OUT!"
  }
},
```

- **`header-force-center`**

Centralizes its child blocks within a header row.

```json
"header-row#4-desktop": {
  "props": {
    "blockClass": "main-header",
    "horizontalAlign": "center",
    "verticalAlign": "center",
    "preventHorizontalStretch": true,
    "preventVerticalStretch": true,
    "fullWidth": true
  },
  "children": ["header-force-center"]
},
"header-force-center": {
  "children":[
    "logo#desktop"
  ]
},
"logo#desktop": {
  "props": {
    "title": "Logo",
    "href": "/",
    "url": "https://storecomponents.vteximg.com.br/arquivos/store-theme-logo.png",
    "width": "180"
  }
},
```

- **`header-spacer`**:

Adds a flexible space between blocks in a header row. Blocks declared before `header-spacer` are pushed to the left, and blocks declared after are pushed to the right.

```json
"header-row#3-desktop": {
  "children": [
    "vtex.menu@2.x:menu#websites",
    "header-spacer",
    "vtex.menu@2.x:menu#institutional"
  ],
  "props": {
    "blockClass": "menu-link",
    "inverted": "true"
  }
},
```

### Advanced configuration

By default, the header configuration is applied to all store templates. To override this behavior and apply custom configurations to different templates, you can modify the `interfaces.json` file.

For detailed instructions, see the guide [Customizing the Header and Footer blocks by page](https://developers.vtex.com/docs/guides/vtex-io-documentation-customizing-the-header-and-footer-blocks-by-page).

## Customization

To apply CSS customizations to these and other blocks, follow the instructions in [Using CSS Handles for store customization](https://developers.vtex.com/docs/guides/vtex-io-documentation-using-css-handles-for-store-customization).

| CSS Handles          |
|----------------------|
| `container`          |
| `leanMode`           |
| `topMenuContainer`   |
| `topMenuLogo`        |
| `topMenuSearchBar`   |
| `topMenuIcons`       |
| `topMenuCollapsible` |
| `forceCenter`        |
| `forceCenterInnerContainer` |
| `headerBorder` |
| `headerSpacer` |
| `headerStickyRow` |
| `headerRowContentContainer` |

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/index.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React, { Suspense } from 'react'
import { useChildBlock, NoSSR } from 'vtex.render-runtime'

import CustomHeader from './components/CustomHeader'

const LegacyHeader = React.lazy(() => import('./legacy'))

function Header(props: PropsWithChildren<unknown>) {
  const hasHeaderDesktop = !!useChildBlock({
    id: 'header-layout.desktop',
  })

  const hasUnstableHeaderDesktop = !!useChildBlock({
    id: 'unstable--header-layout.desktop',
  })

  const hasHeaderMobile = !!useChildBlock({
    id: 'header-layout.mobile',
  })

  const hasUnstableHeaderMobile = !!useChildBlock({
    id: 'unstable--header-layout.mobile',
  })

  const hasCustomHeader =
    hasHeaderDesktop ||
    hasHeaderMobile ||
    hasUnstableHeaderDesktop ||
    hasUnstableHeaderMobile

  return hasCustomHeader ? (
    <CustomHeader {...props} />
  ) : (
    <NoSSR>
      <Suspense fallback={<div />}>
        <LegacyHeader {...props} />
      </Suspense>
    </NoSSR>
  )
}

// @ts-expect-error - legacy code
Header.schema = LegacyHeader.schema

export default Header

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/Border.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { useCssHandles } from 'vtex.css-handles'

import StickyRow from './components/StickyRow'

const CSS_HANDLES = ['headerBorder'] as const

interface Props {
  /**
   * Define if the element behaves in a sticky manner
   * @default false
   * */
  sticky: boolean
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * @deprecated Use 'vtex.sticky-layout' instead
 */
function Border({ sticky, classes }: PropsWithChildren<Props>) {
  const { handles } = useCssHandles(CSS_HANDLES, {
    classes,
  })

  return (
    <StickyRow sticky={sticky}>
      <div className={`${handles.headerBorder} bb b--muted-3`} />
    </StickyRow>
  )
}

export default Border

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/Spacer.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { useCssHandles } from 'vtex.css-handles'

const CSS_HANDLES = ['headerSpacer'] as const

interface Props {
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * @deprecated Use a simple inline element instead
 */
function Spacer({ classes }: PropsWithChildren<Props>) {
  const { handles } = useCssHandles(CSS_HANDLES, {
    classes,
  })

  return <div className={`${handles.headerSpacer} flex flex-grow-1`} />
}

export default Spacer

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/ForceCenter.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { useCssHandles } from 'vtex.css-handles'

const CSS_HANDLES = ['forceCenter', 'forceCenterInnerContainer'] as const

interface Props {
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * @deprecated Use `vtex.sticky-layout` and inline elements instead.
 */
function ForceCenter({ children, classes }: PropsWithChildren<Props>) {
  const { handles } = useCssHandles(CSS_HANDLES, {
    classes,
  })

  return (
    <div
      className={`${handles.forceCenter} absolute left-0 right-0 flex justify-center z-1`}
      style={{ pointerEvents: 'none' }}
    >
      <div
        className={handles.forceCenterInnerContainer}
        style={{ pointerEvents: 'all' }}
      >
        {children}
      </div>
    </div>
  )
}

export default ForceCenter

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/package.json from the store-header VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "version": "2.29.2",
  "name": "vtex.header",
  "description": "A Header Component.",
  "license": "ISC",
  "scripts": {
    "pretest": "yarn",
    "test": "vtex-test-tools test",
    "test:coverage": "vtex-test-tools test --collectCoverage",
    "gen:coveralls": "yarn test:coverage  && cat ./coverage/lcov.info | coveralls",
    "lint": "tsc --noEmit && eslint --ext ts,tsx ."
  },
  "devDependencies": {
    "@types/classnames": "^2.2.7",
    "@vtex/test-tools": "^0.1.3",
    "apollo-client": "^2.5.1",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@1.0.0/public/@types/vtex.css-handles",
    "vtex.category-menu": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.category-menu@2.15.0/public/_types/react",
    "vtex.device-detector": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.device-detector@0.2.5/public/@types/vtex.device-detector",
    "vtex.locale-switcher": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.locale-switcher@0.5.5/public/@types/vtex.locale-switcher",
    "vtex.login": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.login@2.39.1/public/_types/react",
    "vtex.menu": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.menu@2.27.0/public/@types/vtex.menu",
    "vtex.minicart": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.minicart@2.54.2/public/@types/vtex.minicart",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.126.4/public/@types/vtex.render-runtime",
    "vtex.rich-text": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.rich-text@0.11.2/public/@types/vtex.rich-text",
    "vtex.sandbox": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.sandbox@0.5.0/public/@types/vtex.sandbox",
    "vtex.store-components": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-components@3.136.2/public/@types/vtex.store-components",
    "vtex.store-drawer": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-drawer@0.15.0/public/@types/vtex.store-drawer",
    "vtex.store-icons": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-icons@0.18.0/public/@types/vtex.store-icons",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.134.0/public/@types/vtex.styleguide",
    "vtex.telemarketing": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.telemarketing@2.10.2/public/@types/vtex.telemarketing"
  },
  "dependencies": {
    "@types/react-resize-detector": "^3.1.1",
    "classnames": "^2.2.6",
    "debounce": "^1.2.0",
    "hoist-non-react-statics": "^3.0.1",
    "react": "^16.3.2",
    "react-adopt": "^0.6.0",
    "react-dom": "^16.3.2",
    "react-intl": "^2.4.0",
    "react-media": "^1.9.2",
    "react-resize-detector": "^4.0.5",
    "react-spring": "^8.0.7",
    "throttleit": "^1.0.0"
  },
  "vtexScriptsOverride": {
    "srcPath": "."
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/Layout.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'

import StickyRows from './components/StickyRows'

/**
 * @deprecated Use the `vtex.sticky-layout` app instead
 */
// eslint-disable-next-line @typescript-eslint/ban-types
function Layout({ children }: PropsWithChildren<{}>) {
  return <StickyRows>{children}</StickyRows>
}

export default Layout

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/Row.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'
import classNames from 'classnames'
import { Container } from 'vtex.store-components'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { useCssHandles } from 'vtex.css-handles'

import StickyRow from './components/StickyRow'

const CSS_HANDLES = [
  'headerRowContainer',
  'headerRow',
  'headerRowBackground',
  'headerRowContentContainer',
] as const

interface Props {
  /**
   * Define if the row behaves in a sticky manner
   * @default false
   * */
  sticky?: boolean
  zIndex?: number
  /**
   * Define if the element takes the full width of its container
   * @default false
   * */
  fullWidth?: boolean
  /**
   * Define if the row should have inverted background and text colors
   * @default false
   * */
  inverted?: boolean
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * @deprecated Use the `vtex.sticky-layout` app instead.
 */
function Row({
  children,
  sticky,
  zIndex,
  fullWidth,
  inverted,
  classes,
}: PropsWithChildren<Props>) {
  const { handles } = useCssHandles(CSS_HANDLES, {
    classes,
  })

  const content = (
    <div className={`${handles.headerRowContainer} w-100 flex items-center`}>
      {children}
    </div>
  )

  return (
    <StickyRow sticky={sticky} zIndex={zIndex}>
      <div className={handles.headerRow}>
        <div
          className={classNames(
            `${handles.headerRowBackground} w-100`,
            inverted
              ? 'bg-base--inverted c-on-base--inverted'
              : 'bg-base c-on-base'
          )}
        >
          {fullWidth ? (
            content
          ) : (
            <Container
              className={`${handles.headerRowContentContainer} w-100 flex`}
            >
              {content}
            </Container>
          )}
        </div>
      </div>
    </StickyRow>
  )
}

export default Row

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/store/blocks.json from the store-header VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "header": {
    "blocks": ["telemarketing", "logo"]
  },
  "header.full": {
    "blocks": ["header-layout.desktop", "header-layout.mobile"]
  },
  "header-layout.desktop": {
    "children": ["header-row#desktop-1", "header-row#desktop-2"]
  },
  "header-row#desktop-1": {
    "children": ["telemarketing"],
    "props": {
      "fullWidth": true
    }
  },
  "header-row#desktop-2": {
    "children": [
      "logo#header",
      "header-spacer",
      "search-bar",
      "login",
      "minicart"
    ],
    "props": {
      "sticky": true
    }
  },
  "header-row#desktop-3": {
    "children": ["category-menu"]
  },
  "header-layout.mobile": {
    "children": ["header-row#mobile-2"]
  },
  "header-row#mobile-1": {
    "children": ["telemarketing"],
    "props": {
      "fullWidth": true,
      "sticky": true
    }
  },
  "header-row#mobile-2": {
    "children": [
      "logo#header",
      "header-spacer",
      "login#header-mobile",
      "minicart"
    ],
    "props": {
      "sticky": true
    }
  },
  "login#header-mobile": {
    "props": {
      "showIconProfile": true
    }
  },
  "logo#header": {
    "props": {
      "width": 132,
      "height": 32,
      "mobileWidth": 90,
      "mobileHeight": 32
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/store/interfaces.json from the store-header VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "header": {
    "allowed": [
      "minicart",
      "minicart-base-content",
      "login",
      "category-menu",
      "search-bar",
      "locale-switcher",
      "theme",
      "user-address",
      "menu",
      "unstable--menu",
      "menu-link",
      "telemarketing",
      "logo",
      "sandbox",
      "header-layout.desktop",
      "header-layout.mobile",
      "header-layout.desktop-scroll",
      "header-layout.mobile-scroll",
      "unstable--header-layout.desktop",
      "unstable--header-layout.mobile",
      "unstable--header-layout.desktop-scroll",
      "unstable--header-layout.mobile-scroll"
    ],
    "component": "index"
  },
  "header.full": {},
  "header-layout": {
    "allowed": ["header-row", "header-border"],
    "component": "Layout",
    "composition": "children"
  },
  "header-layout.desktop": {
    "device": "desktop"
  },
  "header-layout.mobile": {
    "device": "mobile"
  },
  "header-layout.desktop-scroll": {},
  "header-layout.mobile-scroll": {},
  "header-spacer": {
    "component": "Spacer"
  },
  "header-row": {
    "allowed": [
      "telemarketing",
      "notification",
      "logo",
      "minicart",
      "minicart-base-content",
      "sandbox",
      "login",
      "search-bar",
      "locale-switcher",
      "menu-link",
      "category-menu",
      "menu",
      "unstable--menu",
      "theme",
      "user-address",
      "header-spacer",
      "rich-text",
      "drawer",
      "header-force-center"
    ],
    "component": "Row",
    "composition": "children"
  },
  "header-border": {
    "component": "Border"
  },
  "theme": {},

  "unstable--header-layout": {
    "allowed": ["unstable--header-row", "unstable--header-border"],
    "component": "Layout",
    "composition": "children"
  },
  "unstable--header-layout.desktop": {
    "device": "desktop"
  },
  "unstable--header-layout.mobile": {
    "device": "mobile"
  },
  "unstable--header-layout.desktop-scroll": {
    "device": "desktop"
  },
  "unstable--header-layout.mobile-scroll": {
    "device": "mobile"
  },
  "_": {
    "component": "Spacer"
  },
  "unstable--header-row": {
    "allowed": [
      "telemarketing",
      "logo",
      "minicart",
      "login",
      "search-bar",
      "locale-switcher",
      "menu-link",
      "category-menu",
      "menu",
      "unstable--menu",
      "theme",
      "user-address",
      "_"
    ],
    "component": "Row",
    "composition": "children"
  },
  "unstable--header-border": {
    "component": "Border"
  },
  "header-force-center": {
    "component": "ForceCenter",
    "composition": "children",
    "allowed": "*"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/index.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment, useEffect, useState } from 'react'
import classNames from 'classnames'
import PropTypes from 'prop-types'
import { ExtensionPoint, useRuntime } from 'vtex.render-runtime'
import TopMenu from './components/TopMenu'
import Spacer from './components/Helpers/Spacer'
import { logo, collapsible, icons, searchBar, login } from './defaults'

import styles from './store-header.css'
import useDevice from './hooks/useDevice'

/**
 * Main header component
 */
const Header = ({
  leanWhen,
  linkUrl,
  logoUrl,
  logoTitle,
  logoSize,
  showSearchBar,
  showLogin,
  iconClasses,
  labelClasses,
  collapsibleAnimation,
}) => {
  const { page, getSettings } = useRuntime()
  const { mobile } = useDevice()
  const [containerHeight, setContainerHeight] = useState(null)
  const { storeName } = getSettings('vtex.store')

  useEffect(() => {
    if (document) {
      const containerElement = document.querySelector(
        '.vtex-store-header-2-x-container'
      )
      const elementHeight = containerElement && containerElement.offsetHeight
      setContainerHeight(elementHeight)
    }
  })

  const topMenuOptions = {
    linkUrl,
    logoUrl,
    logoTitle: logoTitle || storeName || '',
    logoSize,
    showSearchBar,
    showLogin,
    iconClasses,
    labelClasses,
    collapsibleAnimation,
    mobile,
  }

  const isLeanMode = () => {
    const acceptedPaths = new RegExp(leanWhen)
    return acceptedPaths.test(page)
  }

  const containerClasses = classNames(
    styles.container,
    'fixed top-0 z-4 w-100',
    isLeanMode() ? styles.leanMode : ''
  )

  return (
    <Fragment>
      <div className={containerClasses}>
        <TopMenu
          {...topMenuOptions}
          leanMode={isLeanMode()}
          extraHeaders={
            <div
              className="left-0 w-100"
              style={{
                transform: 'translateZ(0)', //Avoid shaking
              }}
            >
              <ExtensionPoint id="telemarketing" />
              <ExtensionPoint id="menu-link" />
            </div>
          }
        />
      </div>
      <Spacer containerHeight={containerHeight} />
    </Fragment>
  )
}

Header.propTypes = {
  /** Cases in which the menu is in lean mode */
  leanWhen: PropTypes.string,
  ...login.propTypes,
  ...searchBar.propTypes,
  ...icons.propTypes,
  ...logo.propTypes,
  ...collapsible.propTypes,
}

Header.defaultProps = {
  leanWhen: 'a^',
  ...login.defaultProps,
  ...searchBar.defaultProps,
  ...icons.defaultProps,
  ...logo.defaultProps,
  ...collapsible.defaultProps,
}

Header.schema = {
  title: 'admin/editor.header.title',
  description: 'admin/editor.header.description',
  type: 'object',
  properties: {
    logoUrl: {
      type: 'string',
      title: 'admin/editor.header.logo.image',
      widget: {
        'ui:widget': 'image-uploader',
      },
    },
    linkUrl: {
      type: 'string',
      title: 'admin/editor.header.link.url',
    },
    showSearchBar: {
      title: 'admin/editor.header.show.searchbar.title',
      type: 'boolean',
      default: true,
      isLayout: true,
    },
    showLogin: {
      title: 'admin/editor.header.show.login.title',
      type: 'boolean',
      default: true,
      isLayout: true,
    },
  },
}

export default Header

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/store-header.css from the store-header VTEX app.

[Assistant]
Here's the implementation:

```css
.logoLink {
  font-size: 0px;
}

.container {
}
.leanMode {
}

.topMenuLogo {
}
.topMenuSearchBar {
}
.topMenuIcons {
}
.topMenuContainer {
}

.topMenuCollapsible {
}

.topMenuCompatibilityContainer {
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/defaults.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'

export const lean = {
  propTypes: {
    /** If it is leanMode or not */
    leanMode: PropTypes.bool,
  },
  defaultProps: {
    leanMode: false,
  },
}

export const logo = {
  propTypes: {
    /** Address opened when the user clicks the logo */
    linkUrl: PropTypes.string,
    /** URL of the logo image */
    logoUrl: PropTypes.string,
    /** Alt text for the logo */
    logoTitle: PropTypes.string,
    /** Size of the logo */
    logoSize: PropTypes.shape({
      /** Size on desktop */
      desktop: PropTypes.shape({
        width: PropTypes.number,
        height: PropTypes.number,
      }),
      /** Size on mobile */
      mobile: PropTypes.shape({
        width: PropTypes.number,
        height: PropTypes.number,
      }),
    }),
  },
  defaultProps: {
    linkUrl: '/',
    logoUrl: '',
    logoSize: {
      desktop: {
        width: 132,
        height: 40,
      },
      mobile: {
        width: 90,
        height: 40,
      },
    },
  },
}

export const searchBar = {
  propTypes: {
    /** Sets whether the search bar is visible or not */
    showSearchBar: PropTypes.bool,
  },
  defaultProps: {
    showSearchBar: true,
  },
}

export const login = {
  propTypes: {
    /** Sets whether the login button is displayed or not*/
    showLogin: PropTypes.bool,
  },
  defaultProps: {
    showLogin: true,
  },
}

export const icons = {
  propTypes: {
    /** Classes for icons */
    iconClasses: PropTypes.string,
    /** Classes for labels */
    labelClasses: PropTypes.string,
  },
  defaultProps: {
    iconClasses: 'c-on-base',
    labelClasses: 'c-on-base',
  },
}

export const collapsible = {
  propTypes: {
    collapsibleAnimation: PropTypes.shape({
      /** If should animate on scroll */
      onScroll: PropTypes.bool,
      /** If should animate on every scroll up or  down */
      always: PropTypes.bool,
      /** Scroll value that animation starts to be active */
      anchor: PropTypes.number,
      /** Initial height */
      from: PropTypes.number,
      /** Target height */
      to: PropTypes.number,
      /** Animation configuration presets: know more @ https://www.react-spring.io/docs/hooks/api */
      preset: PropTypes.oneOf([
        'default',
        'gentle',
        'wobbly',
        'stiff',
        'slow',
        'molasses',
      ]),
      /** Animation configuration: know more @ https://www.react-spring.io/docs/hooks/api */
      config: PropTypes.shape({
        mass: PropTypes.number,
        tension: PropTypes.number,
        friction: PropTypes.number,
        clamp: PropTypes.bool,
        precision: PropTypes.number,
        velocity: PropTypes.number,
        duration: PropTypes.number,
        easing: PropTypes.func,
      }),
    }),
  },

  defaultProps: {
    collapsibleAnimation: {
      onScroll: true,
      always: true,
      anchor: 100,
      from: 4,
      to: 0,
      preset: 'default',
      config: {},
    },
  },
}

export const spacer = {
  propTypes: {
    /** Height on mobile mode */
    spacerHeightMobile: PropTypes.number,
    /** Height on desktop mode */
    spacerHeightDesktop: PropTypes.number,
    /** Width on mobile and desktop */
    spacerWidth: PropTypes.number,
  },

  defaultProps: {
    spacerHeightMobile: 96,
    spacerHeightDesktop: 160,
    spacerWidth: 0,
  },
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/components/StickyRow.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FunctionComponent, CSSProperties } from 'react'
import React, { useContext } from 'react'
import ReactResizeDetector from 'react-resize-detector'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'

import { RowContext } from './StickyRows'

const CSS_HANDLES = ['headerStickyRow'] as const

interface Props {
  /**
   * Define if the element behaves in a sticky manner
   * @default false
   * */
  sticky?: boolean
  zIndex?: number
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

const StickyRow: FunctionComponent<Props> = ({
  children,
  sticky,
  zIndex,
  classes,
}) => {
  const { handles } = useCssHandles(CSS_HANDLES, {
    classes,
  })

  const { offset, onResize } = useContext(RowContext)

  const stickyStyle: CSSProperties = {
    top: offset,
    zIndex,
  }

  return (
    <div
      style={sticky ? stickyStyle : undefined}
      className={`${handles.headerStickyRow} ${
        sticky ? `sticky ${!zIndex ? 'z-999' : ''}` : ''
      }`}
    >
      {children}

      {sticky && (
        <ReactResizeDetector
          handleHeight
          onResize={(_, height) => {
            onResize(height)
          }}
        />
      )}
    </div>
  )
}

export default StickyRow

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/components/CustomHeader.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FunctionComponent } from 'react'
import React from 'react'
import { Block } from 'vtex.render-runtime'
import { useDevice } from 'vtex.device-detector'

const enum Device {
  mobile = 'mobile',
  desktop = 'desktop',
}

const CustomHeaderLayout = React.memo(({ device }: { device: Device }) => {
  switch (device) {
    case Device.mobile:
      return (
        <>
          <Block id="header-layout.mobile" />
          <Block id="unstable--header-layout.mobile" />
        </>
      )

    case Device.desktop:
    // falls through

    default:
      return (
        <>
          <Block id="header-layout.desktop" />
          <Block id="unstable--header-layout.desktop" />
        </>
      )
  }
})

CustomHeaderLayout.displayName = 'CustomHeaderLayout'

const CustomHeader: FunctionComponent = () => {
  const { isMobile } = useDevice()

  return (
    <CustomHeaderLayout device={isMobile ? Device.mobile : Device.desktop} />
  )
}

export default CustomHeader

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/components/StickyRows.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { PropsWithChildren } from 'react'
import React from 'react'

import useCumulativeHeightState from '../hooks/useCumulativeHeightState'

type RowContextType = {
  /** Callback executed when element is resized */
  onResize(height: number): void
  /** Vertical Offset from top of container */
  offset: number
}

const RowContext = React.createContext<RowContextType>({
  onResize: () => {},
  offset: 0,
})

/**
 * @deprecated Use the `vtex.sticky-layout` app instead
 */
// eslint-disable-next-line @typescript-eslint/ban-types
function StickyRows({ children }: PropsWithChildren<{}>) {
  const { updateRowHeight, getAccumulatedHeight } = useCumulativeHeightState()

  return (
    <>
      {React.Children.map(children, (child, index) => (
        <RowContext.Provider
          value={{
            onResize: (height: number) => updateRowHeight({ height, index }),
            offset: getAccumulatedHeight(index),
          }}
        >
          {child}
        </RowContext.Provider>
      ))}
    </>
  )
}

export default StickyRows

export { RowContext }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/__tests__/Header.test.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'
import { useRuntime } from 'vtex.render-runtime'

import Header from '../legacy/index'

describe('Header Component', () => {
  beforeEach(() => {
    const { setHints } = useRuntime()

    setHints({ mobile: false, desktop: true })
  })

  it('should be rendered', () => {
    const component = render(<Header />)

    expect(component).toBeTruthy()
  })

  it('should match snapshot without leanmode', () => {
    const component = render(<Header />)

    expect(component.asFragment()).toMatchSnapshot()
  })

  it('should match snapshot with leanmode', () => {
    const component = render(<Header leanWhen="test" />)

    expect(component.asFragment()).toMatchSnapshot()
  })

  it('should match snapshot mobile without leanmode', () => {
    const { setHints } = useRuntime()

    setHints({ mobile: true, desktop: false })

    const component = render(<Header />)

    expect(component.asFragment()).toMatchSnapshot()
  })

  it('should match snapshot mobile with leanmode', () => {
    const { setHints } = useRuntime()

    setHints({ mobile: true, desktop: false })

    const component = render(<Header leanWhen="test" />)

    expect(component.asFragment()).toMatchSnapshot()
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/hooks/useCumulativeHeightState.tsx from the store-header VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

interface State {
  [id: string]: number
}

const enum ActionTypes {
  UPDATE = 'update',
}

interface UpdateAction {
  type: ActionTypes.UPDATE
  payload: {
    index: number
    height: number
  }
}

type Actions = UpdateAction

const reducer = (state: State, action: Actions) => {
  switch (action.type) {
    case 'update':
      return {
        ...state,
        [action.payload.index]: action.payload.height,
      }

    default:
      return state
  }
}

const useCumulativeHeightState = () => {
  const [state, dispatch]: [
    State,
    React.Dispatch<UpdateAction>
  ] = React.useReducer(reducer, {})

  const updateRowHeight = ({
    height,
    index,
  }: {
    height: number
    index: number
  }) => {
    if (state[index] === height) {
      return
    }

    dispatch({
      payload: {
        height,
        index,
      },
      type: ActionTypes.UPDATE,
    })
  }

  const getAccumulatedHeight = (index: number) => {
    const sortedIndices = Object.keys(state)
      .map((key) => parseInt(key, 10))
      .sort((a, b) => a - b)

    const indices = sortedIndices.slice(0, sortedIndices.indexOf(index))

    return indices.reduce((acc, cur) => (state[cur] || 0) + acc, 0)
  }

  return {
    getAccumulatedHeight,
    updateRowHeight,
  }
}

export default useCumulativeHeightState

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/testUtils/setupTests.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
// react-testing-library renders your components to document.body,
// this will ensure they're removed after each test.
import 'react-testing-library/cleanup-after-each'

// this adds jest-dom's custom assertions
import 'jest-dom/extend-expect'

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/testUtils/test-utils.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import * as reactTestingLibrary from 'react-testing-library'
import { IntlProvider } from 'react-intl'

import defaultStrings from '../../messages/en.json'

const customRender = (node, options) => {
  const rendered = reactTestingLibrary.render(
    <IntlProvider messages={defaultStrings} locale="en-US">
      {node}
    </IntlProvider>,
    options
  )

  return {
    ...rendered,
    rerender: (newUi) =>
      customRender(newUi, {
        container: rendered.container,
        baseElement: rendered.baseElement,
      }),
  }
}

// re-export everything
module.exports = {
  ...reactTestingLibrary,
  render: customRender,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/FixedContent.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment, useState } from 'react'
import { ExtensionPoint } from 'vtex.render-runtime'
import PropTypes from 'prop-types'
import { Container } from 'vtex.store-components'
import classNames from 'classnames'
import Logo from './Logo'
import SearchBar from './SearchBar'
import Actions from './Actions'
import { logo, icons, lean, searchBar, login } from '../defaults'

import styles from '../store-header.css'

/**
 * Component that deals with content thats always fixed on top
 * Also handles the toggle between mobile search and mobile navbar
 */
const FixedContent = ({
  leanMode,
  logoUrl,
  linkUrl,
  logoTitle,
  logoSize,
  showSearchBar,
  showLogin,
  iconClasses,
  labelClasses,
  mobile,
}) => {
  const [mobileSearchActive, toggleSearch] = useState(false)
  const containerClasses = classNames(
    `${
      styles.topMenuContainer
    } relative flex justify-center bg-base h3 bb bw0 b--white`
  )
  const contentClasses = classNames(
    'w-100 mw9 flex justify-center',
    leanMode ? 'pv0' : 'pv6-l pv2-m'
  )

  return (
    <div className="w-100 bg-base">
      <Container
        className={containerClasses}
        style={{
          transform: 'translateZ(0)', //Avoid shaking
        }}
      >
        <div className={contentClasses} style={{ pointerEvents: 'none' }}>
          <div
            className="flex w-100 justify-between-m items-center pv3"
            style={{
              pointerEvents: 'auto',
            }}
          >
            {mobileSearchActive ? (
              mobile &&
              showSearchBar && (
                <div className="flex justify-start pa2 relative w-100">
                  <SearchBar
                    mobile={mobile}
                    iconClasses={iconClasses}
                    onCancel={() => toggleSearch(false)}
                  />
                </div>
              )
            ) : (
              <Fragment>
                {!leanMode && mobile && (
                  <ExtensionPoint
                    id="category-menu"
                    mobileMode
                    iconClasses={iconClasses}
                  />
                )}

                <Logo
                  logoUrl={logoUrl}
                  logoTitle={logoTitle}
                  linkUrl={linkUrl}
                  logoSize={logoSize}
                  mobile={mobile}
                />

                {!leanMode && !mobile && showSearchBar && (
                  <div className="dn db-ns flex-grow-1">
                    <SearchBar mobile={mobile} />
                  </div>
                )}

                <ExtensionPoint id="locale-switcher"/>

                <Actions
                  iconClasses={iconClasses}
                  labelClasses={labelClasses}
                  showSearchBar={showSearchBar}
                  showSearchIcon={showSearchBar}
                  leanMode={leanMode}
                  showLogin={showLogin}
                  onActiveSearch={() => toggleSearch(true)}
                  mobile={mobile}
                />

                {!mobile && (
                  <ExtensionPoint id="user-address" variation="inline" />
                )}
              </Fragment>
            )}
          </div>
        </div>
      </Container>
    </div>
  )
}

FixedContent.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  ...lean.propTypes,
  ...login.propTypes,
  ...searchBar.propTypes,
  ...logo.propTypes,
  ...icons.propTypes,
}

FixedContent.defaultProps = {
  ...lean.defaultProps,
  ...login.defaultProps,
  ...searchBar.defaultProps,
  ...logo.defaultProps,
  ...icons.defaultProps,
}

export default FixedContent

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/Collapsible.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import classNames from 'classnames'
import { NoSSR, ExtensionPoint } from 'vtex.render-runtime'
import PropTypes from 'prop-types'
import {
  useSpring,
  animated,
  config as springPresets,
} from 'react-spring/web.cjs'
import useScrollDirection from '../hooks/useScrollDirection'
import Border from './Helpers/Border'
import { collapsible, lean } from '../defaults'

import styles from '../store-header.css'

/**
 * Represents a collapsible part of the header
 */
const Collapsible = ({ children, leanMode, collapsibleAnimation, mobile }) => {
  const { scroll, scrollingUp } = useScrollDirection()
  const {
    onScroll,
    anchor,
    always,
    from,
    to,
    preset,
    config,
  } = collapsibleAnimation

  let animationTrigger = true

  if (onScroll) {
    const animateWhen = scroll < anchor
    const elastic = always ? scrollingUp : false
    animationTrigger = animateWhen || elastic
  }

  const animationStyle =
    !!window.requestAnimationFrame && // Fix SSR Issues
    useSpring({
      config: preset ? springPresets[preset] : config,
      transform: animationTrigger
        ? `translate3d(0, ${to}rem, 0)`
        : `translate3d(0, ${-from}rem, 0)`,
    })

  const collapsibleClassnames = classNames(
    styles.topMenuCollapsible,
    'bg-base flex justify-center relative bb bw1 b--muted-4'
  )

  const fallback = <div className={collapsibleClassnames}>{children}</div>

  return (
    <React.Fragment>
      {!mobile && !leanMode ? (
        <NoSSR onSSR={fallback}>
          <animated.div
            className={collapsibleClassnames}
            style={{ ...animationStyle, zIndex: -2 }}
          >
            {children}
          </animated.div>
        </NoSSR>
      ) : (
        <Border />
      )}
      {mobile && !leanMode && (
        <ExtensionPoint id="user-address" variation="bar" />
      )}
    </React.Fragment>
  )
}

Collapsible.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  ...lean.propTypes,
  ...collapsible.propTypes,
}

Collapsible.defaultProps = {
  ...lean.defaultProps,
  ...collapsible.defaultProps,
}

export default Collapsible

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/TopMenu.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { ExtensionPoint, useChildBlock } from 'vtex.render-runtime'
import Collapsible from './Collapsible'
import FixedContent from './FixedContent'
import { logo, collapsible, icons, lean, searchBar, login } from '../defaults'
import styles from '../store-header.css'

/**
 * Top menu that contains the fixed and collapsible parts
 */
const TopMenu = ({
  extraHeaders,
  leanMode,
  logoUrl,
  linkUrl,
  logoTitle,
  logoSize,
  showLogin,
  showSearchBar,
  iconClasses,
  labelClasses,
  collapsibleAnimation,
  mobile,
}) => {
  const hasMenu = !!useChildBlock({ id: 'menu' })
  const hasUnstableMenu = !!useChildBlock({ id: 'unstable--menu' })

  if (hasUnstableMenu) {
    console.warn(
      'The flag `unstable--` from the menu component will be deprecated soon, in favor of just `menu`. The `second-level-menu` will also be deprecated in favor of `menu`.'
    )
  }

  return (
    <Fragment>
      {extraHeaders}

      <FixedContent
        leanMode={leanMode}
        logoUrl={logoUrl}
        linkUrl={linkUrl}
        logoSize={logoSize}
        logoTitle={logoTitle}
        showSearchBar={showSearchBar}
        showLogin={showLogin}
        iconClasses={iconClasses}
        labelClasses={labelClasses}
        mobile={mobile}
      />

      <Collapsible
        collapsibleAnimation={collapsibleAnimation}
        leanMode={leanMode}
        mobile={mobile}
      >
        {hasMenu || hasUnstableMenu ? (
          <div className={styles.topMenuCompatibilityContainer}>
            <div className="flex flex-grow-1" />
            <ExtensionPoint id={hasMenu ? 'menu' : 'unstable--menu'} />
            <div className="flex flex-grow-1" />
          </div>
        ) : (
          <ExtensionPoint id="category-menu" />
        )}
      </Collapsible>
    </Fragment>
  )
}

TopMenu.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  /** Very top aditional sections */
  extraHeaders: PropTypes.element,
  ...lean.propTypes,
  ...login.propTypes,
  ...searchBar.propTypes,
  ...logo.propTypes,
  ...icons.propTypes,
  ...collapsible.propTypes,
}

TopMenu.defaultProps = {
  ...lean.defaultProps,
  ...login.defaultProps,
  ...searchBar.defaultProps,
  ...logo.defaultProps,
  ...icons.defaultProps,
  ...collapsible.defaultProps,
}

export default TopMenu

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/Actions.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import PropTypes from 'prop-types'
import { ExtensionPoint } from 'vtex.render-runtime'
import { FormattedMessage } from 'react-intl'
import { ButtonWithIcon } from 'vtex.styleguide'
import { IconSearch } from 'vtex.store-icons'
import { lean, icons, searchBar, login } from '../defaults'

import styles from '../store-header.css'

/**
 * Represents the header icon buttons
 */
const Actions = ({
  showSearchBar,
  leanMode,
  iconClasses,
  labelClasses,
  showLogin,
  onActiveSearch,
  mobile,
}) => {
  return (
    <div
      className={`${
        styles.topMenuIcons
      } flex justify-end flex-grow-1 flex-grow-0-ns items-center order-1-s ml-auto-s order-2-ns`}
    >
      {mobile && (
        <div className="flex mr3">
          {showSearchBar && !leanMode && (
            <ButtonWithIcon
              icon={
                <span className={iconClasses}>
                  <IconSearch />
                </span>
              }
              variation="tertiary"
              onClick={onActiveSearch}
            />
          )}

          {showLogin && (
            <ExtensionPoint
              id="login"
              iconClasses={iconClasses}
              labelClasses={labelClasses}
            />
          )}

          {!leanMode && (
            <ExtensionPoint
              id="minicart"
              iconClasses={iconClasses}
              labelClasses={labelClasses}
            />
          )}
        </div>
      )}

      {!mobile && (
        <div className="flex">
          {showLogin && (
            <ExtensionPoint
              id="login"
              iconClasses={iconClasses}
              labelClasses={labelClasses}
              iconLabel={
                <FormattedMessage id="store/header.topMenu.login.icon.label" />
              }
            />
          )}

          {!leanMode && (
            <ExtensionPoint
              id="minicart"
              iconClasses={iconClasses}
              labelClasses={labelClasses}
              iconLabel={
                <FormattedMessage id="store/header.topMenu.minicart.icon.label" />
              }
            />
          )}
        </div>
      )}
    </div>
  )
}

Actions.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  /** Callback function for search active */
  onActiveSearch: PropTypes.func,
  ...lean.propTypes,
  ...login.propTypes,
  ...searchBar.propTypes,
  ...icons.propTypes,
}

Actions.defaultProps = {
  onActiveSearch: () => {},
  ...lean.defaultProps,
  ...login.defaultProps,
  ...searchBar.defaultProps,
  ...icons.defaultProps,
}

export default Actions

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/SearchBar.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import { Adopt } from 'react-adopt'
import { ExtensionPoint } from 'vtex.render-runtime'
import { Button } from 'vtex.styleguide'
import classNames from 'classnames'
import { icons } from '../defaults'

import styles from '../store-header.css'

/**
 * Represents the search bar of the header
 */
const SearchBar = ({ onCancel, iconClasses, mobile }) => {
  const searchBarClassNames = classNames(
    `${styles.topMenuSearchBar} flex pa2-m flex-grow-1`,
    mobile ? 'justify-between' : 'justify-center'
  )

  const cancelClassNames = classNames(`${iconClasses} ttl`)

  return (
    <div className={searchBarClassNames}>
      <div className="w-75">
        <Adopt
          mapper={{
            placeholder: <FormattedMessage id="store/header.search-placeholder" />,
            emptyPlaceholder: (
              <FormattedMessage id="store/header.search-emptyPlaceholder" />
            ),
          }}
        >
          {({ placeholder, emptyPlaceholder }) => (
            <ExtensionPoint
              id="search-bar"
              placeholder={placeholder}
              emptyPlaceholder={emptyPlaceholder}
              autoFocus={mobile}
              hasIconLeft={mobile}
              iconClasses={iconClasses}
            />
          )}
        </Adopt>
      </div>
      {mobile && (
        <div className="w-25 pa2-m pt2-s">
          <Button size="small" variation="tertiary" onClick={onCancel}>
            <span className={cancelClassNames}>
              <FormattedMessage id="store/header.search-cancel" />
            </span>
          </Button>
        </div>
      )}
    </div>
  )
}

SearchBar.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  /** Callback function on cancel */
  onCancel: PropTypes.func,
  ...icons.propTypes,
}

SearchBar.defaultProps = {
  onCancel: () => {},
  ...icons.defaultProps,
}

export default SearchBar

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/Logo.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { ExtensionPoint, Link } from 'vtex.render-runtime'
import PropTypes from 'prop-types'
import { logo } from '../defaults'

import styles from '../store-header.css'

/**
 * Represents the header logo
 */
const Logo = ({ logoUrl, logoTitle, linkUrl, logoSize, mobile }) => {
  return (
    <div className={`${styles.topMenuLogo} pv2 mr5`}>
      <Link to={linkUrl} className={`outline-0 ${styles.logoLink}`}>
        <ExtensionPoint
          id="logo"
          url={logoUrl}
          title={logoTitle}
          width={mobile ? logoSize.mobile.width : logoSize.desktop.width}
          height={mobile ? logoSize.mobile.height : logoSize.desktop.height}
          isMobile={mobile}
        />
      </Link>
    </div>
  )
}

Logo.propTypes = {
  /** If it's mobile mode */
  mobile: PropTypes.bool.isRequired,
  ...logo.propTypes,
}

Logo.defaultProps = {
  ...logo.defaultProps,
}

export default Logo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/hooks/useScrollDirection.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { useState, useEffect } from 'react'
import useScroll from './useScroll'

/**
 * Hook that handles the scroll direction
 * @returns {Number, Boolean, Boolean} - the current scroll value and if the scroll is up, or down
 */
const useScrollDirection = () => {
  const { scroll } = useScroll()
  const [scrollingUp, setScrollingUp] = useState(false)
  const [lastScroll, setLastScroll] = useState(0)

  useEffect(() => {
    setLastScroll(scroll)
    setScrollingUp(lastScroll > scroll)
  }, [scroll])

  return { scroll, scrollingUp }
}

export default useScrollDirection

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/hooks/useScroll.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { useState, useEffect } from 'react'
import throttle from 'throttleit'

/**
 * Hook that handles the scroll position
 * @returns {Number} - scroll position value
 */
const useScroll = () => {
  const [scroll, setScroll] = useState(0)

  useEffect(() => {
    const handleScroll = () => {
      setScroll(window.scrollY)
    }
    const throttled = throttle(handleScroll, 100)
    window.addEventListener('scroll', throttled)
    return () => window.removeEventListener('scroll', throttled)
  }, [])

  return { scroll }
}

export default useScroll

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/hooks/useDevice.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { useState, useLayoutEffect } from 'react'
import { useRuntime } from 'vtex.render-runtime'
import { debounce } from 'debounce'

/**
 * Hook that handles dynamic device change on resize
 * @param {Number} mobileBreakpoint - break point of mobile change
 * @returns {Boolean, Boolean} - if its mobile or desktop
 */
const useDevice = (mobileBreakpoint = 640) => {
  const { hints } = useRuntime()

  const isMobile = !!window.innerWidth
    ? window.innerWidth <= mobileBreakpoint
    : hints.mobile

  const [mobile, setMobile] = useState(isMobile)
  const [desktop, setDesktop] = useState(!isMobile)

  useLayoutEffect(() => {
    const handleResize = () => {
      setMobile(window.innerWidth <= mobileBreakpoint)
      setDesktop(window.innerWidth > mobileBreakpoint)
    }
    const debounced = debounce(handleResize, 100)
    window.addEventListener('resize', debounced)
    window.addEventListener('load', handleResize)
    return () => {
      window.removeEventListener('resize', debounced)
      window.removeEventListener('load', handleResize)
    }
  }, [mobileBreakpoint])

  return {
    mobile,
    desktop,
  }
}

export default useDevice

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/Helpers/Spacer.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { spacer } from '../../defaults'
import useDevice from '../../hooks/useDevice'

/**
 * Spacer necessary to content due fixed Header
 */
const Spacer = ({ spacerHeightDesktop, spacerHeightMobile, spacerWidth, containerHeight }) => {
  const { desktop } = useDevice()

  const height = containerHeight || (desktop ? spacerHeightDesktop : spacerHeightMobile)

  return (
    <div
      className="z-1 bg-base w-100 relative"
      style={{
        height,
        width: spacerWidth,
      }}
    />
  )
}

Spacer.propTypes = {
  ...spacer.propTypes,
}

Spacer.defaultProps = {
  ...spacer.defaultProps,
}

export default Spacer

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-header/react/legacy/components/Helpers/Border.js from the store-header VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'

/**
 * Simple border
 */
const Border = () => {
  return (
    <div
      className="bb bw1 b--muted-4 relative"
      style={{
        top: 'inherit',
        boxSizing: 'content-box',
        zIndex: -2,
      }}
    />
  )
}

export default Border

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/docs/README.md from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```markdown

# Service Example

A reference app implementing a VTEX IO service with HTTP route handlers.

![Service Example Architecture](https://user-images.githubusercontent.com/18706156/77381360-72489680-6d5c-11ea-9da8-f4f03b6c5f4c.jpg)

We use [**KoaJS**](https://koajs.com/) as the web framework, so you might want to get into that

We also use the [**node-vtex-api**](https://github.com/vtex/node-vtex-api), a VTEX set of utilities for Node services. You can import this package using NPM from `@vtex/api` (already imported on this project)

- Start from `node/index.ts` and follow the comments and imports :)

## Recipes

### Defining routes on _service.json_
```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 4,
  "routes": {
    "status": {
      "path": "/_v/status/:code",
      "public": true
    }
  }
}
```

The `service.json` file that sits on the root of the `node` folder holds informations about this service, like the maximum timeout and number of replicas, what might be discontinued on the future, but also **sets its routes**.

Koa uses the [path-to-regexp](https://github.com/pillarjs/path-to-regexp) format for defining routes and, as seen on the example, we use the `:code` notation for declaring a **route param** named code, in this case. A HTTP request for `https://{{workspace}}--{{account}}.myvtex.com/_v/status/500` will match the route we've defined.

For cach _key_ on the `routes` object, there should be a **corresponding entry** on the exported Service object on `node/index.ts`, this will hook your code to a specific route.

### Access Control
You can also provide a `public` option for each route. If `true`, that resource will be reachable for everyone on the internet. If `false`, VTEX credentials will be requested as well.

Another way of controlling access to specific routes is using **ReBACs (Resource-based access)**, that supports more robust configuration. You can read more [on this document](https://docs.google.com/document/d/1ZxNHMFIXfXz3BgTN9xyrHL3V5dYz14wivYgQjRBZ6J8/edit#heading=h.z7pad3qd2qw7) (VTEX only).

#### Query String
For `?accepting=query-string`, you **don't need to declare anything**, as any query provided to the URL will already be available for you to use on the code as `ctx.query`, already parsed as an object, or `ctx.queryString`, taken directly from the URL as a string.

#### Route Params
Route Params will be available for you to use on the code as `ctx.vtex.params`, already parsed as an object.
For a path like `/_v/status/:code`, if you receive the request `/_v/status/200`, `ctx.vtex.params` will return `{ code: '200' }`

#### HTTP methods
When you define a route on the `service.json`, your NodeJS handlers for that route will be triggered  **on every HTTP method** (GET, POST, PUT...), so, if you need to handle them separately you need to implement a "sub-router". Fortunately, the _node-vtex-api_ provides a helper function `method`, exported from `@vtex/api`, to accomplish that behaviour. Instead of passing your handlers directly to the corresponding route on `index.ts`, you pass a `method` call passing **an object with the desired method as key and one handler as its corresponding value**. Check this example:
```typescript
import { method } from '@vtex/api'
...

export default new Service<Clients, State>({
  clients,
  routes: {
    status: method({
      GET: statusGetHandler,
      POST: statusPostHandler,
    }),
  },
})
```

### Throwing errors

When building a HTTP service, we should follow HTTP rules regarding data types, cache, authorization, and status code. Our example app sets a `ctx.status` value that will be used as a HTTP status code return value, but often we also want to give proper information about errors as well.

The **node-vtex-api** already exports a handful of **custom error classes** that can be used for that purpose, like the `NotFoundError`. You just need to throw them inside one of the the route handlers that the appropriate response will be sent to the server.

```typescript
import { UserInputError } from '@vtex/api'

export async function validate(ctx: Context, next: () => Promise<any>) {
  const { code } = ctx.vtex.route.params
  if (isNaN(code) || code < 100 || code > 600) {
    throw new UserInputError('Code must be a number between 100 and 600')
  }
...
```

You can check all the available errors [here](https://github.com/vtex/node-vtex-api/tree/fd6139349de4e68825b1074f1959dd8d0c8f4d5b/src/errors), but some are not useful for just-HTTP services. Check the most useful ones:

|Error Class | HTTP Code |
|--|:--:|
| `UserInputError` | 400 |
| `AuthenticationError` | 401 |
| `ForbiddenError` | 403 |
| `NotFoundError` | 404 |

You can also **create your custom error**, just see how it's done above ;)

### Reading a JSON body

When writing POST or PUT handlers, for example, often you need to have access to the **request body** that comes as a JSON format, which is not provided directly by the handler function.

For this, you have to use the [co-body](https://www.npmjs.com/package/co-body) package that will parse the request into a readable JSON object, used as below:
```typescript
import { json } from 'co-body'
export async function method(ctx: Context, next: () => Promise<any>) {
    const body = await json(ctx.req)
```

### Other example apps

We use Node services across all VTEX, and there are a lot inspiring examples. If you want to dive deeper on learning about this subject, don't miss those internal apps: [builder-hub](https://github.com/vtex/builder-hub) or [store-sitemap](https://github.com/vtex-apps/store-sitemap)

## Testing

`@vtex/test-tools` and `@types/jest` should be installed on `./node` package as `devDependencies`.

Run `vtex test` and [Jest](https://jestjs.io/) will do its thing.

Check the `node/__tests__/simple.test.ts` test case and also [Jest's Documentation](https://jestjs.io/docs/en/getting-started).

## Splunk Dashboard

We have an (for now, VTEX-only, internal) Splunk dashboard to show all metrics related to your app. You can find it [here](https://splunk7.vtex.com/en-US/app/vtex_colossus/node_app_metrics).

After linking this app and making some requests, you can select `vtex.service-example` and see the metrics for your app. **Don't forget to check the box Development, as you are linking your app in a development workspace**.

For convenience, the link for the current version: https://splunk7.vtex.com/en-US/app/vtex_colossus/node_app_metrics?form.time.earliest=-30m%40m&form.time.latest=%40m&form.picked_context=false&form.picked_region=aws-us-east-*&form.picked_service=vtex.service-example

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/service.json from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 30,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1,
  "routes": {
    "notify": {
      "path": "/notify",
      "public": false,
      "access": "authorized",
      "policies": [
        {
          "effect": "allow",
          "actions": ["post"],
          "principals": ["vrn:apps:*:{{account}}:{{workspace}}:app/*.*@*"]
        }
      ]
    }
  },
  "events": {
    "eventBroadcaster": {
      "sender": "vtex.spreadsheet-event-broadcaster",
      "keys": ["event.chain"]
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/package.json from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "@vtex/clients": "^2.19.4",
    "async-busboy": "^1.1.0",
    "co-body": "^6.0.0",
    "get-stream": "^6.0.1",
    "ramda": "^0.25.0",
    "uuid": "^8.3.2",
    "xlsx": "^0.17.5"
  },
  "devDependencies": {
    "@types/async-busboy": "^1.1.1",
    "@types/co-body": "^0.0.3",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.0.0",
    "@types/ramda": "types/npm-ramda#dist",
    "@types/uuid": "^8.3.4",
    "@vtex/api": "6.48.0",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7",
    "vtex.spreadsheet-event-broadcaster": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.spreadsheet-event-broadcaster@0.1.0/public/_types/react"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty"
  },
  "version": "0.2.3"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/index.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  ClientsConfig,
  ServiceContext,
  RecorderState,
  EventContext,
} from '@vtex/api'
import { method, Service } from '@vtex/api'

import { Clients } from './clients'
import { broadcast } from './middlewares/broadcaster/broadcast'
import { splitPayload } from './middlewares/broadcaster/splitPayload'
import { verifyUniqueness } from './middlewares/broadcaster/verifyUniqueness'
import { parseFile } from './middlewares/notify/parseFile'
import { startEventChain } from './middlewares/notify/startEventChain'

const TIMEOUT_MS = 6000

const clients: ClientsConfig<Clients> = {
  implementation: Clients,
  options: {
    default: {
      retries: 2,
      timeout: TIMEOUT_MS,
    },
  },
}

declare global {
  type Context = ServiceContext<Clients, State>

  interface State extends RecorderState {
    payload: unknown[]
    senderAppId: string
    clientAppId: string
  }

  interface BroadcasterEventContext extends EventContext<Clients> {
    body: {
      eventId: string
      payload: unknown[]
      senderAppId: string
      clientAppId: string
    }
  }
}

export default new Service({
  clients,
  routes: {
    notify: method({
      POST: [parseFile, startEventChain],
    }),
  },
  events: {
    eventBroadcaster: [verifyUniqueness, splitPayload, broadcast],
  },
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/masterdata/eventRegistry/schema.json from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "$schema": "http://json-schema.org/schema#",
  "title": "Event Registry",
  "type": "object",
  "properties": {
    "hasBeenProcessed": {
      "type": "boolean"
    }
  },
  "required": ["hasBeenProcessed"],
  "v-cache": false
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/clients/index.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { IOClients } from '@vtex/api'
import { masterDataFor } from '@vtex/clients'
import type { EventRegistry } from 'vtex.spreadsheet-event-broadcaster'

export class Clients extends IOClients {
  public get eventRegistry() {
    return this.getOrSet(
      'eventRegistry',
      masterDataFor<EventRegistry>('eventRegistry')
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/typings/notify.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { FileReadStream } from 'async-busboy'

export type NotifyInputParameters = {
  fields: {
    appId?: string
  }
  files: [FileReadStream]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/utils/constants.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const APP_ID = 'vtex.spreadsheet-event-broadcaster'

export const EVENT_CHAIN_KEY = 'event.chain'

export const OUTPUT_EVENT_KEY = 'row.output'

export const MASTER_DATA_NO_CHANGES_RESPONSE_STATUS = 304

const _1GB = 1024 ** 3

export const MAXIMUM_FILE_SIZE = _1GB

export const MAXIMUM_FILE_SIZE_STRING = '1GB'

export const ARRAY_SIZE_TARGET = 1000

export const ARRAY_SIZE_PAYLOAD = 5000

export const ARRAY_SPLIT_FACTOR = 100

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/utils/parsing.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { IncomingMessage } from 'http'

import Busboy from 'busboy'

export async function busboyWrapper<T>(req: IncomingMessage): Promise<T> {
  let result
  let clientAppId

  try {
    const parsedData = await parseForm(req)
    result = parsedData.files
    clientAppId = parsedData.fields.appId
  } catch (e) {
    throw new Error(e)
  }

  return {
    fields: { appId: clientAppId },
    files: [result],
  } as unknown as T
}

async function parseForm(req: IncomingMessage): Promise<{ fields: any, files: any }> {
  try {
    return new Promise((resolve, reject) => {
      const bb = new Busboy({ headers: req.headers as { 'content-type': string } })
      const fields: any = {}
      const files: any = []

      bb.on('file', (_, file) => {
        const fileData: Buffer[] = []

        file.on('data', (data) => {
          fileData.push(data)
        })

        file.on('end', () => {
          files.push(Buffer.concat(fileData))
        })
      })

      bb.on('field', (fieldname, val) => {
        fields[fieldname] = val
      })

      bb.on('finish', () => {
        resolve({ fields, files })
      })

      bb.on('error', (err: any) => {
        reject(err)
      })

      req.pipe(bb)
    })
  } catch (error) {
    throw new Error(error)
  }
}

export function senderAppIdFromHeaders(headers: IncomingMessage['headers']) {
  const appIdWithVersion = headers['x-vtex-caller'] as string

  return appIdWithVersion.split('@')[0]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/services/eventRegistry.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { MasterDataEntity } from '@vtex/clients'
import type { EventRegistry } from 'vtex.spreadsheet-event-broadcaster'

import { MASTER_DATA_NO_CHANGES_RESPONSE_STATUS } from '../utils/constants'

export class EventRegistryService {
  private client: MasterDataEntity<EventRegistry>
  constructor(client: MasterDataEntity<EventRegistry>) {
    this.client = client
  }

  public async isEventUnique(eventId: string) {
    try {
      await this.client.saveOrUpdate({
        id: eventId,
        hasBeenProcessed: true,
      })
    } catch (error) {
      if (error?.response?.status === MASTER_DATA_NO_CHANGES_RESPONSE_STATUS) {
        return false
      }
    }

    return true
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/middlewares/notify/startEventChain.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { v4 as uuid } from 'uuid'

import {
  APP_ID as thisAppId,
  EVENT_CHAIN_KEY as eventKey,
  ARRAY_SIZE_PAYLOAD,
} from '../../utils/constants'

export async function startEventChain(ctx: Context) {
  const {
    state: { payload, senderAppId, clientAppId },
    clients: { events },
  } = ctx

  if (payload.length > ARRAY_SIZE_PAYLOAD) {
    const chunkSize = ARRAY_SIZE_PAYLOAD
    for (let i = 0; i < payload.length; i += chunkSize) {
      const eventId = uuid()
      const chunk = payload.slice(i, i + chunkSize)

      events.sendEvent(thisAppId, eventKey, {
        eventId,
        payload: chunk,
        senderAppId,
        clientAppId,
      })
    }
  } else {
    const eventId = uuid()
    events.sendEvent(thisAppId, eventKey, {
      eventId,
      payload,
      senderAppId,
      clientAppId,
    })
  }

  ctx.status = 200
  ctx.message = 'The spreadsheet is being processed'
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/middlewares/notify/parseFile.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { buffer } from 'get-stream'
import { read, utils } from 'xlsx'

import type { NotifyInputParameters } from '../../typings/notify'
import {
  MAXIMUM_FILE_SIZE,
  MAXIMUM_FILE_SIZE_STRING,
} from '../../utils/constants'
import { busboyWrapper, senderAppIdFromHeaders } from '../../utils/parsing'

export async function parseFile(ctx: Context, next: () => Promise<unknown>) {
  const {
    req,
    vtex: { logger },
  } = ctx

  const senderAppId = senderAppIdFromHeaders(req.headers)

  try {
    const {
      fields: { appId: clientAppId },
      files: [file],
    } = await busboyWrapper<NotifyInputParameters>(req)

    if (!file) {
      const errorMessage = 'No file was sent'

      logger.error(errorMessage)

      ctx.status = 400
      ctx.message = errorMessage

      return
    }

    const bufferedStream = await buffer(file, {
      maxBuffer: MAXIMUM_FILE_SIZE,
    }).catch(() => {
      const errorMessage = `Input file cannot be larger than ${MAXIMUM_FILE_SIZE_STRING}`

      logger.error(errorMessage)

      ctx.status = 413
      ctx.message = errorMessage
    })

    if (!bufferedStream) {
      return
    }
    const workbook = read(bufferedStream)

    const [sheetName] = workbook.SheetNames

    const sheet = workbook.Sheets[sheetName]

    const payload = utils.sheet_to_json(sheet)

    ctx.state.payload = payload
    ctx.state.senderAppId = senderAppId
    ctx.state.clientAppId = clientAppId ?? ''
  } catch (error) {
    logger.error(error.message)

    ctx.status = 500
    ctx.message = error.message

    throw new Error(error)
  }

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/middlewares/broadcaster/splitPayload.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { v4 as uuid } from 'uuid'

import {
  APP_ID as thisAppId,
  EVENT_CHAIN_KEY as eventKey,
  ARRAY_SIZE_TARGET,
  ARRAY_SPLIT_FACTOR,
} from '../../utils/constants'

export async function splitPayload(
  ctx: BroadcasterEventContext,
  next: () => Promise<unknown>
) {
  const {
    clients: { events },
    body: { payload, senderAppId, clientAppId },
  } = ctx

  if (payload.length > ARRAY_SIZE_TARGET) {
    const chunkSize = Math.ceil(payload.length / ARRAY_SPLIT_FACTOR)

    for (let i = 0; i < payload.length; i += chunkSize) {
      const eventId = uuid()

      const chunk = payload.slice(i, i + chunkSize)

      events.sendEvent(thisAppId, eventKey, {
        eventId,
        payload: chunk,
        senderAppId,
        clientAppId,
      })
    }

    return
  }

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/middlewares/broadcaster/broadcast.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { OUTPUT_EVENT_KEY as eventKey } from '../../utils/constants'

export async function broadcast(
  ctx: BroadcasterEventContext,
  next: () => Promise<unknown>
) {
  const {
    clients: { events },
    body: { payload, senderAppId, clientAppId },
  } = ctx

  payload.forEach((row) => {
    events.sendEvent(clientAppId, eventKey, {
      data: row,
      senderAppId,
    })
  })

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of spreadsheet-event-broadcaster/node/middlewares/broadcaster/verifyUniqueness.ts from the spreadsheet-event-broadcaster VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { EventRegistryService } from '../../services/eventRegistry'

export async function verifyUniqueness(
  ctx: BroadcasterEventContext,
  next: () => Promise<unknown>
) {
  const {
    clients: { eventRegistry },
    body: { eventId },
  } = ctx

  const registryService = new EventRegistryService(eventRegistry)

  const isUnique = await registryService.isEventUnique(eventId)

  if (!isUnique) return

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of tab-layout/messages/pt.json from the tab-layout VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.tabLayout.title": "Tab Layout",
  "admin/editor.tabLayout.description": "Container for tabbed layout structure",
  "admin/editor.tabList.title": "Tab List",
  "admin/editor.tabList.description": "Container for tab buttons",
  "admin/editor.tabListItem.title": "Tab List Item",
  "admin/editor.tabListItem.label": "Título da aba",
  "admin/editor.tabListItem.description": "Button with a tabId and label to control visibility of a matching Tab Content Item",
  "admin/editor.tabContent.title": "Tab Content",
  "admin/editor.tabContent.description": "Container for the tab panes",
  "admin/editor.tabContentItem.title": "Tab Content Item",
  "admin/editor.tabContentItem.description": "A content area which will be shown or hidden depending on which tab is active"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of tab-layout/messages/en.json from the tab-layout VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.tabLayout.title": "Tab Layout",
  "admin/editor.tabLayout.description": "Container for tabbed layout structure",
  "admin/editor.tabList.title": "Tab List",
  "admin/editor.tabList.description": "Container for tab buttons",
  "admin/editor.tabListItem.title": "Tab List Item",
  "admin/editor.tabListItem.label": "Tab label",
  "admin/editor.tabListItem.description": "Button with a tabId and label to control visibility of a matching Tab Content Item",
  "admin/editor.tabContent.title": "Tab Content",
  "admin/editor.tabContent.description": "Container for the tab panes",
  "admin/editor.tabContentItem.title": "Tab Content Item",
  "admin/editor.tabContentItem.description": "A content area which will be shown or hidden depending on which tab is active"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of tab-layout/messages/context.json from the tab-layout VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.tabLayout.title": "admin/editor.tabLayout.title",
  "admin/editor.tabLayout.description": "admin/editor.tabLayout.description",
  "admin/editor.tabList.title": "admin/editor.tabList.title",
  "admin/editor.tabList.description": "admin/editor.tabList.description",
  "admin/editor.tabListItem.title": "admin/editor.tabListItem.title",
  "admin/editor.tabListItem.label": "Tab label",
  "admin/editor.tabListItem.description": "admin/editor.tabListItem.description",
  "admin/editor.tabContent.title": "admin/editor.tabContent.title",
  "admin/editor.tabContent.description": "admin/editor.tabContent.description",
  "admin/editor.tabContentItem.title": "admin/editor.tabContentItem.title",
  "admin/editor.tabContentItem.description": "admin/editor.tabContentItem.description"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of tab-layout/messages/es.json from the tab-layout VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.tabLayout.title": "Tab Layout",
  "admin/editor.tabLayout.description": "Container for tabbed layout structure",
  "admin/editor.tabList.title": "Tab List",
  "admin/editor.tabList.description": "Container for tab buttons",
  "admin/editor.tabListItem.title": "Tab List Item",
  "admin/editor.tabListItem.label": "Título de la pestaña",
  "admin/editor.tabListItem.description": "Button with a tabId and label to control visibility of a matching Tab Content Item",
  "admin/editor.tabContent.title": "Tab Content",
  "admin/editor.tabContent.description": "Container for the tab panes",
  "admin/editor.tabContentItem.title": "Tab Content Item",
  "admin/editor.tabContentItem.description": "A content area which will be shown or hidden depending on which tab is active"
}
```