Repository: vtex/faststore
Pull request #2851: feat: Add Region Slider to set/change location
Author: login: lariciamota
Labels: name: enhancement
description: New feature or request
Created: 2025-05-19T15:51:01Z | Merged: 2025-05-22T18:29:04Z

## What's the purpose of this pull request?

Create the Region Slider component to be used for setting and changing the location (postal code).

## How it works?

It's triggered when the shopper clicks on the "Set location" button in the PLP filters and when they click on the postal code link in the PLP filters. The first one is the set location type of this Region Slider, and the second is the change location type.
I've added a new state in the UIProvider and functions to handle its change for the Region Slider.

## How to test it?

In the preview, test both the set and change location scenarios:
#### Set location
When no postal code is defined yet, the "Set location" button is displayed in the PLP filters.
When the shopper clicks this button, a slideover is displayed to set the postal code.
| Desktop | Mobile |
| ---- | ---- |
| <img width="1505" alt="Screenshot 2025-05-19 at 13 42 54" src="https://github.com/user-attachments/assets/06abcd1e-f963-4746-ad45-6003c675f49a" /> | <img width="218" alt="Screenshot 2025-05-19 at 13 47 14" src="https://github.com/user-attachments/assets/75db72a0-7f3b-45a1-ba6d-4c27617c5e55" /> |
| <img width="1507" alt="Screenshot 2025-05-19 at 13 44 04" src="https://github.com/user-attachments/assets/3cf4a05d-a58b-47dc-bf19-bac99a53be55" /> | <img width="216" alt="Screenshot 2025-05-19 at 13 47 50" src="https://github.com/user-attachments/assets/bd87d1ed-9fdd-40f7-b009-e6480d10c89d" /> |

#### Change location
When a postal code was previously set, this postal code is displayed as a link in the PLP filters.
When the shopper clicks this link, a slideover is displayed to change the postal code.
| Desktop | Mobile |
| ---- | ---- |
| <img width="1503" alt="Screenshot 2025-05-19 at 13 44 24" src="https://github.com/user-attachments/assets/f2f5cbe7-5c11-47b1-9769-f1223a1a3339" /> | <img width="216" alt="Screenshot 2025-05-19 at 13 48 14" src="https://github.com/user-attachments/assets/9b1b513f-e3be-4f81-8328-7728dec1e876" /> |
| <img width="1506" alt="Screenshot 2025-05-19 at 13 44 45" src="https://github.com/user-attachments/assets/06a8e8dc-d7b7-41d0-80f8-2462abd52058" /> | <img width="218" alt="Screenshot 2025-05-19 at 13 48 29" src="https://github.com/user-attachments/assets/62f1fc05-f24e-4fbb-83de-4c90d2342d63" /> |

### Starters Deploy Preview

[Preview](https://vendemo-cm9sir9v900u7z6llkl62l70j-k5r6r35q4.b.vtex.app/)
[PR](https://github.com/dp-faststore-org/vendemo-dp/pull/19)

## References

- [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2449)


Diff:
diff --git a/packages/components/src/hooks/UIProvider.tsx b/packages/components/src/hooks/UIProvider.tsx
index c3c4e8b624..8665b7fefb 100644
--- a/packages/components/src/hooks/UIProvider.tsx
+++ b/packages/components/src/hooks/UIProvider.tsx
@@ -13,6 +13,18 @@ export interface Popover {
   triggerRef?: RefObject<HTMLElement>
 }
 
+export const regionSliderTypes = {
+  setLocation: 'setLocation',
+  changeLocation: 'changeLocation',
+} as const
+
+type RegionSliderType =
+  (typeof regionSliderTypes)[keyof typeof regionSliderTypes]
+
+export type RegionSlider = {
+  type: RegionSliderType | 'none'
+}
+
 interface State {
   /** Cart sidebar */
   cart: boolean
@@ -26,6 +38,8 @@ interface State {
   toasts: Toast[]
   /** Region Popover */
   popover: Popover
+  /** Region slider */
+  regionSlider: RegionSlider
 }
 
 type UIElement = 'navbar' | 'cart' | 'modal' | 'filter'
@@ -56,6 +70,13 @@ type Action =
   | {
       type: 'closePopover'
     }
+  | {
+      type: 'openRegionSlider'
+      payload: RegionSliderType
+    }
+  | {
+      type: 'closeRegionSlider'
+    }
 
 const reducer = (state: State, action: Action): State => {
   const { type } = action
@@ -127,6 +148,22 @@ const reducer = (state: State, action: Action): State => {
       }
     }
 
+    case 'openRegionSlider': {
+      return {
+        ...state,
+        regionSlider: {
+          type: action.payload,
+        },
+      }
+    }
+    case 'closeRegionSlider':
+      return {
+        ...state,
+        regionSlider: {
+          type: 'none',
+        },
+      }
+
     default:
       throw new Error(`Action ${type} not implemented`)
   }
@@ -142,6 +179,9 @@ const initializer = (): State => ({
     isOpen: false,
     triggerRef: undefined,
   },
+  regionSlider: {
+    type: 'none',
+  },
 })
 
 interface Context extends State {
@@ -157,6 +197,8 @@ interface Context extends State {
   popToast: () => void
   openPopover: (popover: Popover) => void
   closePopover: () => void
+  openRegionSlider: (type: RegionSliderType) => void
+  closeRegionSlider: () => void
 }
 
 const UIContext = createContext<Context | undefined>(undefined)
@@ -180,6 +222,9 @@ function UIProvider({ children }: PropsWithChildren<unknown>) {
       openPopover: (popover: Popover) =>
         dispatch({ type: 'openPopover', payload: popover }),
       closePopover: () => dispatch({ type: 'closePopover' }),
+      openRegionSlider: (type: RegionSliderType) =>
+        dispatch({ type: 'openRegionSlider', payload: type }),
+      closeRegionSlider: () => dispatch({ type: 'closeRegionSlider' }),
     }),
     []
   )
diff --git a/packages/components/src/hooks/index.ts b/packages/components/src/hooks/index.ts
index f216c91896..1366c79a55 100644
--- a/packages/components/src/hooks/index.ts
+++ b/packages/components/src/hooks/index.ts
@@ -1,15 +1,20 @@
-export { default as UIProvider, Toast as ToastProps, useUI } from './UIProvider'
+export {
+  regionSliderTypes,
+  Toast as ToastProps,
+  default as UIProvider,
+  useUI,
+} from './UIProvider'
 export { useFadeEffect } from './useFadeEffect'
 export { useOnClickOutside } from './useOnClickOutside'
+export { useScrollDirection } from './useScrollDirection'
 export { useSearch } from './useSearch'
 export { useSKUMatrix } from './useSKUMatrix'
-export { useScrollDirection } from './useScrollDirection'
 export { useSlider } from './useSlider'
 export type {
-  UseSliderArgs,
-  SliderState,
-  SliderDispatch,
   SlideDirection,
+  SliderDispatch,
+  SliderState,
+  UseSliderArgs,
 } from './useSlider'
 export { useSlideVisibility } from './useSlideVisibility'
 export { useTrapFocus } from './useTrapFocus'
