[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-components/react/AutocompleteResults.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, useMemo } from 'react'
import type { RefObject } from 'react'
import classnames from 'classnames'
import { FormattedMessage } from 'react-intl'
import { useQuery } from 'react-apollo'
import { Spinner } from 'vtex.styleguide'
import { Link, useRuntime } from 'vtex.render-runtime'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'
import type { PropGetters } from 'downshift'

import './AutocompleteResults.css'
import autocomplete from './graphql/autocomplete.gql'

const MIN_RESULTS_WIDTH = 320
const CSS_HANDLES = [
  'resultsItem',
  'resultsList',
  'searchTerm',
  'resultsItemImage',
  'spinnerContainer',
  'spinnerInnerContainer',
  'resultsItemName',
] as const

const getImageUrl = (image: string) => {
  const [imageUrl] = image.match(/https?:(.*?)"/g) ?? ['']

  return imageUrl.replace(/https?:/, '').replace(/-25-25/g, '-50-50')
}

const getLinkProps = (element: AutocompleteItem) => {
  const terms = element.slug.split('/')

  if (element.criteria) {
    // This param is only useful to track terms searched
    // See: https://support.google.com/analytics/answer/1012264
    const paramForSearchTracking = `&_c=${terms[0]}`

    return {
      page: 'store.search',
      params: { term: terms.join('/') },
      query: `map=c,ft${paramForSearchTracking}`,
    }
  }

  return {
    page: 'store.product',
    params: { slug: element.slug, id: element.productId },
    query: '',
  }
}

export type Props = {
  parentContainer?: RefObject<HTMLElement>
  /** Downshift specific prop */
  highlightedIndex: number | null
  /** Search query */
  inputValue: string
  /** A template for a custom url. It can have a substring ${term} used as placeholder to interpolate the searched term. (e.g. `/search?query=${term}`) */
  customSearchPageUrl?: string
  isOpen?: boolean
  attemptPageTypeSearch?: boolean
  /** Closes the options box. */
  closeMenu: () => void
  /** Clears the input */
  onClearInput: () => void
  /** Downshift function */
  getItemProps: PropGetters<AutocompleteItem | { term: string }>['getItemProps']
  getMenuProps: PropGetters<AutocompleteItem | { term: string }>['getMenuProps']
  /** Used to override default CSS handles */
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

type AutocompleteItem = {
  thumb: string
  name: string
  href: string
  slug: string
  criteria: string
  productId: string
}

interface AutocompleteResult {
  autocomplete: {
    itemsReturned: AutocompleteItem[]
  }
}

/** List of search results to be displayed */
function AutocompleteResults({
  parentContainer,
  isOpen,
  inputValue,
  closeMenu,
  onClearInput,
  getItemProps,
  getMenuProps,
  highlightedIndex,
  attemptPageTypeSearch,
  customSearchPageUrl,
  classes,
}: Props) {
  const { data, loading } = useQuery<AutocompleteResult>(autocomplete, {
    skip: !inputValue,
    variables: { inputValue },
  })

  const items = data?.autocomplete?.itemsReturned ?? []

  const {
    hints: { mobile },
  } = useRuntime()

  const { handles } = useCssHandles(CSS_HANDLES, { classes })
  const encodedInputValue = encodeURIComponent(inputValue)

  const listStyle = useMemo(
    () => ({
      width: Math.max(
        MIN_RESULTS_WIDTH,
        parentContainer?.current?.offsetWidth ?? 0
      ),
    }),
    /* with the isOpen here this will be called
    only when you open or close the ResultList */
    [parentContainer]
  )

  const listClassNames = classnames(
    handles.resultsList,
    'z-max w-100 bl-ns bb br-ns bw1 b--muted-4 bg-base c-on-base t-body left-0 list pv4 ph0 mv0 list overflow-y-auto',
    mobile ? 'fixed' : 'absolute',
    { dn: !isOpen || !inputValue }
  )

  const handleItemClick = () => {
    onClearInput()
    closeMenu()
  }

  function getListItemClassNames({
    itemIndex = -1,
    // eslint-disable-next-line no-shadow
    highlightedIndex,
    hasThumb,
  }: {
    itemIndex?: number
    highlightedIndex?: number | null
    hasThumb?: boolean
  } = {}) {
    const highlightClass = highlightedIndex === itemIndex ? 'bg-muted-5' : ''

    return `pointer pa4 outline-0 ${handles.resultsItem} ${highlightClass} ${
      hasThumb ? 'flex justify-start' : 'db w-100'
    }`
  }

  const WrappedSpinner = () => (
    <div className={`w-100 flex justify-center ${handles.spinnerContainer}`}>
      <div className={`${handles.spinnerInnerContainer} w3 ma0`}>
        <Spinner />
      </div>
    </div>
  )

  const fullTextSearchLabel = (
    <FormattedMessage
      id="store/search.searchFor"
      values={{
        term: <span className={handles.searchTerm}>{`"${inputValue}"`}</span>,
      }}
    />
  )

  // eslint-disable-next-line no-shadow
  const renderSearchByClick = (inputValue: string) => {
    return customSearchPageUrl ? (
      <Link
        className={getListItemClassNames({
          itemIndex: 0,
          highlightedIndex,
        })}
        to={customSearchPageUrl.replace(/\$\{term\}/g, inputValue)}
      >
        {fullTextSearchLabel}
      </Link>
    ) : (
      <Link
        page="store.search"
        params={{ term: inputValue }}
        query="map=ft"
        className={getListItemClassNames({
          itemIndex: 0,
          highlightedIndex,
        })}
      >
        {fullTextSearchLabel}
      </Link>
    )
  }

  return (
    <div style={listStyle}>
      <ul className={listClassNames} {...getMenuProps()}>
        {isOpen ? (
          loading ? (
            <div className={getListItemClassNames({})}>
              <WrappedSpinner />
            </div>
          ) : (
            <Fragment>
              <li
                {...getItemProps({
                  key: `ft${inputValue}`,
                  item: { term: encodedInputValue },
                  index: 0,
                  onClick: handleItemClick,
                })}
              >
                {attemptPageTypeSearch ? (
                  // eslint-disable-next-line jsx-a11y/anchor-is-valid
                  <a
                    href="#"
                    onClick={event => event.preventDefault()}
                    className={getListItemClassNames({
                      itemIndex: 0,
                      highlightedIndex,
                    })}
                  >
                    {fullTextSearchLabel}
                  </a>
                ) : (
                  renderSearchByClick(encodedInputValue)
                )}
              </li>

              {items.map((item, index) => {
                return (
                  // eslint-disable-next-line react/jsx-key
                  <li
                    {...getItemProps({
                      key: `${item.name}${index}`,
                      index: index + 1,
                      item,
                      onClick: handleItemClick,
                    })}
                  >
                    <Link
                      {...getLinkProps(item)}
                      className={getListItemClassNames({
                        itemIndex: index + 1,
                        highlightedIndex,
                        hasThumb: !!item.thumb,
                      })}
                    >
                      {item.thumb && (
                        <img
                          width={50}
                          height={50}
                          alt={item.name}
                          className={`${handles.resultsItemImage} mr4`}
                          src={getImageUrl(item.thumb)}
                        />
                      )}
                      <div
                        className={`${handles.resultsItemName} flex justify-start items-center`}
                      >
                        {item.name}
                      </div>
                    </Link>
                  </li>
                )
              })}
            </Fragment>
          )
        ) : null}
      </ul>
    </div>
  )
}

export default AutocompleteResults

```


[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-components/react/GradientCollapse.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import GradientCollapse from './components/GradientCollapse/index'

export default GradientCollapse

```


[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-components/react/ProductName.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment } from 'react'
import { isEmpty } from 'ramda'
import { useProduct } from 'vtex.product-context'
import ContentLoader from 'react-content-loader'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { Link } from 'vtex.render-runtime'
import { IOMessage } from 'vtex.native-types'

const CSS_HANDLES = [
  'productNameContainer',
  'sponsoredBadge',
  'productBrand',
  'productSku',
  'productReference',
  'productNameLoader',
  'productNameBrandLoader',
  'productNameSkuLoader',
  'productNameLink',
] as const

type DeprecatedProps = {
  /**
   * Name of the product
   * @deprecated This prop is fulfilled automatically via product-context.
   */
  name?: string
  /**
   * Selected SKU name
   * @deprecated This prop is fulfilled automatically via product-context.
   */
  skuName?: string
  /**
   * Product reference
   * @deprecated This prop is fulfilled automatically via product-context.
   */
  productReference?: string
  /**
   * Brand name
   * @deprecated This prop is fulfilled automatically via product-context.
   */
  brandName?: string
}

type Props = {
  /** Show sku */
  showSku?: boolean
  /** Show product reference */
  showProductReference?: boolean
  /** Show brand name */
  showBrandName?: boolean
  /** Show sponsored badge */
  showSponsoredBadge?: boolean
  /** Label to display in the sponsored badge */
  sponsoredBadgeLabel?: string
  /** Classes to be applied to root element */
  className?: string
  /** Classes to be applied to brandName element */
  brandNameClass?: string
  /** Classes to be applied to skuName element */
  skuNameClass?: string
  /** Classes to be applied to productReference element */
  productReferenceClass?: string
  /** Classes to be applied to loader root element */
  loaderClass?: string
  /** HTML tag to be used in the component container */
  tag?: 'div' | 'h1' | 'h2' | 'h3'
  /** Used to override default CSS handles */
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
  /** Show product link with the product name */
  displayMode?: 'plainText' | 'linkToProductPage'
  /** Product link */
  productLink?: string
  /** Product id */
  productId?: string
} & DeprecatedProps

type LinkWrapperProps = {
  /** Show product link with the product name */
  displayMode: 'plainText' | 'linkToProductPage'
  /** Props for navigating to the product page */
  linkProps: LinkProps
  /** Classes to be applied to root element */
  className: string
  /** Component children that will be displayed */
  children: React.ReactNode
}

type LinkProps = {
  /** Page name */
  page: string
  /** Navigation params */
  params: Record<string, unknown>
}

/**
 * Shows the link associated with the product name or plain text depending on the displayMode.
 */
const LinkWrapper = ({
  displayMode,
  linkProps,
  className,
  children,
}: LinkWrapperProps) => {
  if (displayMode === 'plainText') {
    return <Fragment>{children}</Fragment>
  }

  return (
    <Link className={className} {...linkProps}>
      {children}
    </Link>
  )
}

function ProductName({
  productReferenceClass,
  brandNameClass,
  skuNameClass,
  loaderClass,
  className,
  showSku = false,
  showBrandName = false,
  showProductReference = false,
  showSponsoredBadge = false,
  sponsoredBadgeLabel,
  tag: Wrapper = 'div',
  classes,
  name,
  skuName,
  brandName,
  productReference,
  displayMode = 'plainText',
  productLink,
  productId,
}: Props) {
  const { handles } = useCssHandles(CSS_HANDLES, { classes })

  if (!name) {
    return (
      <div
        className={`${handles.productNameContainer} ${
          handles.productNameLoader
        } ${loaderClass ?? ''}`}
      >
        <ContentLoader
          style={{
            width: '100%',
            height: '100%',
          }}
          width={456}
          height={100}
          preserveAspectRatio="xMinYMin meet"
        >
          <rect height="1.125em" width="75%" x="15%" />
          <rect height="1.125em" width="50%" x="25%" y="1.75em" />
        </ContentLoader>
      </div>
    )
  }

  const linkProps = {
    page: 'store.product',
    params: {
      slug: productLink,
      id: productId,
    },
  }

  return (
    <Wrapper
      className={`${handles.productNameContainer} mv0 ${className ?? ''}`}
    >
      <LinkWrapper
        displayMode={displayMode}
        className={`${handles.productNameLink} pointer c-link hover-c-link active-c-link no-underline underline-hover`}
        linkProps={linkProps}
      >
        {showSponsoredBadge && (
          <span className={`${handles.sponsoredBadge} db c-muted-1 t-mini-s`}>
            <IOMessage id={sponsoredBadgeLabel} />
          </span>
        )}
        <span className={`${handles.productBrand} ${brandNameClass ?? ''}`}>
          {name} {showBrandName && brandName && `- ${brandName}`}
        </span>
        {showSku && skuName && (
          <span className={`${handles.productBrand} ${skuNameClass ?? ''}`}>
            {skuName}
          </span>
        )}
        {showProductReference && productReference && (
          <span
            className={`${handles.productReference} ${
              productReferenceClass ?? ''
            }`}
          >
            {`REF: ${productReference}`}
          </span>
        )}
      </LinkWrapper>
    </Wrapper>
  )
}

/**
 * Displays the product name along other information such as **SKU** or **brand**.
 */
function ProductNameWrapper(props: Props) {
  const valuesFromContext = useProduct()

  if (!valuesFromContext || isEmpty(valuesFromContext)) {
    return <ProductName {...props} />
  }

  const { product, selectedItem } = valuesFromContext

  return (
    <ProductName
      {...props}
      tag={props.tag ?? 'h1'}
      name={props.name ?? product?.productName}
      skuName={props.skuName ?? selectedItem?.name}
      productReference={props.productReference ?? product?.productReference}
      brandName={props.brandName ?? product?.brand}
      className={props.className ?? 't-heading-4'}
      displayMode={props.displayMode}
      productLink={product?.linkText}
      productId={product?.productId}
    />
  )
}

ProductNameWrapper.schema = {
  title: 'admin/editor.productName.title',
  description: 'admin/editor.productName.description',
  type: 'object',
  properties: {
    showBrandName: {
      type: 'boolean',
      title: 'admin/editor.productName.showBrandName.title',
      default: false,
      isLayout: true,
    },
    showSku: {
      type: 'boolean',
      title: 'admin/editor.productName.showSku.title',
      default: false,
      isLayout: true,
    },
    showProductReference: {
      type: 'boolean',
      title: 'admin/editor.productName.showProductReference.title',
      default: false,
      isLayout: true,
    },
    displayMode: {
      type: 'string',
      title: 'admin/editor.productName.displayMode.title',
      enum: ['plainText', 'linkToProductPage'],
      enumNames: [
        'admin/editor.productName.displayMode.plainText',
        'admin/editor.productName.displayMode.linkToProductPage',
      ],
      default: 'plainText',
    },
  },
}

export default ProductNameWrapper

```


[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-components/react/Logo.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { Link, useRuntime } from 'vtex.render-runtime'
import type { RenderContext } from 'vtex.render-runtime'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'
import * as Amp from 'react-amphtml'

import Placeholder from './components/Logo/LogoPlaceholder'
import styles from './components/Logo/styles.css'

const CSS_HANDLES = ['logoLink', 'logoImage', 'logoContainer'] as const

interface Props {
  /** Logo's URL */
  url: string
  /** Title to be displayed as alt text */
  title: string
  /** Logo's width */
  width?: string | number
  /** Logo's height */
  height?: string | number
  /** Link to redirect users on click */
  href?: string
  /** Logo's width on mobile */
  mobileWidth?: string | number
  /** Logo's height on mobile */
  mobileHeight?: string | number
  /** Used to override default CSS handles */
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * Store's logo.
 */
function Logo({
  url,
  href,
  width,
  height,
  title,
  mobileWidth,
  mobileHeight,
  classes,
}: Props) {
  const {
    amp,
    account,
    hints: { mobile },
  } = useRuntime() as RenderContext

  const { handles } = useCssHandles(CSS_HANDLES, { classes })
  const logoClassNames = `store-logo ${handles.logoContainer} ${
    mobile ? styles.sizeMobile : styles.sizeDesktop
  }`

  const imgWidth = mobile && mobileWidth ? mobileWidth : width
  const imgHeight = mobile && mobileHeight ? mobileHeight : height

  const imageUrl = url?.replace(/{{account}}/g, account)

  let image = null

  if (amp && url) {
    image = (
      <Amp.AmpImg
        specName="default"
        width={imgWidth}
        height={imgHeight}
        alt={title}
        src={imageUrl}
        className={handles.logoImage}
      />
    )
  } else if (url) {
    image = (
      <img
        src={imageUrl}
        width={imgWidth}
        height={imgHeight}
        alt={title}
        className={handles.logoImage}
      />
    )
  }

  const logo = (
    <span className={`${logoClassNames} pv4 ph6`}>
      {url ? (
        image
      ) : (
        <Placeholder width={width} height={height} title={title} />
      )}
    </span>
  )

  return href ? (
    <Link to={href} className={handles.logoLink}>
      {logo}
    </Link>
  ) : (
    logo
  )
}

Logo.schema = {
  title: 'admin/editor.logo.title',
  description: 'admin/editor.logo.description',
  type: 'object',
  properties: {
    href: {
      title: 'admin/editor.logo.href.title',
      description: 'admin/editor.logo.href.description',
      type: 'string',
    },
    url: {
      title: 'admin/editor.logo.url.title',
      description: 'admin/editor.logo.url.description',
      type: 'string',
      widget: {
        'ui:widget': 'image-uploader',
      },
    },
    width: {
      title: 'admin/editor.logo.width.title',
      description: 'admin/editor.logo.width.description',
      type: 'number',
      isLayout: true,
    },
    height: {
      title: 'admin/editor.logo.height.title',
      description: 'admin/editor.logo.height.description',
      type: 'number',
      isLayout: true,
    },
    title: {
      title: 'admin/editor.logo.title.title',
      description: 'admin/editor.logo.title.description',
      type: 'string',
    },
    mobileWidth: {
      title: 'admin/editor.logo.mobileWidth.title',
      description: 'admin/editor.logo.mobileWidth.description',
      type: 'number',
      isLayout: true,
    },
    mobileHeight: {
      title: 'admin/editor.logo.mobileHeight.title',
      description: 'admin/editor.logo.mobileHeight.description',
      type: 'number',
      isLayout: true,
    },
  },
}

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-components/react/Image.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { Image } from 'vtex.store-image'

export default Image

```


[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-components/react/AutocompleteResults.css from the store-components VTEX app.

[Assistant]
Here's the implementation:

```css
.resultsList {
  max-height: 60vh;
}

.resultsList a,
.resultsList div {
  text-decoration: none;
  color: #727273;
}

.resultsList a:hover {
  background-color: #f2f4f5;
}

.resultsItemImage {
  width: 50px;
}

@media only screen and (max-width: 49rem) {
  .resultsList {
    margin: 0px;
    max-height: calc(100vh - 6.2rem);
  }
}

```


[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-components/react/ProductHighlights.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductHighlights from './components/ProductHighlights/Wrapper'

export default ProductHighlights

```


[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-components/react/UserAddress.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect } from 'react'
import { useQuery } from 'react-apollo'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'
import ADDRESS_QUERY from 'vtex.store-resources/QueryAddress'

import Container from './Container'
import AddressInfo, {
  CSS_HANDLES as AddressInfoCssHandles,
} from './components/UserAddress/AddressInfo'
import { UserAddressCssHandlesProvider } from './components/UserAddress/UserAddressCssHandles'

export const USER_ADDRESS_CSS_HANDLES = [
  'userAddressContainer',
  ...AddressInfoCssHandles,
] as const

type Props = {
  /** Define if address should be displayed in a single line or in blocks */
  variation: 'inline' | 'bar'
  /** Define if street should be displayed */
  showStreet?: boolean
  /** Define if city and state should be displayed */
  showCityAndState?: boolean
  /** Define if postal code should be displayed */
  showPostalCode?: boolean
  /** Define if prefix should be displayed */
  showPrefix?: boolean
  /** Define if component should render if address is empty */
  showIfEmpty?: boolean
  /** Define if component should render if ZipCode contains asterics */
  showIfMasked?: boolean
  /** Used to override default CSS handles */
  classes?: CssHandlesTypes.CustomClasses<typeof USER_ADDRESS_CSS_HANDLES>
}

function UserAddress({
  variation,
  showStreet = true,
  showCityAndState = false,
  showPostalCode = false,
  showPrefix = true,
  showIfEmpty = false,
  showIfMasked = false,
  classes,
}: Props) {
  const { handles, withModifiers } = useCssHandles(USER_ADDRESS_CSS_HANDLES, {
    classes,
  })

  // todo: type the data returned
  const { data: orderFormData, refetch } = useQuery(ADDRESS_QUERY, {
    ssr: false,
  })

  useEffect(() => {
    const handleLocationUpdated = () => refetch()

    window.addEventListener('locationUpdated', handleLocationUpdated)

    return () => {
      window.removeEventListener('locationUpdated', handleLocationUpdated)
    }
  }, [refetch])

  const orderForm = orderFormData?.orderForm

  if (!orderForm || (!orderForm?.shippingData?.address && !showIfEmpty)) {
    return null
  }

  const isInline = variation === 'inline'
  const isInverted = !isInline

  const AddressInfoWithHandles = () => {
    return (
      <UserAddressCssHandlesProvider
        handles={handles}
        withModifiers={withModifiers}
      >
        <AddressInfo
          inverted={isInverted}
          inline={isInline}
          orderForm={orderForm}
          showStreet={showStreet}
          showCityAndState={showCityAndState}
          showPostalCode={showPostalCode}
          showPrefix={showPrefix}
          showIfEmpty={showIfEmpty}
          showIfMasked={showIfMasked}
        />
      </UserAddressCssHandlesProvider>
    )
  }

  if (isInline) {
    return (
      <div
        className={`${handles.userAddressContainer} ph5`}
        style={{
          maxWidth: '30rem',
        }}
      >
        <AddressInfoWithHandles />
      </div>
    )
  }

  return (
    <div
      className={`${handles.userAddressContainer} bg-base--inverted c-on-base--inverted flex ph5 pointer pv3 ml3 mr3`}
    >
      <Container className="flex justify-center w-100 left-0">
        <div className="w-100 mw9 flex">
          <AddressInfoWithHandles />
        </div>
      </Container>
    </div>
  )
}

export default UserAddress

```


[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-components/react/Slider.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Slider from './components/Slider/index'

export default Slider

```


[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-components/react/Animation.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Animation from './components/Animation/index'

export default Animation

```


[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-components/react/setupTests.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
window.__RUNTIME__ = {
  settings: {
    'vtex.store': {
      enableOrderFormOptimization: false,
      enableDefaultSeller: 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 store-components/react/ProductSKUAttributes.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

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

const CSS_HANDLES = [
  'productSKUAttributesContainer',
  'attributeLine',
  'attributeName',
  'attributeValue',
] as const

const getVariationsFromSelectedItem = (
  productContext: ReturnType<typeof useProduct>
) => {
  if (
    !productContext ||
    !productContext.product ||
    !productContext.skuSelector ||
    !productContext.selectedItem
  ) {
    return null
  }

  const { selectedImageVariationSKU } = productContext.skuSelector

  if (selectedImageVariationSKU) {
    const selected = productContext.product.items.find(item => {
      return item.itemId === selectedImageVariationSKU
    })

    if (selected) {
      return selected.variations
    }
  }

  return productContext.selectedItem.variations
}

interface Props {
  blockClass?: string
  /** Used to override default CSS handles */
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
}

/**
 * Name component. Show name and relevant SKU information of the Product Summary
 */
function ProductSKUAttributes({ classes }: Props) {
  const { handles } = useCssHandles(CSS_HANDLES, { classes })
  const productContext = useProduct()

  const skuVariations = getVariationsFromSelectedItem(productContext)

  if (!skuVariations) {
    return null
  }

  return (
    <div className={`${handles.productSKUAttributesContainer} mv0`}>
      {skuVariations.map(sku => {
        return (
          <div className={handles.attributeLine} key={sku.name}>
            <span className={`${handles.attributeName} mr2 b`}>
              {sku.name}:
            </span>
            <span className={handles.attributeValue}>
              {sku.values.join(', ')}
            </span>
          </div>
        )
      })}
    </div>
  )
}

export default ProductSKUAttributes

```


[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-components/react/Newsletter.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Newsletter from './components/Newsletter/index'

export default Newsletter

```


[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-components/react/ProductPrice.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductPrice from './components/ProductPrice/Wrapper'

export default ProductPrice

```


[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-components/react/Share.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Share from './components/Share/Wrapper'

export default Share

```


[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-components/react/ProductSpecifications.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductSpecifications from './components/ProductSpecifications/Wrapper'

export default ProductSpecifications

```


[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-components/store/contentSchemas.json from the store-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "definitions": {
    "InfoCard": {
      "properties": {
        "isFullModeStyle": {
          "title": "admin/editor.info-card.isFullModeStyle.title",
          "description": "admin/editor.info-card.isFullModeStyle.description",
          "type": "boolean",
          "default": false
        },
        "textMode": {
          "default": "html",
          "type": "string",
          "title": "admin/editor.info-card.textMode.title",
          "enum": ["html", "rich-text"],
          "enumNames": [
            "admin/editor.info-card.textMode.html",
            "admin/editor.info-card.textMode.rich-text"
          ]
        },
        "headline": {
          "title": "admin/editor.info-card.headline.title",
          "description": "admin/editor.info-card.headline.description",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "subhead": {
          "title": "admin/editor.info-card.subhead.title",
          "description": "admin/editor.info-card.subhead.description",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "bodyText": {
          "title": "admin/editor.info-card.body-text.title",
          "description": "admin/editor.info-card.body-text.description",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "callToActionMode": {
          "default": "button",
          "type": "string",
          "title": "admin/editor.info-card.callToActionMode.title",
          "enum": ["none", "button", "link"],
          "enumNames": [
            "admin/editor.info-card.callAction.none",
            "admin/editor.info-card.callAction.button",
            "admin/editor.info-card.callAction.link"
          ]
        },
        "callToActionText": {
          "title": "admin/editor.info-card.callToActionText.title",
          "description": "admin/editor.info-card.callToActionText.description",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "callToActionUrl": {
          "title": "admin/editor.info-card.callToActionUrl.title",
          "description": "admin/editor.info-card.callToActionUrl.description",
          "$ref": "app:vtex.native-types#/definitions/url",
          "default": ""
        },
        "callToActionLinkTarget": {
          "default": "_self",
          "type": "string",
          "title": "admin/editor.info-card.callToActionLinkTarget.title",
          "enum": ["_blank", "_self"],
          "enumNames": [
            "admin/editor.info-card.callToActionLinkTarget.blank",
            "admin/editor.info-card.callToActionLinkTarget.self"
          ]
        },
        "imageUrl": {
          "title": "admin/editor.info-card.imageUrl.title",
          "description": "admin/editor.info-card.imageUrl.description",
          "$ref": "app:vtex.native-types#/definitions/url",
          "default": "",
          "widget": {
            "ui:widget": "image-uploader"
          }
        },
        "mobileImageUrl": {
          "title": "admin/editor.info-card.mobileImageUrl.title",
          "description": "admin/editor.info-card.mobileImageUrl.description",
          "$ref": "app:vtex.native-types#/definitions/url",
          "default": "",
          "widget": {
            "ui:widget": "image-uploader"
          }
        },
        "imageActionUrl": {
          "title": "admin/editor.info-card.imageActionUrl.title",
          "description": "admin/editor.info-card.imageActionUrl.description",
          "$ref": "app:vtex.native-types#/definitions/url",
          "default": ""
        },
        "textPosition": {
          "default": "left",
          "type": "string",
          "title": "admin/editor.info-card.textPosition.title",
          "enum": ["left", "center", "right"],
          "enumNames": [
            "admin/editor.info-card.textPosition.left",
            "admin/editor.info-card.textPosition.center",
            "admin/editor.info-card.textPosition.right"
          ]
        },
        "textAlignment": {
          "default": "left",
          "type": "string",
          "title": "admin/editor.info-card.textAlignment.title",
          "enum": ["left", "center", "right"],
          "enumNames": [
            "admin/editor.info-card.textAlignment.left",
            "admin/editor.info-card.textAlignment.center",
            "admin/editor.info-card.textAlignment.right"
          ]
        },
        "blockClass": {
          "title": "admin/editor.blockClass.title",
          "description": "admin/editor.blockClass.description",
          "type": "string"
        }
      }
    },
    "ProductDescription": {
      "title": "admin/editor.product-description.title",
      "type": "object",
      "properties": {
        "title": {
          "$ref": "app:vtex.native-types#/definitions/text",
          "title": "admin/editor.product-description.title-prop.title"
        }
      }
    },
    "SearchBar": {
      "title": "admin/editor.search-bar.title",
      "type": "object",
      "properties": {
        "placeholder": {
          "$ref": "app:vtex.native-types#/definitions/text",
          "title": "admin/editor.search-bar.placeholder.title"
        }
      }
    },
    "ProductPrice": {
      "properties": {
        "labelSellingPrice": {
          "title": "admin/editor.productPrice.labelSellingPrice",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": "store/pricing.to"
        },
        "labelListPrice": {
          "title": "admin/editor.productPrice.labelListPrice",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": "store/pricing.from"
        }
      }
    },
    "Newsletter": {
      "properties": {
        "placeholder": {
          "title": "admin/editor.newsletter.placeholder",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": "store/newsletter.placeholder"
        },
        "label": {
          "title": "admin/editor.newsletter.label",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": "store/newsletter.label"
        },
        "submit": {
          "title": "admin/editor.newsletter.submit",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": "store/newsletter.submit"
        }
      }
    },
    "SKUSelector": {
      "type": "object",
      "properties": {
        "seeMoreLabel": {
          "title": "admin/editor.skuSelector.seeMoreLabel.title",
          "description": "admin/editor.skuSelector.seeMoreLabel.description",
          "default": "store/skuSelector.seeMore",
          "$ref": "app:vtex.native-types#/definitions/text"
        }
      }
    },
    "NotificationBar": {
      "type": "object",
      "description": "admin/editor.notification-bar.description",
      "properties": {
        "content": {
          "title": "admin/editor.notification-bar.content.title",
          "description": "admin/editor.notification-bar.content.description",
          "$ref": "app:vtex.native-types#/definitions/text"
        }
      }
    }
  }
}

```


[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-components/store/interfaces.json from the store-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "logo": {
    "component": "Logo"
  },
  "search-bar": {
    "component": "SearchBar",
    "allowed": ["autocomplete-result-list", "icon-search", "icon-close"],
    "content": {
      "$ref": "app:vtex.store-components#/definitions/SearchBar"
    }
  },
  "autocomplete-result-list": {
    "component": "AutocompleteResults"
  },
  "buy-button": {
    "component": "BuyButton"
  },
  "product-name": {
    "component": "ProductName"
  },
  "product-sku-attributes": {
    "component": "ProductSKUAttributes"
  },
  "product-brand": {
    "component": "ProductBrand"
  },
  "product-images": {
    "component": "ProductImages"
  },
  "product-images.high-quality-image": {
    "component": "HighQualityProductImage"
  },
  "product-price": {
    "component": "ProductPrice",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/ProductPrice"
    }
  },
  "product-description": {
    "component": "ProductDescription",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/ProductDescription"
    }
  },
  "product-separator": {
    "component": "ProductSeparator"
  },
  "sku-selector": {
    "component": "SKUSelector",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/SKUSelector"
    }
  },
  "shipping-simulator": {
    "component": "ShippingSimulator"
  },
  "share": {
    "component": "Share"
  },
  "availability-subscriber": {
    "component": "AvailabilitySubscriber"
  },
  "product-specifications": {
    "component": "ProductSpecifications"
  },
  "product-highlights": {
    "component": "ProductHighlights"
  },
  "info-card": {
    "component": "InfoCard",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/InfoCard"
    }
  },
  "user-address": {
    "allowed": ["modal"],
    "component": "UserAddress"
  },
  "product-services": {
    "component": "ProductServices"
  },
  "newsletter": {
    "component": "Newsletter",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/Newsletter"
    }
  },
  "notification": {},
  "notification.inline": {
    "component": "NotificationInline",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/NotificationBar"
    }
  },
  "notification.bar": {
    "component": "NotificationBar",
    "content": {
      "$ref": "app:vtex.store-components#/definitions/NotificationBar"
    }
  },
  "image": {
    "component": "Image",
    "content": {
      "$ref": "app:vtex.store-image#/definitions/Image"
    }
  },
  "back-to-top-button": {
    "render": "client",
    "component": "BackToTopButton"
  }
}

```


[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-components/react/typings/storefront.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { FunctionComponent } from 'react'

type GenericObject = Record<string, any>

declare global {
  interface StorefrontFC<P = GenericObject> extends FunctionComponent<P> {
    getSchema?(props: P): GenericObject
    schema?: GenericObject
  }

  interface StorefrontComponent<P = GenericObject, S = GenericObject>
    extends Component<P, S> {
    getSchema?(props: P): GenericObject
    schema: GenericObject
  }
}

```


[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-components/react/typings/jsx.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import 'react'

declare module 'react' {
  interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
    loading?: 'lazy' | 'eager' | 'auto'
    fetchPriority?: 'high' | 'low' | 'auto'
  }
}

```


[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-components/react/typings/vtex.product-context.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
interface ProductItem {
  itemId: string
  name: string
  images: Image[]
  variations: Array<{
    name: string
    values: string[]
  }>
  sellers: Array<{
    sellerDefault: boolean
    commertialOffer: {
      Price: number
      ListPrice: number
      AvailableQuantity: number
    }
  }>
}

interface Product {
  brand: string
  brandId: string
  itemMetadata: ItemMetadata
  items: ProductItem[]
  linkText: string
  productId: string
  skuSpecifications: SkuSpecification[]
  productName: string
  productReference: string
  brand: string
  description: string
}

interface SkuSpecification {
  field: SkuSpecificationField
  values: SkuSpecificationValues[]
}

interface SkuSpecificationField {
  name: string
  originalName: string
}

interface SkuSpecificationValues {
  name: string
  originalName: string
}

declare module 'vtex.product-context/ProductDispatchContext' {
  type DispatchFunction = (payload: { type: string; args?: any }) => void
  export const useProductDispatch: () => DispatchFunction
}

declare module 'vtex.product-context' {
  export interface Seller {
    sellerDefault: boolean
    commertialOffer: {
      Price: number
      AvailableQuantity: number
    }
  }

  type GroupId = string

  interface AssemblyOptionItem {
    id: string
    quantity: number
    seller: string
    initialQuantity: number
    choiceType: string
    name: string
    price: number
    children: Record<string, AssemblyOptionItem[]> | null
  }

  type InputValues = Record<string, string>

  export interface ProductContext {
    product?: Product
    selectedItem: ProductItem | null
    selectedQuantity: number
    skuSelector: {
      isVisible: boolean
      areAllVariationsSelected: boolean
      selectedImageVariationSKU: string
    }
    buyButton: {
      clicked: boolean
    }
    assemblyOptions: {
      items: Record<GroupId, AssemblyOptionItem[]>
      inputValues: Record<GroupId, InputValues>
      areGroupsValid: Record<GroupId, boolean>
    }
  }

  export const useProduct: () => ProductContext
  type DispatchFunction = (payload: { type: string; args?: any }) => void
  export const useProductDispatch: () => DispatchFunction
  export const ProductContext
}

```


[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-components/react/typings/vtex.device-detector.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.device-detector' {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const useDevice: any
}

```


[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-components/react/typings/css.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const css: any
  export default css
}

```


[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-components/react/typings/json.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.json' {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const value: any
  export default value
}

```


[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-components/react/typings/product.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface Product {
  linkText: string
  productName: string
  brand: string
  categoryId: string
  categoryTree: Category[]
  productId: string
  titleTag: string
  metaTagDescription: string
  items: SKU[]
  skuSpecifications: SkuSpecification[]
}

export interface Category {
  id: string
  name: string
}

export interface SKU {
  itemId: string
  ean: string
  referenceId: [{ Value: string }]
  sellers: Seller[]
}

interface Seller {
  commertialOffer: CommertialOffer
  sellerId: string
}

interface CommertialOffer {
  ListPrice: number
  Price: number
}

interface Seller {
  commertialOffer: CommertialOffer
}

interface CommertialOffer {
  AvailableQuantity: number
}

interface SkuSpecification {
  field: SkuSpecificationField
  values: SkuSpecificationValues[]
}

interface SkuSpecificationField {
  name: string
}

interface SkuSpecificationValues {
  name: string
}

```


[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-components/react/typings/graphql.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.gql' {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const graphql: any
  export default graphql
}

```


[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-components/react/typings/vtex.store-resources.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.store-resources/OrderFormContext' {
  export const orderFormConsumer
}

declare module 'vtex.store-resources/QueryAddress'

```


[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-components/react/typings/vtex.styleguide.d.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module 'vtex.styleguide' {
  export const Checkbox: any
  export const Radio: any
  export const NumericStepper: any
  export const Button: any
  export const Modal: any
  export const withToast: any
  export const Tooltip: any
  // eslint-disable-next-line @typescript-eslint/naming-convention
  export const EXPERIMENTAL_Select: any
  export const Dropdown: any
  export const Input: any
  export const Spinner: any
  export const InputSearch: any
}

```


[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-components/react/utils/sellers.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Seller } from 'vtex.product-context'

export function getDefaultSeller(sellers?: Seller[]) {
  if (!sellers || sellers.length === 0) {
    return
  }

  const defaultSeller = sellers.find(seller => seller.sellerDefault)

  if (defaultSeller) {
    return defaultSeller
  }

  return sellers[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-components/react/utils/imgUrlHelpers.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const DEFAULT_WIDTH = 'auto'
export const DEFAULT_HEIGHT = 'auto'
export const MAX_WIDTH = 3000
export const MAX_HEIGHT = 4000

/**
 * Having the url below as base for the LEGACY file manager,
 * https://storecomponents.vteximg.com.br/arquivos/ids/155472/Frame-3.jpg?v=636793763985400000
 * the following regex will match https://storecomponents.vteximg.com.br/arquivos/ids/155472
 *
 * Also matches urls with defined sizes like:
 * https://storecomponents.vteximg.com.br/arquivos/ids/155473-160-auto
 * @type {RegExp}
 *
 * On the new vtex.file-manager isn't necessary replace the URL, just add the param on the querystring, like:
 * "?width=WIDTH&height=HEIGHT&aspect=true"
 *
 */
const baseUrlRegex = new RegExp(/.+ids\/(\d+)/)

const httpRegex = new RegExp(/http:\/\//)

export function toHttps(url: string) {
  return url.replace(httpRegex, 'https://')
}

export function cleanImageUrl(imageUrl: string) {
  const result = baseUrlRegex.exec(imageUrl)

  if (result && result.length > 0) {
    return result[0]
  }

  return null
}

function replaceLegacyFileManagerUrl(
  imageUrl: string,
  width: number | string,
  height: number | string
) {
  const legacyUrlPattern = '/arquivos/ids/'
  const isLegacyUrl = imageUrl.includes(legacyUrlPattern)

  if (!isLegacyUrl) {
    return imageUrl
  }

  return `${cleanImageUrl(imageUrl)}-${width}-${height}`
}

export function changeImageUrlSize({
  imageUrl,
  width = DEFAULT_WIDTH,
  height = DEFAULT_HEIGHT,
}: {
  imageUrl: string
  width?: string | number
  height?: string | number
}) {
  let adjustedWidth = width
  let adjustedHeight = height

  if (typeof width === 'number') {
    adjustedWidth = Math.min(width, MAX_WIDTH)
  }

  if (typeof height === 'number') {
    adjustedHeight = Math.min(height, MAX_HEIGHT)
  }

  const normalizedImageUrl = replaceLegacyFileManagerUrl(
    imageUrl,
    adjustedWidth,
    adjustedHeight
  )

  const queryStringSeparator = normalizedImageUrl.includes('?') ? '&' : '?'

  return `${normalizedImageUrl}${queryStringSeparator}width=${adjustedWidth}&height=${adjustedHeight}&aspect=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 store-components/react/utils/useCommercialOffer.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useRuntime } from 'vtex.render-runtime'
import { path } from 'ramda'
import { ProductContextState } from 'vtex.product-context/react/ProductTypes'

import { getDefaultSeller } from './sellers'

export const useCommercialOffer = (
  valuesFromContext: Partial<ProductContextState>
) => {
  const renderRuntime = useRuntime()

  const { selectedItem } = valuesFromContext

  const settings = renderRuntime?.getSettings?.('vtex.store')

  if (settings?.enableDefaultSeller) {
    return getDefaultSeller(selectedItem?.sellers)?.commertialOffer
  }

  console.warn(
    'In feature releases the enableDefaultSeller setting will be removed, and the commercialOffer will be calculated only by defaultSeller'
  )

  return path(['sellers', 0, 'commertialOffer'], selectedItem)
}

```


[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-components/react/components/SanitizedHTML.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useMemo, FC } from 'react'
import insane from '@vtex/insane'

type SanitizeOpts = {
  allowedAttributes?: Record<string, string[]>
  allowedClasses?: Record<string, string[]>
  allowedTags?: string[]
}

type SanitizedHTMLProps = SanitizeOpts & {
  content: string
}

export const DEFAULTS = {
  allowedAttributes: {
    '*': [
      'id',
      'title',
      'accesskey',
      'class',
      'style',
      'aria-label',
      'width',
      'height',
      'hidden',
    ],
    a: ['href', 'name', 'target'],
    iframe: ['allow', 'allowfullscreen', 'frameborder', 'src'],
    img: ['src', 'alt'],
    link: ['rel', 'type', 'href'],
    td: ['colspan', 'rowspan', 'headers'],
  },
  allowedClasses: {},
  allowedSchemes: ['http', 'https', 'mailto', 'tel'],
  allowedTags: [
    'a',
    'abbr',
    'article',
    'b',
    'blockquote',
    'br',
    'caption',
    'code',
    'del',
    'details',
    'div',
    'em',
    'figure',
    'h1',
    'h2',
    'h3',
    'h4',
    'h5',
    'h6',
    'hr',
    'header',
    'footer',
    'i',
    'img',
    'ins',
    'iframe',
    'kbd',
    'li',
    'main',
    'mark',
    'ol',
    'p',
    'picture',
    'pre',
    'section',
    'source',
    'span',
    'strike',
    'strong',
    'sub',
    'summary',
    'sup',
    'table',
    'tbody',
    'td',
    'th',
    'thead',
    'tr',
    'u',
    'ul',
  ],
}

function sanitizeHTML(
  html: string,
  { allowedAttributes, allowedClasses, allowedTags }: SanitizeOpts = {}
) {
  const opts: Record<string, any> = { ...DEFAULTS }

  if (allowedTags) opts.allowedTags = allowedTags
  if (allowedClasses) opts.allowedClasses = allowedClasses
  if (allowedAttributes) opts.allowedAttributes = allowedAttributes

  return insane(html, opts)
}

function getDangerousSanitizedHTML(html: string, opts: SanitizeOpts = {}) {
  return { __html: sanitizeHTML(html, opts) }
}

function useSanitizedHTML(
  html: string,
  { allowedAttributes, allowedClasses, allowedTags }: SanitizeOpts = {}
) {
  const sanitizedHTML = useMemo(() => {
    return getDangerousSanitizedHTML(html, {
      allowedAttributes,
      allowedClasses,
      allowedTags,
    })
  }, [allowedAttributes, allowedClasses, allowedTags, html])

  return sanitizedHTML
}

export const SanitizedHTML: FC<SanitizedHTMLProps> = ({
  content,
  allowedAttributes,
  allowedClasses,
  allowedTags,
}) => {
  const sanitizedContent = useSanitizedHTML(content, {
    allowedAttributes,
    allowedClasses,
    allowedTags,
  })

  if (!content) {
    return null
  }

  return (
    <div
      // Display 'contents' is used so this div doesn't affect the layout
      style={{ display: 'contents' }}
      dangerouslySetInnerHTML={sanitizedContent}
    />
  )
}

```


[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-components/react/components/CollectionBadges.test.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

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

import CollectionBadges from './CollectionBadges'

describe('<CollectionBadges /> component', () => {
  it('should match snapshot without badges', () => {
    const { container } = render(<CollectionBadges>Test</CollectionBadges>)

    expect(container.firstChild).toMatchInlineSnapshot(`
      <div
        class="collectionContainer relative dib w-100"
      >
        Test
        <div
          class="inline-flex justify-end absolute w-100 bottom-0 left-0"
        />
      </div>
    `)
  })

  it('should match snapshot with badges', () => {
    const { container } = render(
      <CollectionBadges collectionBadgesText={['badge1', 'badge2']}>
        Test
      </CollectionBadges>
    )

    expect(container.firstChild).toMatchInlineSnapshot(`
      <div
        class="collectionContainer relative dib w-100"
      >
        Test
        <div
          class="inline-flex justify-end absolute w-100 bottom-0 left-0"
        >
          <div
            class="item mh1 pa2 bg-blue white tc"
          >
            badge1
          </div>
          <div
            class="item mh1 pa2 bg-blue white tc"
          >
            badge2
          </div>
        </div>
      </div>
    `)
  })
})

```


[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-components/react/components/CollectionBadges.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

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

export type Props = {
  collectionBadgesText?: string[]
}

const HANDLES = ['collectionContainer', 'item'] as const

/**
 * @deprecated This component is deprecated. Please use [vtex.product-highlights](https://github.com/vtex-apps/product-highlights) instead.
 */
const CollectionBadges: FC<Props> = ({
  collectionBadgesText = [],
  children,
}) => {
  const { handles } = useCssHandles(HANDLES)

  return (
    <div className={`${handles.collectionContainer} relative dib w-100`}>
      {children}
      <div className="inline-flex justify-end absolute w-100 bottom-0 left-0">
        {collectionBadgesText.map((collectionBadgeText, index) => (
          <div
            key={`${collectionBadgeText}-${index}`}
            className={`${handles.item} mh1 pa2 bg-blue white tc`}
          >
            {collectionBadgeText}
          </div>
        ))}
      </div>
    </div>
  )
}

export default CollectionBadges

```


[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-components/react/graphql/addToAvailabilitySubscriberMutation.gql from the store-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation availabilitySubscribe($acronym: String!, $document: DocumentInput) {
  createDocument(acronym: $acronym, document: $document)
    @context(provider: "vtex.store-graphql") {
    cacheId
    id
    href
    documentId
  }
}

```


[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-components/react/graphql/productBrand.gql from the store-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Brand($id: Int) {
  brand(id: $id) @context(provider: "vtex.store-graphql") {
    slug
    imageUrl
  }
}

```


[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-components/react/graphql/autocomplete.gql from the store-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Autocomplete($maxRows: Int, $inputValue: String) {
  autocomplete(maxRows: $maxRows, searchTerm: $inputValue)
    @context(provider: "vtex.search-graphql") {
    itemsReturned {
      thumb
      name
      href
      productId
      criteria
      slug
    }
  }
}

```


[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-components/react/components/SearchBar/SearchBar.css from the store-components VTEX app.

[Assistant]
Here's the implementation:

```css
.searchBarContainer :global(.vtex-input-prefix__group) {
  height: 38px;
}

.searchBarContainer input {
  color: #727273;
  border-radius: 1px;
}

.compactMode input {
  border-top-style: none !important;
  border-left-style: none !important;
  border-right-style: none !important;
  border-bottom: 2px solid !important;
}

.paddingInput input {
  -webkit-appearance: none;
  padding-left: 40px !important;
}

.searchMobile .vtex-button {
  padding: 0.9rem;
  font-weight: 400;
  font-size: 0.875rem;
}

.searchMobile input {
  border: none;
}

@media only screen and (max-width: 49rem) {
  .searchBarContainer input {
    box-shadow: none;
  }
}

.visuallyHidden {
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

```


[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-components/react/components/SearchBar/AutocompleteInput.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useRef, useEffect } from 'react'
import classNames from 'classnames'
import { Input, InputSearch } from 'vtex.styleguide'
import { ExtensionPoint, useChildBlock } from 'vtex.render-runtime'
import { IconSearch, IconClose } from 'vtex.store-icons'
import type { DownshiftProps } from 'downshift'
import { useIntl } from 'react-intl'

import { useSearchBarCssHandles } from './SearchBarCssHandles'

const DISPLAY_MODES = [
  'clear-button',
  'search-and-clear-buttons',
  'search-button',
]

/** Midleware component to adapt the styleguide/Input to be used by the Downshift */
export const CSS_HANDLES = [
  'autoCompleteOuterContainer',
  'compactMode',
  'externalSearchButtonWrapper',
  'paddingInput',
  'searchBarClearIcon',
  'searchBarIcon',
  'searchBarSearchIcon',
  'suffixWrapper',
] as const

const CloseIcon = () => {
  const hasIconBlock = Boolean(useChildBlock({ id: 'icon-close' }))

  if (hasIconBlock) {
    return <ExtensionPoint id="icon-close" size={16} type="line" />
  }

  return <IconClose type="line" size={16} />
}

const SearchIcon = () => {
  const hasIconBlock = Boolean(useChildBlock({ id: 'icon-search' }))

  if (hasIconBlock) {
    return <ExtensionPoint id="icon-search" />
  }

  return <IconSearch />
}

interface Props {
  /** Downshift prop to be passed to the input */
  autoComplete?: string
  /** Input ID */
  id?: string
  /** Downshift prop to be passed to the input */
  onBlur?: () => void
  /** Downshift prop to be passed to the input */
  onChange?: DownshiftProps<any>['onChange']
  /** Downshift prop to be passed to the input */
  onKeyDown?: (event: any) => void
  /** Downshift prop to be passed to the input */
  value?: string
  /** Downshift func to open the menu */
  openMenu?: () => void
  /** Placeholder to be used on the input */
  placeholder?: string
  compactMode?: boolean
  /** Clears the input */
  onClearInput: () => void
  /** Identify if the search icon is on left or right position */
  hasIconLeft?: boolean
  /** Custom classes for the search icon */
  iconClasses?: string
  /** Block class for the search icon */
  iconBlockClass?: string
  /** Identify if the search input should autofocus or not */
  autoFocus?: boolean
  /** Function to direct the user to the searchPage */
  onGoToSearchPage: () => void
  /**
   * @deprecated Use `displayMode`
   * Identify if icon should submit on click
   * */
  submitOnIconClick?: boolean
  /* Define the input display mode */
  displayMode?: 'clear-button' | 'search-and-clear-buttons' | 'search-button'
  /** Error message showed in search input */
  inputErrorMessage?: string
  /** The type of the search input */
  inputType?: 'text' | 'search'
  openAutocompleteOnFocus?: boolean
  onInputChange: DownshiftProps<any>['onChange']
  inputValue: string
}

function AutocompleteInput({
  onClearInput,
  compactMode,
  value,
  hasIconLeft,
  iconBlockClass,
  iconClasses,
  autoFocus,
  onGoToSearchPage,
  submitOnIconClick,
  displayMode = 'clear-button',
  openMenu,
  inputErrorMessage,
  inputType = 'text',
  openAutocompleteOnFocus,
  ...restProps
}: Props) {
  const { handles, withModifiers } = useSearchBarCssHandles()
  const inputRef = useRef<HTMLInputElement>(null)

  const intl = useIntl()

  let dMode = displayMode

  if (DISPLAY_MODES.indexOf(dMode) < 0) {
    console.error(
      `[store-components/search-bar] Invalid displayMode '${displayMode}'. The valid options are: ${DISPLAY_MODES.join(
        ', '
      )}`
    )
  }

  // for backward compatibility
  if (submitOnIconClick === true) {
    dMode = 'search-button'
  } else if (submitOnIconClick === false) {
    dMode = 'clear-button'
  }

  useEffect(() => {
    const changeClassInput = () => {
      // eslint-disable-next-line vtex/prefer-early-return
      if (compactMode && inputRef.current) {
        inputRef.current.placeholder = ''
        inputRef.current.classList.add(handles.paddingInput)
      }
    }

    changeClassInput()
    if (autoFocus) inputRef.current?.focus()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  const hasValue = value != null && value.length > 0

  const showClearButton =
    (dMode === 'clear-button' && hasValue) ||
    dMode === 'search-and-clear-buttons'

  const showInternalSearchButton =
    (dMode === 'clear-button' && !hasValue) || dMode === 'search-button'

  const showExternalSearchButton = dMode === 'search-and-clear-buttons'

  const clearButton = showClearButton && (
    <button
      className={`${iconClasses ?? ''} ${withModifiers(
        'searchBarIcon',
        'clear'
      )} flex items-center pointer bn bg-transparent outline-0 pv0 pl0 pr3`}
      style={{
        visibility: hasValue ? 'visible' : 'hidden',
      }}
      aria-label={intl.formatMessage({
        id: 'store/search.clear-input',
      })}
      onClick={() => onClearInput()}
    >
      <CloseIcon />
    </button>
  )

  const internalSearchButton = showInternalSearchButton && (
    <button
      className={`${iconClasses ?? ''} ${withModifiers(
        'searchBarIcon',
        'search'
      )} flex items-center pointer bn bg-transparent outline-0 pv0 pl0 pr3`}
      onClick={() => hasValue && onGoToSearchPage()}
      aria-label={intl.formatMessage({
        id: 'store/search.submit-search',
      })}
    >
      <SearchIcon />
    </button>
  )

  const externalSearchButton = showExternalSearchButton && (
    <div
      className={`${handles.externalSearchButtonWrapper} bw1 bl b--muted-4 flex items-center `}
    >
      <button
        className={`${iconClasses ?? ''} ${withModifiers(
          'searchBarIcon',
          'external-search'
        )}  flex items-center h-100 pointer pv0 nr5 ph5 bn c-link`}
        onClick={onGoToSearchPage}
        aria-label={intl.formatMessage({
          id: 'store/search.submit-search',
        })}
      >
        <SearchIcon />
      </button>
    </div>
  )

  const suffix = (
    <div className={`${handles.suffixWrapper} flex h-100`}>
      {clearButton}
      {internalSearchButton}
      {externalSearchButton}
    </div>
  )

  const prefix = (
    <span
      className={`${iconClasses} ${withModifiers('searchBarIcon', 'prefix')} `}
    >
      <SearchIcon />
    </span>
  )

  const classContainer = classNames('w-100 flex', {
    [handles.compactMode]: compactMode,
  })

  if (inputType === 'search') {
    // <form> tag is needed for iOS:
    // https://stackoverflow.com/a/26287843
    return (
      <form
        action="#"
        onSubmit={e => {
          e.preventDefault()
          e.stopPropagation()
          e.nativeEvent.stopImmediatePropagation()
        }}
        className={handles.autoCompleteOuterContainer}
      >
        <div className={classContainer}>
          <InputSearch
            ref={inputRef}
            size="large"
            value={value}
            {...restProps}
            error={Boolean(inputErrorMessage)}
            errorMessage={inputErrorMessage}
            onSubmit={onGoToSearchPage}
            aria-label={intl.formatMessage({
              id: 'store/search.autocompleteInput.aria-label',
            })}
          />
        </div>
      </form>
    )
  }

  return (
    <div className={handles.autoCompleteOuterContainer}>
      <div className={classContainer}>
        <Input
          ref={inputRef}
          size="large"
          value={value}
          prefix={hasIconLeft && prefix}
          suffix={suffix}
          {...restProps}
          error={Boolean(inputErrorMessage)}
          errorMessage={inputErrorMessage}
          aria-label={intl.formatMessage({
            id: 'store/search.autocompleteInput.aria-label',
          })}
        />
      </div>
    </div>
  )
}

export default AutocompleteInput

```


[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-components/react/components/SearchBar/SearchBar.tsx from the store-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useRef, useCallback, useState, useEffect, useMemo } from 'react'
import classNames from 'classnames'
import Downshift, {
  DownshiftProps,
  DownshiftState,
  StateChangeOptions,
} from 'downshift'
import debounce from 'debounce'
import {
  NoSSR,
  useRuntime,
  ExtensionPoint,
  useChildBlock,
} from 'vtex.render-runtime'
import { Overlay } from 'vtex.react-portal'
import { defineMessages, useIntl } from 'react-intl'
import { formatIOMessage } from 'vtex.native-types'

import styles from './SearchBar.css'
import AutocompleteResults from '../../AutocompleteResults'
import type { Props as AutocompleteResultsProps } from '../../AutocompleteResults'
import AutocompleteInput from './AutocompleteInput'
import { useSearchBarCssHandles } from './SearchBarCssHandles'

export const CSS_HANDLES = ['searchBarInnerContainer'] as const

const SEARCH_DELAY_TIME = 1000
const AUTOCOMPLETE_EXTENSION_ID = 'autocomplete-result-list'

const messages = defineMessages({
  searchTermTooShort: {
    id: 'store/search.search-term-too-short',
    defaultMessage: '',
  },
})

interface Props {
  /** Placeholder to be used on the input */
  placeholder: string
  /** Current value of the input */
  inputValue: string
  /** Function to handle input changes */
  onInputChange: DownshiftProps<any>['onChange']
  /** Function to direct the user to the searchPage */
  onGoToSearchPage: () => void
  /** Function to clear the input */
  onClearInput: () => void
  /** Indentify when use the compact version of the component */
  compactMode?: boolean
  /** Identify if the search icon is on left or right position */
  hasIconLeft?: boolean
  /** Custom classes for the search icon */
  iconClasses?: string
  /** Block class for the search icon */
  iconBlockClass?: string
  /** Identify if the search input should autofocus or not */
  autoFocus?: boolean
  /** Max width of the search bar */
  maxWidth?: string | number
  /** A template for a custom url. It can have a substring ${term} used as placeholder to interpolate the searched term. (e.g. `/search?query=${term}`) */
  customSearchPageUrl?: string
  /** Uses the term the user has inputed to try to navigate to the proper
   * page type (e.g. a department, a brand, a category)
   */
  attemptPageTypeSearch?: boolean
  /* Autocomplete Horizontal alignment */
  autocompleteAlignment?: 'right' | 'left' | 'center'
  /** Identify if autocomplete should be open on input focus or not */
  openAutocompleteOnFocus?: boolean
  /** Identify if input should blur on submit */
  blurOnSubmit?: boolean
  /** Identify if icon should submit on click */
  submitOnIconClick?: boolean
  /** Minimum search term length allowed */
  minSearchTermLength?: number
  /** If true, the autocomplete will fill the whole window horizontally */
  autocompleteFullWidth?: boolean
  /** The type of the search input */
  inputType?: 'text' | 'search'
  /** Define the component display mode,such as which buttons should be visible */
  displayMode?: 'clear-button' | 'search-and-clear-buttons' | 'search-button'
  /** Define how the autocomplete component should be displayed. Possible values are: `overlay` (suggestions overlapping other components) and `container` (displays the suggestion within a container). */
  containerMode: 'overlay' | 'container'
  /** The autocomplete can have touchable/clickable components. Interacting with those components may trigger blur and touch events that will close the autcomplete. When set to true, this prop will disable those handlers */
  disableBlurAndTouchEndHandler?: boolean
}

function SearchBar({
  placeholder,
  onInputChange,
  onGoToSearchPage,
  onClearInput,
  inputValue,
  compactMode,
  hasIconLeft,
  iconClasses,
  iconBlockClass,
  autoFocus,
  maxWidth,
  attemptPageTypeSearch,
  customSearchPageUrl,
  autocompleteAlignment,
  openAutocompleteOnFocus,
  blurOnSubmit,
  submitOnIconClick,
  displayMode,
  minSearchTermLength,
  autocompleteFullWidth,
  inputType,
  containerMode = 'overlay',
  disableBlurAndTouchEndHandler,
}: Props) {
  const { withModifiers } = useSearchBarCssHandles()
  const intl = useIntl()
  const container = useRef<HTMLDivElement>(null)
  const { navigate } = useRuntime()
  const [searchTerm, setSearchTerm] = useState(inputValue)
  const [inputErrorMessage, setInputErrorMessage] = useState<
    string | undefined
  >()

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const debouncedSetSearchTerm = useCallback(
    debounce((newValue: string) => {
      setSearchTerm(newValue)
    }, SEARCH_DELAY_TIME),
    []
  )

  useEffect(() => {
    debouncedSetSearchTerm(inputValue)
  }, [debouncedSetSearchTerm, inputValue])

  const onSelect = useCallback(
    element => {
      if (!element) {
        return
      }

      if (element.term) {
        if (attemptPageTypeSearch) {
          window.location.href = `/${element.term}`

          return
        }

        if (customSearchPageUrl) {
          navigate({
            to: customSearchPageUrl.replace(/\$\{term\}/g, element.term),
          })

          return
        }

        navigate({
          page: 'store.search',
          params: { term: element.term },
          query: 'map=ft',
        })

        return
      }

      let page = 'store.product'
      let params: Record<string, string> = {
        slug: element.slug,
        id: element.productId,
      }

      let query = ''
      const terms = element.slug.split('/')

      if (element.criteria) {
        // This param is only useful to track terms searched
        // See: https://support.google.com/analytics/answer/1012264
        const paramForSearchTracking = `&_c=${terms[0]}`

        page = 'store.search'
        params = { term: terms.join('/') }
        query = `map=c,ft${paramForSearchTracking}`
      }

      navigate({ page, params, query })
    },
    [navigate, attemptPageTypeSearch, customSearchPageUrl]
  )

  const validateInput = () => {
    if (minSearchTermLength && inputValue.length < minSearchTermLength) {
      return intl.formatMessage(messages.searchTermTooShort)
    }

    return null
  }

  const showInputErrorMessage = (newInputErrorMessage: string) => {
    setInputErrorMessage(newInputErrorMessage)
  }

  const hideInputErrorMessage = () => {
    setInputErrorMessage(undefined)
  }

  const fallback = (
    <AutocompleteInput
      placeholder={formatIOMessage({ id: placeholder, intl }) as string}
      onInputChange={onInputChange}
      inputValue={inputValue}
      hasIconLeft={hasIconLeft}
      iconClasses={iconClasses}
      iconBlockClass={iconBlockClass}
      inputErrorMessage={inputErrorMessage}
      onGoToSearchPage={onGoToSearchPage}
      onClearInput={onClearInput}
    />
  )

  const isAutocompleteDeclared = Boolean(
    useChildBlock({ id: AUTOCOMPLETE_EXTENSION_ID })
  )

  const SelectedAutocompleteResults = useMemo(() => {
    if (isAutocompleteDeclared) {
      const AutoCompleteResultsWrapper = (props: AutocompleteResultsProps) => (
        <ExtensionPoint id={AUTOCOMPLETE_EXTENSION_ID} {...props} />
      )

      return AutoCompleteResultsWrapper
    }

    const AutoCompleteResultsWrapper = (props: AutocompleteResultsProps) => (
      <AutocompleteResults {...props} />
    )

    return AutoCompleteResultsWrapper
  }, [isAutocompleteDeclared])

  const autocompleteContainerRef = useRef<HTMLDivElement>(null)

  const stateReducer = (
    state: DownshiftState<unknown>,
    changes: StateChangeOptions<unknown>
  ): StateChangeOptions<unknown> => {
    const { type } = changes

    if (
      (type === Downshift.stateChangeTypes.blurInput ||
        type === Downshift.stateChangeTypes.touchEnd) &&
      disableBlurAndTouchEndHandler
    ) {
      return {
        ...changes,
        isOpen: state.isOpen,
      }
    }

    return changes
  }

  return (
    <div
      ref={container}
      className={classNames('w-100 mw7 pv4', styles.searchBarContainer)}
      style={{
        ...(maxWidth && {
          maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,
        }),
      }}
    >
      <NoSSR onSSR={fallback}>
        <Downshift onSelect={onSelect} stateReducer={stateReducer}>
          {({
            getInputProps,
            getItemProps,
            getMenuProps,
            getLabelProps,
            selectedItem,
            highlightedIndex,
            isOpen,
            closeMenu,
            openMenu,
          }) => (
            <div
              className={`relative-m w-100 ${withModifiers(
                'searchBarInnerContainer',
                [isOpen ? 'opened' : '', inputValue ? 'filled' : '']
              )}`}
            >
              <label {...getLabelProps()} className={styles.visuallyHidden}>
                {formatIOMessage({ id: placeholder, intl }) as string}
              </label>
              <AutocompleteInput
                // eslint-disable-next-line jsx-a11y/no-autofocus
                autoFocus={autoFocus}
                compactMode={compactMode}
                hasIconLeft={hasIconLeft}
                iconClasses={iconClasses}
                openAutocompleteOnFocus={openAutocompleteOnFocus}
                submitOnIconClick={submitOnIconClick}
                displayMode={displayMode}
                inputType={inputType}
                openMenu={openMenu}
                inputErrorMessage={inputErrorMessage}
                {...getInputProps({
                  onKeyDown: event => {
                    // Only call default search function if user doesn't
                    // have any item highlighted in the menu options
                    if (event.key === 'Enter' && highlightedIndex === null) {
                      const errorMessage = validateInput()

                      if (errorMessage) {
                        showInputErrorMessage(errorMessage)

                        return
                      }

                      if (blurOnSubmit) {
                        event.currentTarget.blur()
                      }

                      onGoToSearchPage()
                      closeMenu()
                    } else {
                      hideInputErrorMessage()
                    }
                  },
                  placeholder: formatIOMessage({
                    id: placeholder,
                    intl,
                  }) as string,
                  value: inputValue,
                  onChange: onInputChange,
                  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                  // @ts-expect-error this exists
                  onFocus: openAutocompleteOnFocus ? openMenu : undefined,
                })}
                onClearInput={onClearInput}
                onGoToSearchPage={onGoToSearchPage}
              />
              <div ref={autocompleteContainerRef} />

              {containerMode === 'container' ? (
                <SelectedAutocompleteResults
                  parentContainer={container ?? undefined}
                  {...{
                    attemptPageTypeSearch,
                    isOpen,
                    getMenuProps,
                    inputValue: searchTerm,
                    getItemProps,
                    selectedItem,
                    highlightedIndex,
                    closeMenu,
                    onClearInput,
                    customSearchPageUrl,
                  }}
                />
              ) : (
                <Overlay
                  fullWindow={autocompleteFullWidth}
                  alignment={autocompleteAlignment}
                  target={autocompleteContainerRef.current ?? undefined}
                >
                  <SelectedAutocompleteResults
                    parentContainer={container}
                    {...{
                      attemptPageTypeSearch,
                      isOpen,
                      getMenuProps,
                      inputValue: searchTerm,
                      getItemProps,
                      selectedItem,
                      highlightedIndex,
                      closeMenu,
                      onClearInput,
                      customSearchPageUrl,
                    }}
                  />
                </Overlay>
              )}
            </div>
          )}
        </Downshift>
      </NoSSR>
    </div>
  )
}

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-components/react/components/SearchBar/SearchBarCssHandles.ts from the store-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createCssHandlesContext } from 'vtex.css-handles'

import { SEARCH_BAR_CSS_HANDLES } from '../../SearchBar'

const { CssHandlesProvider, useContextCssHandles } = createCssHandlesContext(
  SEARCH_BAR_CSS_HANDLES
)

export {
  CssHandlesProvider as SearchBarCssHandlesProvider,
  useContextCssHandles as useSearchBarCssHandles,
}

```


[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-components/react/components/ShippingSimulator/Wrapper.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, {
  useContext,
  useState,
  useEffect,
  useCallback,
  useRef,
} from 'react'
import { ProductContext } from 'vtex.product-context'
import { useRuntime } from 'vtex.render-runtime'
import { useApolloClient } from 'react-apollo'
import { addValidation, removeValidation } from 'vtex.address-form/helpers'
import {
  useOrderShipping,
  OrderShippingProvider,
} from 'vtex.order-shipping/OrderShipping'
import { useOrderForm } from 'vtex.order-manager/OrderForm'

import { getNewAddress } from './utils'
import ShippingSimulator from './index'
import getShippingEstimates from './queries/getShippingEstimates.gql'
import ShippingSimulatorLoader from './Loader'
import { getDefaultSeller } from '../../utils/sellers'

const useAddressState = (country, postalCode) => {
  const [address, setAddress] = useState(() =>
    addValidation(getNewAddress(country, postalCode))
  )

  const [isValid, setIsValid] = useState(!!postalCode)

  const updateAddress = newAddress => {
    const updatedAddress = {
      ...address,
      ...newAddress,
    }

    setAddress(updatedAddress)
    setIsValid(updatedAddress.postalCode.valid)
  }

  return { address, updateAddress, isValid }
}

const BaseShippingSimulatorWrapper = ({
  country,
  seller,
  skuId,
  loaderStyles,
  onShippingAddressUpdate = _ => {},
  initialPostalCode = undefined,
  shouldUpdateOrderForm,
  pricingMode,
  selectedQuantity,
}) => {
  const [shipping, setShipping] = useState(null)
  const [loading, setLoading] = useState(false)

  const { address, updateAddress, isValid } = useAddressState(
    country,
    initialPostalCode
  )

  const client = useApolloClient()

  const handleCalculateShipping = useCallback(
    e => {
      e && e.preventDefault()
      setLoading(true)
      const rawAddress = removeValidation(address)

      client
        .query({
          query: getShippingEstimates,
          variables: {
            country,
            postalCode: rawAddress.postalCode,
            items: [
              {
                quantity: selectedQuantity,
                id: skuId,
                seller,
              },
            ],
          },
        })
        .then(result => {
          setShipping(result.data.shipping)
        })
        .then(() => {
          if (!shouldUpdateOrderForm) return

          return onShippingAddressUpdate?.(rawAddress)
        })
        .catch(error => {
          console.error(error)
        })
        .finally(() => {
          setLoading(false)
        })
    },
    [
      address,
      client,
      country,
      seller,
      skuId,
      selectedQuantity,
      onShippingAddressUpdate,
      shouldUpdateOrderForm,
    ]
  )

  const isMountedRef = useRef(false)

  useEffect(() => {
    if (isMountedRef.current) {
      isMountedRef.current = false
    }
  }, [seller])

  useEffect(() => {
    if (isMountedRef.current) {
      return
    }

    isMountedRef.current = true

    if (!address || !isValid) {
      return
    }

    handleCalculateShipping()
  }, [handleCalculateShipping, address, isValid])

  return (
    <ShippingSimulator
      skuId={skuId}
      seller={seller}
      country={country}
      loaderStyles={loaderStyles}
      loading={loading}
      address={address}
      isValid={isValid}
      shipping={shipping}
      pricingMode={pricingMode}
      selectedQuantity={selectedQuantity}
      onAddressChange={updateAddress}
      onCalculateShipping={handleCalculateShipping}
    />
  )
}

const ShippingSimulatorWithOrderForm = ({
  country,
  skuId,
  seller,
  loaderStyles,
  shouldUpdateOrderForm,
  pricingMode,
  selectedQuantity,
}) => {
  const { updateSelectedAddress } = useOrderShipping()
  const { orderForm } = useOrderForm()

  const selectedAddress = orderForm?.shipping?.selectedAddress

  return (
    <BaseShippingSimulatorWrapper
      skuId={skuId}
      seller={seller}
      country={country}
      loaderStyles={loaderStyles}
      initialPostalCode={
        orderForm?.canEditData || selectedAddress?.isDisposable
          ? selectedAddress?.postalCode
          : undefined
      }
      onShippingAddressUpdate={updateSelectedAddress}
      shouldUpdateOrderForm={shouldUpdateOrderForm}
      pricingMode={pricingMode}
      selectedQuantity={selectedQuantity}
    />
  )
}

const OrderFormLoader = props => {
  const { loading } = useOrderForm()

  if (loading) {
    return <ShippingSimulatorLoader {...props.loaderStyles} />
  }

  return props.children
}

const ShippingSimulatorWrapper = props => {
  const { culture } = useRuntime()
  const productContext = useContext(ProductContext)

  const country = props.country || culture.country
  const skuId = props.skuId || productContext?.selectedItem?.itemId
  const selectedQuantity = productContext?.selectedQuantity?.toString()

  const { pricingMode } = props

  let sellerId = props.seller

  if (!sellerId) {
    const defaultSeller = getDefaultSeller(
      productContext?.selectedItem?.sellers
    )

    if (defaultSeller) {
      sellerId = defaultSeller.sellerId
    }
  }

  const { shouldUpdateOrderForm = true } = props

  if (
    window.__RUNTIME__?.settings?.['vtex.store']
      ?.enableOrderFormOptimization !== true
  ) {
    return (
      <BaseShippingSimulatorWrapper
        country={country}
        skuId={skuId}
        seller={sellerId}
        pricingMode={pricingMode}
        selectedQuantity={selectedQuantity}
        loaderStyles={props.loaderStyles}
      />
    )
  }

  return (
    <OrderShippingProvider>
      <OrderFormLoader>
        <ShippingSimulatorWithOrderForm
          country={country}
          seller={sellerId}
          skuId={skuId}
          loaderStyles={props.loaderStyles}
          pricingMode={pricingMode}
          selectedQuantity={selectedQuantity}
          shouldUpdateOrderForm={shouldUpdateOrderForm}
        />
      </OrderFormLoader>
    </OrderShippingProvider>
  )
}

export default ShippingSimulatorWrapper

```


[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-components/react/components/ShippingSimulator/global.css from the store-components VTEX app.

[Assistant]
Here's the implementation:

```css
.vtex-store-components-3-x-shippingContainer .vtex-input {
  height: 100%;
}

.vtex-store-components-3-x-shippingContainer .vtex-input input {
  padding: 10px 5px;
  color: #4f4f4f;
  border: 1px solid #e3e4e6;
  border-radius: 2px;
  height: 100%;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.vtex-store-components-3-x-shippingContainer .vtex-button {
  border-radius: 2px;
  border-top-left-radius: 0;
  border-bottom-left-radius: 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-components/react/components/ShippingSimulator/index.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment } from 'react'
import { useIntl } from 'react-intl'
import PropTypes from 'prop-types'
import { Button } from 'vtex.styleguide'
import {
  AddressRules,
  AddressContainer,
  PostalCodeGetter,
} from 'vtex.address-form'
import { StyleguideInput } from 'vtex.address-form/inputs'

import ShippingTable from './components/ShippingTable'
import ShippingSimulatorLoader from './Loader'
import styles from './shippingSimulator.css'

const ShippingSimulator = ({
  /* eslint-disable react/prop-types */
  skuId,
  seller,
  country,
  loading,
  loaderStyles,
  onAddressChange,
  address,
  isValid,
  onCalculateShipping,
  shipping,
  pricingMode,
  /* eslint-enable react/prop-types */
}) => {
  const intl = useIntl()

  if (!seller || !skuId) {
    return <ShippingSimulatorLoader {...loaderStyles} />
  }

  return (
    <Fragment>
      <div className={`${styles.shippingContainer} t-small c-on-base`}>
        <AddressRules country={country} shouldUseIOFetching>
          <AddressContainer
            Input={StyleguideInput}
            address={address}
            onChangeAddress={onAddressChange}
            autoCompletePostalCode
            disabled={loading}
          >
            <PostalCodeGetter onSubmit={onCalculateShipping} />
          </AddressContainer>
        </AddressRules>
        <Button
          onClick={onCalculateShipping}
          className={styles.shippingCTA}
          disabled={!isValid}
          size="small"
          type="submit"
          block
          isLoading={loading}
        >
          {intl.formatMessage({ id: 'store/shipping.label' })}
        </Button>
      </div>
      <ShippingTable shipping={shipping} pricingMode={pricingMode} />
    </Fragment>
  )
}

ShippingSimulator.propTypes = {
  skuId: PropTypes.string,
  seller: PropTypes.string,
  pricingMode: PropTypes.enum,
  country: PropTypes.string.isRequired,
  /** Component and content loader styles */
  styles: PropTypes.object,
}

ShippingSimulator.defaultProps = {
  pricingMode: 'individualItems',
}

export default ShippingSimulator

```


[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-components/react/components/ShippingSimulator/shippingSimulator.css from the store-components VTEX app.

[Assistant]
Here's the implementation:

```css
.shippingContainer {}
.shippingContainerLoader {}
.shippingCTA {}
.shippingInputLoader {}
.shippingNoMessage {}
.shippingTable {}
.shippingTableBody {}
.shippingTableCell {}
.shippingTableCellDeliveryEstimate {}
.shippingTableCellDeliveryName {}
.shippingTableCellDeliveryPrice {}
.shippingTableHead
.shippingTableHead {
  /* Use the following CSS rule to display correctly */
  /* display: table-header-group */
}
.shippingTableHeadDeliveryEstimate {}
.shippingTableHeadDeliveryName {}
.shippingTableHeadDeliveryPrice {}
.shippingTableLabel {}
.shippingTableRadioBtn {}
.shippingTableRow {}
.shippingZipcodeLabel {}
.shippingZipcodeLabelLoader {}
```


[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-components/react/components/ShippingSimulator/Loader.js from the store-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import ContentLoader from 'react-content-loader'

import styles from './shippingSimulator.css'

const ShippingSimulatorLoader = (loaderProps = {}) => (
  <div className={styles.shippingContainer}>
    <ContentLoader
      className={styles.shippingContainerLoader}
      style={{
        width: '100%',
        height: '100%',
      }}
      width={500}
      height={40}
      preserveAspectRatio="xMinYMin meet"
      {...loaderProps}
    >
      <rect
        height="100%"
        width="7em"
        {...loaderProps[styles.shippingZipcodeLabelLoader]}
      />
      <rect
        height="100%"
        width="15em"
        x="8em"
        {...loaderProps[styles.shippingInputLoader]}
      />
    </ContentLoader>
  </div>
)

export default ShippingSimulatorLoader

```