diff --git a/packages/components/src/organisms/Filter/FilterSlider.tsx b/packages/components/src/organisms/Filter/FilterSlider.tsx
index a21829c94e..80b1d7a9f0 100644
--- a/packages/components/src/organisms/Filter/FilterSlider.tsx
+++ b/packages/components/src/organisms/Filter/FilterSlider.tsx
@@ -42,6 +42,11 @@ export interface FilterSliderProps extends HTMLAttributes<HTMLDivElement> {
    * Function called when Close Button is clicked.
    */
   onClose: () => void
+  /**
+   * Display FilterSlider footer with buttons.
+   * @default true
+   */
+  footer?: boolean
 }
 
 function FilterSlider({
@@ -53,10 +58,11 @@ function FilterSlider({
   clearBtnProps,
   overlayProps,
   onClose,
+  footer = true,
   ...otherProps
 }: PropsWithChildren<FilterSliderProps>) {
   const { fade, fadeOut } = useFadeEffect()
-  const { closeFilter } = useUI()
+  const { closeFilter, closeRegionSlider } = useUI()
 
   return (
     <SlideOver
@@ -66,7 +72,12 @@ function FilterSlider({
       onDismiss={fadeOut}
       size={size}
       direction={direction}
-      onTransitionEnd={() => fade === 'out' && closeFilter()}
+      onTransitionEnd={() => {
+        if (fade === 'out') {
+          closeFilter()
+          closeRegionSlider()
+        }
+      }}
       overlayProps={overlayProps}
       {...otherProps}
     >
@@ -81,18 +92,23 @@ function FilterSlider({
         </SlideOverHeader>
         {children}
       </div>
-      <footer data-fs-filter-slider-footer>
-        <Button data-fs-filter-slider-footer-button-clear {...clearBtnProps} />
-        <Button
-          data-fs-filter-slider-footer-button-apply
-          data-testid="filter-slider-button-apply"
-          {...applyBtnProps}
-          onClick={(e) => {
-            applyBtnProps?.onClick?.(e)
-            fadeOut()
-          }}
-        />
-      </footer>
+      {footer && (
+        <footer data-fs-filter-slider-footer>
+          <Button
+            data-fs-filter-slider-footer-button-clear
+            {...clearBtnProps}
+          />
+          <Button
+            data-fs-filter-slider-footer-button-apply
+            data-testid="filter-slider-button-apply"
+            {...applyBtnProps}
+            onClick={(e) => {
+              applyBtnProps?.onClick?.(e)
+              fadeOut()
+            }}
+          />
+        </footer>
+      )}
     </SlideOver>
   )
 }
diff --git a/packages/core/cms/faststore/content-types.json b/packages/core/cms/faststore/content-types.json
index 70093f1cb3..4a9a1c86e2 100644
--- a/packages/core/cms/faststore/content-types.json
+++ b/packages/core/cms/faststore/content-types.json
@@ -87,15 +87,31 @@
                     "description": {
                       "title": "Description",
                       "type": "string",
-                      "default": "Offers and delivery options vary based on region."
+                      "default": "Offers and availability vary by location."
                     },
                     "setLocationButtonLabel": {
                       "title": "Call to Action label",
                       "type": "string",
                       "default": "Set Location"
                     },
-                    "deliveryCustomLabels": {
-                      "title": "Filter options labels",
+                    "postalCodeEditSlider": {
+                      "title": "Postal Code Edit SlideOver",
+                      "type": "object",
+                      "properties": {
+                        "setLocation": {
+                          "title": "Set Location label",
+                          "type": "string",
+                          "default": "Set Location"
+                        },
+                        "changeLocation": {
+                          "title": "Change Postal Code",
+                          "type": "string",
+                          "default": "Change Location"
+                        }
+                      }
+                    },
+                    "deliveryMethods": {
+                      "title": "Delivery methods filter",
                       "type": "object",
                       "properties": {
                         "delivery": {
@@ -114,9 +130,21 @@
                           "default": "Pickup Nearby"
                         },
                         "pickupAll": {
-                          "title": "Pickup Anywhere label",
-                          "type": "string",
-                          "default": "Pickup Anywhere"
+                          "title": "Pickup All",
+                          "type": "object",
+                          "properties": {
+                            "enabled": {
+                              "title": "Display pickup all filter",
+                              "description": "Display the pickup all filter in the PLP/Search page. This is recommended only for B2B stores.",
+                              "type": "boolean",
+                              "default": false
+                            },
+                            "label": {
+                              "title": "Label",
+                              "type": "string",
+                              "default": "Pickup Anywhere"
+                            }
+                          }
                         }
                       }
                     }
diff --git a/packages/core/cms/faststore/sections.json b/packages/core/cms/faststore/sections.json
index 6a3bac41e9..0ac3eb6289 100644
--- a/packages/core/cms/faststore/sections.json
+++ b/packages/core/cms/faststore/sections.json
@@ -1913,53 +1913,6 @@
                   "default": "Apply"
                 }
               }
-            },
-            "deliverySettings": {
-              "title": "Delivery Settings",
-              "type": "object",
-              "properties": {
-                "title": {
-                  "title": "Delivery section title",
-                  "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                  "type": "string"
-                },
-                "description": {
-                  "title": "Delivery section description",
-                  "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                  "type": "string"
-                },
-                "setLocationButtonLabel": {
-                  "title": "Call to Action label",
-                  "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                  "type": "string"
-                },
-                "deliveryCustomLabels": {
-                  "title": "Delivery Custom labels",
-                  "type": "object",
-                  "properties": {
-                    "delivery": {
-                      "title": "Shipping label",
-                      "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                      "type": "string"
-                    },
-                    "pickupInPoint": {
-                      "title": "Pickup in point label",
-                      "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                      "type": "string"
-                    },
-                    "pickupNearby": {
-                      "title": "Pickup Nearby label",
-                      "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                      "type": "string"
-                    },
-                    "pickupAll": {
-                      "title": "Pickup Anywhere label",
-                      "description": "[Deprecated] Use the fields from the Settings tab in Global Sections",
-                      "type": "string"
-                    }
-                  }
-                }
-              }
             }
           }
         },
diff --git a/packages/core/src/components/region/RegionSlider/RegionSlider.tsx b/packages/core/src/components/region/RegionSlider/RegionSlider.tsx
new file mode 100644
index 0000000000..5e1cf9a25e
--- /dev/null
+++ b/packages/core/src/components/region/RegionSlider/RegionSlider.tsx
@@ -0,0 +1,138 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useEffect, useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const inputRef = useRef<HTMLInputElement>(null)
+  const { isValidating, ...session } = useSession()
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
+
+  const [input, setInput] = useState<string>('')
+
+  const inputField = cmsData?.inputField
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const handleSubmit = async () => {
+    if (isValidating) {
+      return
+    }
+
+    await setRegion({
+      session,
+      onSuccess: () => {
+        setInput('')
+        closeRegionSlider()
+      },
+      postalCode: input,
+      errorMessage: inputField?.errorMessage,
+      noProductsAvailableErrorMessage:
+        inputField?.noProductsAvailableErrorMessage,
+    })
+  }
+
+  const idkPostalCodeLinkProps = {
+    href: idkPostalCodeLink?.to,
+    children: (
+      <>
+        {idkPostalCodeLink?.text}
+        {!!idkPostalCodeLink?.icon?.icon && (
+          <UIIcon
+            name={idkPostalCodeLink?.icon?.icon}
+            aria-label={idkPostalCodeLink?.icon?.alt}
+            width={20}
+            height={20}
+          />
+        )}
+      </>
+    ),
+  }
+
+  useEffect(() => {
+    inputRef.current?.focus()
+  }, [])
+
+  return (
+    <UIFilterSlider
+      data-fs-filter-region-slider
+      overlayProps={{
+        className: `section ${styles.section} section-filter-slider`,
+      }}
+      title={
+        regionSliderType !== 'none'
+          ? cmsData?.deliverySettings?.postalCodeEditSlider?.[regionSliderType]
+          : ''
+      }
+      size="partial"
+      direction="rightSide"
+      onClose={() => {}}
+      footer={false}
+    >
+      <div data-fs-filter-region-slider-content>
+        <span data-fs-filter-region-slider-description>
+          {cmsData?.deliverySettings?.description}
+        </span>
+        <UIInputField
+          id="region-slider-input-field"
+          inputRef={inputRef}
+          label={inputField?.label}
+          actionable
+          value={input}
+          buttonActionText={loading ? '...' : inputField?.buttonActionText}
+          onInput={(e) => {
+            regionError !== '' && setRegionError('')
+            setInput(e.currentTarget.value)
+          }}
+          onSubmit={() => {
+            handleSubmit()
+          }}
+          onClear={() => {
+            setInput('')
+            setRegionError('')
+          }}
+          error={regionError}
+        />
+        {idkPostalCodeLink?.to && (
+          <UILink data-fs-filter-delivery-link {...idkPostalCodeLinkProps} />
+        )}
+      </div>
+    </UIFilterSlider>
+  )
+}
+
+export default RegionSlider
diff --git a/packages/core/src/components/region/RegionSlider/index.ts b/packages/core/src/components/region/RegionSlider/index.ts
new file mode 100644
index 0000000000..f59dd7c4ab
--- /dev/null
+++ b/packages/core/src/components/region/RegionSlider/index.ts
@@ -0,0 +1 @@
+export { default as RegionSlider } from './RegionSlider'
diff --git a/packages/core/src/components/region/RegionSlider/section.module.scss b/packages/core/src/components/region/RegionSlider/section.module.scss
new file mode 100644
index 0000000000..f8b6deaf70
--- /dev/null
+++ b/packages/core/src/components/region/RegionSlider/section.module.scss
@@ -0,0 +1,52 @@
+.section {
+  @import "@faststore/ui/src/components/atoms/Button/styles.scss";
+  @import "@faststore/ui/src/components/atoms/Icon/styles.scss";
+  @import "@faststore/ui/src/components/atoms/Input/styles.scss";
+  @import "@faststore/ui/src/components/atoms/Link/styles.scss";
+  @import "@faststore/ui/src/components/molecules/InputField/styles.scss";
+  @import "@faststore/ui/src/components/molecules/Modal/styles.scss";
+  @import "@faststore/ui/src/components/organisms/FilterSlider/styles.scss";
+  @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
+
+  [data-fs-filter-region-slider] {
+    [data-fs-filter-slider-title] {
+      font-size: var(--fs-text-size-3);
+      font-weight: var(--fs-text-weight-semibold);
+    }
+
+    [data-fs-slide-over-header] {
+      @include media(">=notebook") {
+        padding-right: var(--fs-spacing-6);
+        padding-left: var(--fs-spacing-6);
+      }
+    }
+
+    [data-fs-filter-region-slider-content] {
+      padding: 0 var(--fs-spacing-3);
+
+      @include media(">=notebook") {
+        padding: 0 var(--fs-spacing-6);
+      }
+    }
+
+    [data-fs-filter-region-slider-description] {
+      display: flex;
+      padding: var(--fs-spacing-4) 0;
+      font-size: var(--fs-text-size-2);
+      line-height: 1.25;
+    }
+
+    // Duplicate from data-fs-region-modal-link
+    [data-fs-filter-delivery-link] {
+      display: flex;
+      flex-direction: row;
+      column-gap: var(--fs-filter-link-column-gap);
+      align-content: flex-start;
+      align-items: center;
+      justify-content: flex-start;
+      padding: var(--fs-filter-link-padding);
+      margin-top: var(--fs-spacing-2);
+      color: var(--fs-filter-link-color);
+    }
+  }
+}
diff --git a/packages/core/src/components/search/Filter/FilterDeliveryOption.tsx b/packages/core/src/components/search/Filter/FilterDeliveryOption.tsx
index 5798c4fc1c..07043cb0f9 100644
--- a/packages/core/src/components/search/Filter/FilterDeliveryOption.tsx
+++ b/packages/core/src/components/search/Filter/FilterDeliveryOption.tsx
@@ -1,14 +1,9 @@
-import { Button as UIButton } from '@faststore/ui'
+import { regionSliderTypes, Button as UIButton, useUI } from '@faststore/ui'
+import { RegionSlider } from 'src/components/region/RegionSlider'
 import { sessionStore } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
 import { textToTitleCase } from 'src/utils/utilities'
 
-interface DeliveryCustomLabels {
-  delivery?: string
-  pickupInPoint?: string
-  pickupNearby?: string
-  pickupAll?: string
-}
-
 interface FacetValue {
   value: string
   label: string
@@ -18,37 +13,45 @@ interface FacetValue {
 
 interface FilterDeliveryOptionProps {
   item: FacetValue
-  deliveryCustomLabels: DeliveryCustomLabels
+  deliveryMethods: RegionalizationCmsData['deliverySettings']['deliveryMethods']
+  cmsData: Record<string, any>
 }
 
 export default function FilterDeliveryOption({
   item,
-  deliveryCustomLabels,
+  deliveryMethods,
+  cmsData,
 }: FilterDeliveryOptionProps) {
   const { city, postalCode } = sessionStore.read()
-  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
+  const {
+    regionSlider: { type: regionSliderType },
+    openRegionSlider,
+  } = useUI()
 
-  const mapDeliveryCustomLabel: Record<string, string> = {
-    delivery: deliveryCustomLabels?.delivery ?? 'Shipping to',
-    'pickup-in-point': deliveryCustomLabels?.pickupInPoint ?? 'Pickup at',
-    'pickup-nearby': deliveryCustomLabels?.pickupNearby ?? 'Pickup Nearby',
-    'pickup-all': deliveryCustomLabels?.pickupAll ?? 'Pickup Anywhere',
+  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
+  const mapDeliveryMethodLabel: Record<string, string> = {
+    delivery: deliveryMethods?.delivery ?? 'Shipping to',
+    'pickup-in-point': deliveryMethods?.pickupInPoint ?? 'Pickup at',
+    'pickup-nearby': deliveryMethods?.pickupNearby ?? 'Pickup Nearby',
+    'pickup-all': deliveryMethods?.pickupAll?.label ?? 'Pickup Anywhere',
   }
 
   if (item.value === 'delivery') {
     return (
       <>
-        {mapDeliveryCustomLabel[item.value]}
+        {mapDeliveryMethodLabel[item.value]}
         <UIButton
           data-fs-filter-list-item-button
           size="small"
           onClick={() => {
-            // TODO: open edit local slideOver
-            window.alert('Open Modal')
+            openRegionSlider(regionSliderTypes.changeLocation)
           }}
         >
           {location}
         </UIButton>
+        {regionSliderType === regionSliderTypes.changeLocation && (
+          <RegionSlider cmsData={cmsData} />
+        )}
       </>
     )
   }
@@ -56,7 +59,7 @@ export default function FilterDeliveryOption({
   if (item.value === 'pickup-in-point') {
     return (
       <>
-        {mapDeliveryCustomLabel[item.value]}
+        {mapDeliveryMethodLabel[item.value]}
         <UIButton
           data-fs-filter-list-item-button
           size="small"
@@ -71,5 +74,5 @@ export default function FilterDeliveryOption({
     )
   }
 
-  return <>{mapDeliveryCustomLabel[item.value]}</>
+  return <>{mapDeliveryMethodLabel[item.value]}</>
 }
diff --git a/packages/core/src/components/search/Filter/FilterDesktop.tsx b/packages/core/src/components/search/Filter/FilterDesktop.tsx
index 4f62135640..8968ffb35c 100644
--- a/packages/core/src/components/search/Filter/FilterDesktop.tsx
+++ b/packages/core/src/components/search/Filter/FilterDesktop.tsx
@@ -1,6 +1,7 @@
 import { setFacet, toggleFacet, useSearch } from '@faststore/sdk'
 
 import {
+  regionSliderTypes,
   Button as UIButton,
   Filter as UIFilter,
   FilterFacetBoolean as UIFilterFacetBoolean,
@@ -8,6 +9,7 @@ import {
   FilterFacetRange as UIFilterFacetRange,
   FilterFacets as UIFilterFacets,
   Icon as UIIcon,
+  useUI,
 } from '@faststore/ui'
 import { gql } from '@generated/gql'
 import { deliveryPromise } from 'discovery.config'
@@ -17,6 +19,7 @@ import type { FilterSliderProps } from './FilterSlider'
 
 import { sessionStore } from 'src/sdk/session'
 import { getRegionalizationSettings } from 'src/utils/globalSettings'
+import RegionSlider from '../../region/RegionSlider/RegionSlider'
 import FilterDeliveryOption from './FilterDeliveryOption'
 
 interface FilterDesktopProps
@@ -34,9 +37,13 @@ function FilterDesktop({
   deliverySettings,
 }: FilterDesktopProps & ReturnType<typeof useFilter>) {
   const { resetInfiniteScroll, state, setState } = useSearch()
+  const {
+    regionSlider: { type: regionSliderType },
+    openRegionSlider,
+  } = useUI()
 
-  const { deliverySettings: deliverySettingsData } =
-    getRegionalizationSettings(deliverySettings)
+  const regionalizationData = getRegionalizationSettings(deliverySettings)
+  const { deliverySettings: deliverySettingsData } = regionalizationData
   const deliveryLabel = deliverySettingsData?.title ?? 'Delivery'
 
   const { postalCode } = sessionStore.read()
@@ -45,6 +52,9 @@ function FilterDesktop({
     ? facets
     : facets.filter((facet) => facet.key !== 'shipping')
 
+  const isPickupAllEnabled =
+    deliverySettingsData?.deliveryMethods?.pickupAll?.enabled ?? false
+
   return (
     <UIFilter
       testId={`desktop-${testId}`}
@@ -67,7 +77,7 @@ function FilterDesktop({
             data-fs-filter-list-delivery-button
             variant="secondary"
             onClick={() => {
-              // TODO: open edit local slideOver
+              openRegionSlider(regionSliderTypes.setLocation)
             }}
             icon={<UIIcon name="MapPin" />}
           >
@@ -75,6 +85,9 @@ function FilterDesktop({
           </UIButton>
         </UIFilterFacets>
       )}
+      {regionSliderType === regionSliderTypes.setLocation && (
+        <RegionSlider cmsData={regionalizationData} />
+      )}
       {filteredFacets.map((facet, idx) => {
         const index = shouldDisplayDeliveryButton ? idx + 1 : idx
         const { __typename: type, label } = facet
@@ -94,42 +107,46 @@ function FilterDesktop({
           >
             {type === 'StoreFacetBoolean' && isExpanded && (
               <UIFilterFacetBoolean>
-                {facet.values.map((item) => (
-                  <UIFilterFacetBooleanItem
-                    key={`${testId}-${facet.label}-${item.label}`}
-                    id={`${testId}-${facet.label}-${item.label}`}
-                    testId={testId}
-                    onFacetChange={(facet) => {
-                      setState({
-                        ...state,
-                        selectedFacets: toggleFacet(
-                          state.selectedFacets,
-                          facet,
-                          true
-                        ),
-                        page: 0,
-                      })
-                      resetInfiniteScroll(0)
-                    }}
-                    selected={item.selected}
-                    value={item.value}
-                    quantity={item.quantity}
-                    facetKey={facet.key}
-                    label={
-                      isDeliveryFacet ? (
-                        <FilterDeliveryOption
-                          item={item}
-                          deliveryCustomLabels={
-                            deliverySettingsData.deliveryCustomLabels
-                          }
-                        />
-                      ) : (
-                        item.label
-                      )
-                    }
-                    type={isDeliveryFacet ? 'radio' : 'checkbox'}
-                  />
-                ))}
+                {facet.values.map(
+                  (item) =>
+                    (item.value !== 'pickup-all' || isPickupAllEnabled) && (
+                      <UIFilterFacetBooleanItem
+                        key={`${testId}-${facet.label}-${item.label}`}
+                        id={`${testId}-${facet.label}-${item.label}`}
+                        testId={testId}
+                        onFacetChange={(facet) => {
+                          setState({
+                            ...state,
+                            selectedFacets: toggleFacet(
+                              state.selectedFacets,
+                              facet,
+                              true
+                            ),
+                            page: 0,
+                          })
+                          resetInfiniteScroll(0)
+                        }}
+                        selected={item.selected}
+                        value={item.value}
+                        quantity={item.quantity}
+                        facetKey={facet.key}
+                        label={
+                          isDeliveryFacet ? (
+                            <FilterDeliveryOption
+                              item={item}
+                              deliveryMethods={
+                                deliverySettingsData.deliveryMethods
+                              }
+                              cmsData={regionalizationData}
+                            />
+                          ) : (
+                            item.label
+                          )
+                        }
+                        type={isDeliveryFacet ? 'radio' : 'checkbox'}
+                      />
+                    )
+                )}
               </UIFilterFacetBoolean>
             )}
             {type === 'StoreFacetRange' && isExpanded && (
diff --git a/packages/core/src/components/search/Filter/FilterSlider.tsx b/packages/core/src/components/search/Filter/FilterSlider.tsx
index 126da05c23..c35c850b81 100644
--- a/packages/core/src/components/search/Filter/FilterSlider.tsx
+++ b/packages/core/src/components/search/Filter/FilterSlider.tsx
@@ -1,14 +1,16 @@
 import dynamic from 'next/dynamic'
 
 import { useSearch } from '@faststore/sdk'
-import type {
-  ButtonProps as UIButtonProps,
-  FilterFacetBooleanItemProps as UIFilterFacetBooleanItemProps,
-  FilterFacetRangeProps as UIFilterFacetRangeProps,
-  FilterFacetsProps as UIFilterFacetsProps,
-  FilterProps as UIFilterProps,
-  FilterSliderProps as UIFilterSliderProps,
-  IconProps as UIIconProps,
+import {
+  regionSliderTypes,
+  useUI,
+  type ButtonProps as UIButtonProps,
+  type FilterFacetBooleanItemProps as UIFilterFacetBooleanItemProps,
+  type FilterFacetRangeProps as UIFilterFacetRangeProps,
+  type FilterFacetsProps as UIFilterFacetsProps,
+  type FilterProps as UIFilterProps,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
 } from '@faststore/ui'
 import { deliveryPromise } from 'discovery.config'
 import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice'
@@ -55,15 +57,13 @@ import FilterDeliveryOption from './FilterDeliveryOption'
 import type { useFilter } from 'src/sdk/search/useFilter'
 import { sessionStore } from 'src/sdk/session'
 
+import RegionSlider from 'src/components/region/RegionSlider/RegionSlider'
+import {
+  getRegionalizationSettings,
+  type RegionalizationCmsData,
+} from 'src/utils/globalSettings'
 import styles from './section.module.scss'
 
-interface DeliveryCustomLabels {
-  delivery?: string
-  pickupInPoint?: string
-  pickupNearby?: string
-  pickupAll?: string
-}
-
 export interface FilterSliderProps {
   /**
    * ID to find this component in testing tools (e.g.: cypress,
@@ -89,12 +89,7 @@ export interface FilterSliderProps {
   /**
    * CMS settings for values related to delivery (e.g., custom name for title, shipping, pickup, pickup-nearby).
    */
-  deliverySettings?: {
-    title?: string
-    description?: string
-    setLocationButtonLabel?: string
-    deliveryCustomLabels?: DeliveryCustomLabels
-  }
+  deliverySettings?: RegionalizationCmsData['deliverySettings']
 }
 
 function FilterSlider({
@@ -109,15 +104,24 @@ function FilterSlider({
   deliverySettings,
 }: FilterSliderProps & ReturnType<typeof useFilter>) {
   const { resetInfiniteScroll, setState, state } = useSearch()
+  const {
+    regionSlider: { type: regionSliderType },
+    openRegionSlider,
+  } = useUI()
 
-  const deliveryLabel = deliverySettings?.title ?? 'Delivery'
-  const { postalCode } = sessionStore.read()
+  const regionalizationData = getRegionalizationSettings(deliverySettings)
+  const { deliverySettings: deliverySettingsData } = regionalizationData
+  const deliveryLabel = deliverySettingsData?.title ?? 'Delivery'
 
+  const { postalCode } = sessionStore.read()
   const shouldDisplayDeliveryButton = deliveryPromise.enabled && !postalCode
   const filteredFacets = deliveryPromise.enabled
     ? facets
     : facets.filter((facet) => facet.key !== 'shipping')
 
+  const isPickupAllEnabled =
+    deliverySettingsData?.deliveryMethods?.pickupAll?.enabled ?? false
+
   return (
     <UIFilterSlider
       overlayProps={{
@@ -171,7 +175,7 @@ function FilterSlider({
               data-fs-filter-list-delivery-button
               variant="secondary"
               onClick={() => {
-                // TODO: open edit local slideOver
+                openRegionSlider(regionSliderTypes.setLocation)
               }}
               icon={<UIIcon name="MapPin" />}
             >
@@ -179,6 +183,9 @@ function FilterSlider({
             </UIButton>
           </UIFilterFacets>
         )}
+        {regionSliderType === regionSliderTypes.setLocation && (
+          <RegionSlider cmsData={regionalizationData} />
+        )}
         {filteredFacets.map((facet, idx) => {
           const index = shouldDisplayDeliveryButton ? idx + 1 : idx
           const { __typename: type, label } = facet
@@ -198,33 +205,37 @@ function FilterSlider({
             >
               {type === 'StoreFacetBoolean' && isExpanded && (
                 <UIFilterFacetBoolean>
-                  {facet.values.map((item) => (
-                    <UIFilterFacetBooleanItem
-                      key={`${testId}-${facet.label}-${item.label}`}
-                      id={`${testId}-${facet.label}-${item.label}`}
-                      testId={`mobile-${testId}`}
-                      onFacetChange={(facet) =>
-                        dispatch({ type: 'toggleFacet', payload: facet })
-                      }
-                      selected={item.selected}
-                      value={item.value}
-                      quantity={item.quantity}
-                      facetKey={facet.key}
-                      label={
-                        isDeliveryFacet ? (
-                          <FilterDeliveryOption
-                            item={item}
-                            deliveryCustomLabels={
-                              deliverySettings?.deliveryCustomLabels
-                            }
-                          />
-                        ) : (
-                          item.label
-                        )
-                      }
-                      type={isDeliveryFacet ? 'radio' : 'checkbox'}
-                    />
-                  ))}
+                  {facet.values.map(
+                    (item) =>
+                      (item.value !== 'pickup-all' || isPickupAllEnabled) && (
+                        <UIFilterFacetBooleanItem
+                          key={`${testId}-${facet.label}-${item.label}`}
+                          id={`${testId}-${facet.label}-${item.label}`}
+                          testId={`mobile-${testId}`}
+                          onFacetChange={(facet) =>
+                            dispatch({ type: 'toggleFacet', payload: facet })
+                          }
+                          selected={item.selected}
+                          value={item.value}
+                          quantity={item.quantity}
+                          facetKey={facet.key}
+                          label={
+                            isDeliveryFacet ? (
+                              <FilterDeliveryOption
+                                item={item}
+                                deliveryMethods={
+                                  deliverySettings?.deliveryMethods
+                                }
+                                cmsData={regionalizationData}
+                              />
+                            ) : (
+                              item.label
+                            )
+                          }
+                          type={isDeliveryFacet ? 'radio' : 'checkbox'}
+                        />
+                      )
+                  )}
                 </UIFilterFacetBoolean>
               )}
               {type === 'StoreFacetRange' && isExpanded && (
diff --git a/packages/core/src/utils/globalSettings.ts b/packages/core/src/utils/globalSettings.ts
index 9a69b8c0cb..083e322079 100644
--- a/packages/core/src/utils/globalSettings.ts
+++ b/packages/core/src/utils/globalSettings.ts
@@ -24,11 +24,18 @@ export type RegionalizationCmsData = {
     title?: string
     description?: string
     setLocationButtonLabel?: string
-    deliveryCustomLabels?: {
+    postalCodeEditSlider?: {
+      setLocation?: string
+      changeLocation?: string
+    }
+    deliveryMethods?: {
       delivery?: string
       pickupInPoint?: string
       pickupNearby?: string
-      pickupAll?: string
+      pickupAll?: {
+        label?: string
+        enabled?: boolean
+      }
     }
   }
 }
diff --git a/packages/ui/src/components/organisms/FilterSlider/styles.scss b/packages/ui/src/components/organisms/FilterSlider/styles.scss
index 8dc905d6e6..1495be8735 100644
--- a/packages/ui/src/components/organisms/FilterSlider/styles.scss
+++ b/packages/ui/src/components/organisms/FilterSlider/styles.scss
@@ -5,11 +5,11 @@
 
   // Content
   --fs-filter-slider-content-height                   : calc(100vh - var(--fs-filter-slider-footer-height));
-  --fs-filter-slider-content-padding                  : var(--fs-spacing-3) var(--fs-spacing-3) calc(var(--fs-filter-slider-footer-height) + var(--fs-spacing-3));
+  --fs-filter-slider-content-padding                  : 0 var(--fs-spacing-3);
 
-  // Title 
-  --fs-filter-slider-title-font-size                  : var(--fs-text-size-4);
-  --fs-filter-slider-title-font-weight                : var(--fs-text-weight-bold);
+  // Title
+  --fs-filter-slider-title-font-size                  : var(--fs-text-size-3);
+  --fs-filter-slider-title-font-weight                : var(--fs-text-weight-semibold);
   --fs-filter-slider-title-line-height                : 1.12;
 
   // Footer
@@ -25,10 +25,34 @@
 
   --fs-filter-slider-footer-button-apply-width        : 60%;
 
+  // Link
+  --fs-filter-link-padding                            : 0;
+  --fs-filter-link-column-gap                         : var(--fs-spacing-0);
+  --fs-filter-link-color                              : var(--fs-color-link);
+
   [data-fs-filter-slider-content] {
     height: var(--fs-filter-slider-content-height);
-    padding: var(--fs-filter-slider-content-padding);
+    padding-bottom: calc(var(--fs-filter-slider-footer-height) + var(--fs-spacing-3));
     overflow-y: auto;
+
+    [data-fs-slide-over-header] {
+      position: relative;
+
+      &::after {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        display: block;
+        width: 100%;
+        height: 1px;
+        content: "";
+        background-color: var(--fs-border-color-light);
+      }
+    }
+  }
+
+  [data-fs-filter] {
+    padding: var(--fs-filter-slider-content-padding);
   }
 
   [data-fs-filter-slider-title] {
@@ -37,10 +61,6 @@
     line-height: var(--fs-filter-slider-title-line-height);
   }
 
-  [data-fs-slide-over-header] {
-    padding: 0;
-  }
-
   [data-fs-filter-slider-footer] {
     position: sticky;
     bottom: 0;


Reviews:
user: login: lucasfp13
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T14:14:21Z
user: login: beatrizmilhomem
body: **Set Location**
-

- I just noticed that the slideover title is wrong in Figma, sorry. It should be **Set Location**.

**Desktop**
- If I close the slideover without adding a location, the `Set Location` button stays in `pressed` state and it should be back to the `default` state.
<img width="382" alt="image" src="https://github.com/user-attachments/assets/acdc3211-d717-420c-a86b-489050853130" />

- When the slideover opens:
     - Currently, the close button is in `focus` state, but it should be in `default` state and the input should be in `focus` instead.
     - Title should be `text-size-3` Semibold.
     - Close button should be 38x38 and the icon 24px.
     - Space before and after the description "Offers and..." should be 24px.
     - Space between the field and "I don't know..." should be 12px.
     - After adding a location, the Delivery filter didn't appear automatically, I had to reload the page.

- The sorting button size should vary according to the selected option, so there isn't a big gap between the option and the caret.
<img width="286" alt="image" src="https://github.com/user-attachments/assets/bc18ed5d-0c6c-4ec0-bee9-d5bf69839d9c" />

**Mobile:**
- Same thing for the sorting button. Also, if it doesn't fit in the horizontal space, the `Sort by` label shouldn't break and it should add ellipsis to the option selected.
<img width="265" alt="image" src="https://github.com/user-attachments/assets/7641d868-6474-4209-8df7-4efc9c87a822" />

- Filter slideover:
  - If I close the slideover, the `Filter` button stays in `pressed` state and it should be back to the `default` state.
   - Title should be `text-size-3` Semibold.
   - When clicking on `Set Location`, the new level should have a back button and title should be Set Location. The should also have a back button for Change Location.
   - Space before and after the description "Offers and..." should be 24px.
   - Space between the field and "I don't know..." should be 12px.
   - Currently, the close button is in `focus` state, but it should be in `default` state and the input should be in `focus` instead.
   - Remove the left and right paddings of the title so it's aligned with the content (space should be the same as it is in `Change Location`). 
<img width="382" alt="image" src="https://github.com/user-attachments/assets/64f7e3c0-9668-4c73-961e-1f2450e10de3" />

state: CHANGES_REQUESTED
author_association: NONE
submitted_at: 2025-05-20T16:51:54Z
user: login: lariciamota
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T18:23:02Z
user: login: lucasfp13
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T18:30:39Z
user: login: lariciamota
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T18:31:24Z
user: login: lariciamota
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T19:01:41Z
user: login: lariciamota
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T19:22:46Z
user: login: lariciamota
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T20:59:12Z
user: login: beatrizmilhomem
state: APPROVED
author_association: NONE
submitted_at: 2025-05-22T16:18:10Z
user: login: lucasfp13
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T17:03:14Z
user: login: lucasfp13
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T17:35:29Z
user: login: hellofanny
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T18:09:58Z

Review comments:
diff_hunk: @@ -81,18 +92,23 @@ function FilterSlider({
         </SlideOverHeader>
         {children}
       </div>
-      <footer data-fs-filter-slider-footer>
-        <Button data-fs-filter-slider-footer-button-clear {...clearBtnProps} />
-        <Button
-          data-fs-filter-slider-footer-button-apply
-          data-testid="filter-slider-button-apply"
-          {...applyBtnProps}
-          onClick={(e) => {
-            applyBtnProps?.onClick?.(e)
-            fadeOut()
-          }}
-        />
-      </footer>
+      {footer && (
+        <footer data-fs-filter-slider-footer>
+          <Button
+            data-fs-filter-slider-footer-button-clear
+            {...clearBtnProps}
+          />
+          <Button
+            data-fs-filter-slider-footer-button-apply
+            data-testid="filter-slider-button-apply"
+            {...applyBtnProps}
+            onClick={(e) => {
+              applyBtnProps?.onClick?.(e)
+              fadeOut()
+            }}
+          />
+        </footer>
+      )}
path: packages/components/src/organisms/Filter/FilterSlider.tsx
user: login: lucasfp13
body: **thought**: It seems to me we would benefit having a `SliderOverFooter` component here, but it isn't in the current task scope. I'll create a improvement task to discuss with the team.
created_at: 2025-05-20T12:55:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -13,6 +13,12 @@ export interface Popover {
   triggerRef?: RefObject<HTMLElement>
 }
 
+type RegionSliderType = 'setLocation' | 'changeLocation'
+
+export type RegionSlider = {
+  type: RegionSliderType | 'none'
path: packages/components/src/hooks/UIProvider.tsx
user: login: lucasfp13
body: **suggestion**: I was ok with `type` attribute here, but when we reach the `RegionSlider` component it feels a bit vague. What do you think of `action`? In the component you could rename to something like `regionSliderAction`
created_at: 2025-05-20T13:01:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lucasfp13
body: **suggestion**: Here we would have the `action` to better understand what this prop would be.
created_at: 2025-05-20T13:02:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const { isValidating, ...session } = useSession()
+  const inputRef = useRef<HTMLInputElement>(null)
+
+  const inputField = cmsData?.inputField
+
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const [input, setInput] = useState<string>('')
+
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lucasfp13
body: **nitpick**

```suggestion
  const inputRef = useRef<HTMLInputElement>(null)
  const { isValidating, ...session } = useSession()
  const { loading, setRegion, regionError, setRegionError } = useRegion()
  
  const [input, setInput] = useState<string>('')
  
  const inputField = cmsData?.inputField
  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
```
created_at: 2025-05-20T13:06:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const { isValidating, ...session } = useSession()
+  const inputRef = useRef<HTMLInputElement>(null)
+
+  const inputField = cmsData?.inputField
+
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const [input, setInput] = useState<string>('')
+
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
+
+  const handleSubmit = async () => {
+    if (isValidating) {
+      return
+    }
+
+    await setRegion({
+      session,
+      onSuccess: () => {
+        setInput('')
+        closeRegionSlider()
+      },
+      postalCode: input,
+      errorMessage: inputField?.errorMessage,
+      noProductsAvailableErrorMessage:
+        inputField?.noProductsAvailableErrorMessage,
+    })
+  }
+
+  const idkPostalCodeLinkProps = {
+    href: idkPostalCodeLink?.to,
+    children: (
+      <>
+        {idkPostalCodeLink?.text}
+        {!!idkPostalCodeLink?.icon?.icon && (
+          <UIIcon
+            name={idkPostalCodeLink?.icon?.icon}
+            aria-label={idkPostalCodeLink?.icon?.alt}
+            width={20}
+            height={20}
+          />
+        )}
+      </>
+    ),
+  }
+
+  return (
+    <UIFilterSlider
+      data-fs-filter-region-slider
+      overlayProps={{
+        className: `section ${styles.section} section-filter-slider`,
+      }}
+      title={
+        cmsData?.deliverySettings?.postalCodeEditSlider?.[
+          regionSliderType === 'setLocation'
+            ? 'chooseDeliveryMethod'
+            : 'changeLocation'
+        ]
+      }
+      size="partial"
+      direction="rightSide"
+      onClose={() => {}}
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lucasfp13
body: **question**: Shouldn't we send a `closeRegionSlider` here?
created_at: 2025-05-20T13:14:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const { isValidating, ...session } = useSession()
+  const inputRef = useRef<HTMLInputElement>(null)
+
+  const inputField = cmsData?.inputField
+
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const [input, setInput] = useState<string>('')
+
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
+
+  const handleSubmit = async () => {
+    if (isValidating) {
+      return
+    }
+
+    await setRegion({
+      session,
+      onSuccess: () => {
+        setInput('')
+        closeRegionSlider()
+      },
+      postalCode: input,
+      errorMessage: inputField?.errorMessage,
+      noProductsAvailableErrorMessage:
+        inputField?.noProductsAvailableErrorMessage,
+    })
+  }
+
+  const idkPostalCodeLinkProps = {
+    href: idkPostalCodeLink?.to,
+    children: (
+      <>
+        {idkPostalCodeLink?.text}
+        {!!idkPostalCodeLink?.icon?.icon && (
+          <UIIcon
+            name={idkPostalCodeLink?.icon?.icon}
+            aria-label={idkPostalCodeLink?.icon?.alt}
+            width={20}
+            height={20}
+          />
+        )}
+      </>
+    ),
+  }
+
+  return (
+    <UIFilterSlider
+      data-fs-filter-region-slider
+      overlayProps={{
+        className: `section ${styles.section} section-filter-slider`,
+      }}
+      title={
+        cmsData?.deliverySettings?.postalCodeEditSlider?.[
+          regionSliderType === 'setLocation'
+            ? 'chooseDeliveryMethod'
+            : 'changeLocation'
+        ]
+      }
+      size="partial"
+      direction="rightSide"
+      onClose={() => {}}
+      footer={false}
+    >
+      <span data-fs-filter-region-slider-description>
+        {cmsData?.deliverySettings?.description}
+      </span>
+      <UIInputField
+        id={'region-slideover-input-field'}
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lucasfp13
body: ```suggestion
        id="region-slider-input-field"
```
created_at: 2025-05-20T13:15:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,22 +20,29 @@ interface FacetValue {
 interface FilterDeliveryOptionProps {
   item: FacetValue
   deliveryCustomLabels: DeliveryCustomLabels
+  cmsData: Record<string, any>
 }
 
 export default function FilterDeliveryOption({
   item,
   deliveryCustomLabels,
+  cmsData,
 }: FilterDeliveryOptionProps) {
   const { city, postalCode } = sessionStore.read()
-  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
+  const {
+    regionSlider: { type: regionSliderType },
+    openRegionSlider,
+  } = useUI()
 
+  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
   const mapDeliveryCustomLabel: Record<string, string> = {
     delivery: deliveryCustomLabels?.delivery ?? 'Shipping to',
     'pickup-in-point': deliveryCustomLabels?.pickupInPoint ?? 'Pickup at',
     'pickup-nearby': deliveryCustomLabels?.pickupNearby ?? 'Pickup Nearby',
     'pickup-all': deliveryCustomLabels?.pickupAll ?? 'Pickup Anywhere',
   }
 
+  const changeLocation = 'changeLocation'
path: packages/core/src/components/search/Filter/FilterDeliveryOption.tsx
user: login: lucasfp13
body: **nitpick**: Would we benefit of having thise consts with the same value name?
created_at: 2025-05-20T14:11:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -13,6 +13,12 @@ export interface Popover {
   triggerRef?: RefObject<HTMLElement>
 }
 
+type RegionSliderType = 'setLocation' | 'changeLocation'
+
+export type RegionSlider = {
+  type: RegionSliderType | 'none'
path: packages/components/src/hooks/UIProvider.tsx
user: login: lariciamota
body: I'm fine with renaming it, but I had chosen "type" because it indicates _which_ region slider it is.
The _action_ would be to `open` the region slider of _type_ `setLocation`, for example. What do you think?
created_at: 2025-05-20T18:23:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -13,6 +13,12 @@ export interface Popover {
   triggerRef?: RefObject<HTMLElement>
 }
 
+type RegionSliderType = 'setLocation' | 'changeLocation'
+
+export type RegionSlider = {
+  type: RegionSliderType | 'none'
path: packages/components/src/hooks/UIProvider.tsx
user: login: lucasfp13
body: Hmm, that's right. It's fine to keep type 🤝 
created_at: 2025-05-20T18:30:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lariciamota
body: This would be the state of the regionSlider and we're accessing which type of regionSlider is opened at the moment. Do you have a suggestion of naming to indicate this?
created_at: 2025-05-20T18:31:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,22 +20,29 @@ interface FacetValue {
 interface FilterDeliveryOptionProps {
   item: FacetValue
   deliveryCustomLabels: DeliveryCustomLabels
+  cmsData: Record<string, any>
 }
 
 export default function FilterDeliveryOption({
   item,
   deliveryCustomLabels,
+  cmsData,
 }: FilterDeliveryOptionProps) {
   const { city, postalCode } = sessionStore.read()
-  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
+  const {
+    regionSlider: { type: regionSliderType },
+    openRegionSlider,
+  } = useUI()
 
+  const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
   const mapDeliveryCustomLabel: Record<string, string> = {
     delivery: deliveryCustomLabels?.delivery ?? 'Shipping to',
     'pickup-in-point': deliveryCustomLabels?.pickupInPoint ?? 'Pickup at',
     'pickup-nearby': deliveryCustomLabels?.pickupNearby ?? 'Pickup Nearby',
     'pickup-all': deliveryCustomLabels?.pickupAll ?? 'Pickup Anywhere',
   }
 
+  const changeLocation = 'changeLocation'
path: packages/core/src/components/search/Filter/FilterDeliveryOption.tsx
user: login: lariciamota
body: I'll think of a better way to be safe
created_at: 2025-05-20T19:01:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const { isValidating, ...session } = useSession()
+  const inputRef = useRef<HTMLInputElement>(null)
+
+  const inputField = cmsData?.inputField
+
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const [input, setInput] = useState<string>('')
+
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
+
+  const handleSubmit = async () => {
+    if (isValidating) {
+      return
+    }
+
+    await setRegion({
+      session,
+      onSuccess: () => {
+        setInput('')
+        closeRegionSlider()
+      },
+      postalCode: input,
+      errorMessage: inputField?.errorMessage,
+      noProductsAvailableErrorMessage:
+        inputField?.noProductsAvailableErrorMessage,
+    })
+  }
+
+  const idkPostalCodeLinkProps = {
+    href: idkPostalCodeLink?.to,
+    children: (
+      <>
+        {idkPostalCodeLink?.text}
+        {!!idkPostalCodeLink?.icon?.icon && (
+          <UIIcon
+            name={idkPostalCodeLink?.icon?.icon}
+            aria-label={idkPostalCodeLink?.icon?.alt}
+            width={20}
+            height={20}
+          />
+        )}
+      </>
+    ),
+  }
+
+  return (
+    <UIFilterSlider
+      data-fs-filter-region-slider
+      overlayProps={{
+        className: `section ${styles.section} section-filter-slider`,
+      }}
+      title={
+        cmsData?.deliverySettings?.postalCodeEditSlider?.[
+          regionSliderType === 'setLocation'
+            ? 'chooseDeliveryMethod'
+            : 'changeLocation'
+        ]
+      }
+      size="partial"
+      direction="rightSide"
+      onClose={() => {}}
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lariciamota
body: I had added the `closeRegionSlider` to the `FilterSlider` alongside the `closeFilter`, but I'll test sending it here instead
created_at: 2025-05-20T19:22:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
+    closeRegionSlider,
+  } = useUI()
+  const { isValidating, ...session } = useSession()
+  const inputRef = useRef<HTMLInputElement>(null)
+
+  const inputField = cmsData?.inputField
+
+  const idkPostalCodeLink = cmsData?.idkPostalCodeLink
+
+  const [input, setInput] = useState<string>('')
+
+  const { loading, setRegion, regionError, setRegionError } = useRegion()
+
+  const handleSubmit = async () => {
+    if (isValidating) {
+      return
+    }
+
+    await setRegion({
+      session,
+      onSuccess: () => {
+        setInput('')
+        closeRegionSlider()
+      },
+      postalCode: input,
+      errorMessage: inputField?.errorMessage,
+      noProductsAvailableErrorMessage:
+        inputField?.noProductsAvailableErrorMessage,
+    })
+  }
+
+  const idkPostalCodeLinkProps = {
+    href: idkPostalCodeLink?.to,
+    children: (
+      <>
+        {idkPostalCodeLink?.text}
+        {!!idkPostalCodeLink?.icon?.icon && (
+          <UIIcon
+            name={idkPostalCodeLink?.icon?.icon}
+            aria-label={idkPostalCodeLink?.icon?.alt}
+            width={20}
+            height={20}
+          />
+        )}
+      </>
+    ),
+  }
+
+  return (
+    <UIFilterSlider
+      data-fs-filter-region-slider
+      overlayProps={{
+        className: `section ${styles.section} section-filter-slider`,
+      }}
+      title={
+        cmsData?.deliverySettings?.postalCodeEditSlider?.[
+          regionSliderType === 'setLocation'
+            ? 'chooseDeliveryMethod'
+            : 'changeLocation'
+        ]
+      }
+      size="partial"
+      direction="rightSide"
+      onClose={() => {}}
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lariciamota
body: As discussed through DM, changing it introduced a bug, and leaving it as is matches how the `closeFilter` is handled, so we decided not to change it.
created_at: 2025-05-20T20:59:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,136 @@
+import {
+  useUI,
+  type FilterSliderProps as UIFilterSliderProps,
+  type IconProps as UIIconProps,
+  type InputFieldProps as UIInputFieldProps,
+} from '@faststore/ui'
+import dynamic from 'next/dynamic'
+import { useRef, useState } from 'react'
+import useRegion from 'src/components/region/RegionModal/useRegion'
+import { useSession } from 'src/sdk/session'
+import type { RegionalizationCmsData } from 'src/utils/globalSettings'
+import styles from './section.module.scss'
+
+const UIFilterSlider = dynamic<UIFilterSliderProps>(
+  () =>
+    /* webpackChunkName: "UIFilterSlider" */
+    import('@faststore/ui').then((mod) => mod.FilterSlider),
+  { ssr: false }
+)
+const UIInputField = dynamic<UIInputFieldProps>(() =>
+  /* webpackChunkName: "UIInputField" */
+  import('@faststore/ui').then((mod) => mod.InputField)
+)
+const UIIcon = dynamic<UIIconProps>(() =>
+  /* webpackChunkName: "UIIcon" */
+  import('@faststore/ui').then((mod) => mod.Icon)
+)
+const UILink = dynamic(() =>
+  /* webpackChunkName: "UILink" */
+  import('@faststore/ui').then((mod) => mod.Link)
+)
+
+type RegionSliderProps = {
+  cmsData: RegionalizationCmsData
+}
+
+function RegionSlider({ cmsData }: RegionSliderProps) {
+  const {
+    regionSlider: { type: regionSliderType },
path: packages/core/src/components/region/RegionSlider/RegionSlider.tsx
user: login: lucasfp13
body: Yeah, ok then let's keep type it makes sense
created_at: 2025-05-22T17:03:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: codesandbox-ci[bot]
created_at: 2025-05-19T15:53:05Z
body: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/vtex/faststore/pr/2851/builds/618885) or the icon next to each commit SHA.
author_association: NONE
user: login: hellofanny
created_at: 2025-05-22T00:48:22Z
body: @beatrizmilhomem I've addressed the majority of the issues that you mentioned ⭐ Can you check again in this [preview](https://vendemo-cm9sir9v900u7z6llkl62l70j-k5r6r35q4.b.vtex.app/) Thanksss

|mobile|desktop|
|-|-|
|<img width="391" alt="image" src="https://github.com/user-attachments/assets/9eb4ac59-8e1d-4c86-87f9-5b60ba75fc51" />|<img width="860" alt="image" src="https://github.com/user-attachments/assets/4da79f08-4fc9-4989-ab2f-805af3525edf" />|

There are 2 points that I haven't cover yet:
1. Close button should be 38x38 and the icon 24px.  (Let's continue this discussion in this [thread](https://vtex.slack.com/archives/C03L3CRCDC4/p1747860576975459?thread_ts=1747757289.741739&cid=C03L3CRCDC4) so we can decided a pattern for all those buttons 👍 )

2. Sorting button size — the label wrapping doesn't look great 🙈. The issue is that we're using the native browser select element with a custom layer on top, so I'm not sure adding an ellipsis is even feasible here. I don't think it's a quick fix for this PR, so could we move it to the backlog and address it later? 
author_association: CONTRIBUTOR