figma guide
Designing store locator and pickup UI in Figma: map, inventory, and checkout handoff
Design store locator maps, pickup-in-store selectors, BOPIS checkout steps, and inventory badges in Figma with component variants and Dev Mode specs for omnichannel retail.
- Published
- Updated
- Jun 28, 2026
- Read time
- 8 min
- Level
- Beginner
Quick answer
Store locator and pickup UI connects online catalog to physical inventory through three reusable patterns: a locator map/list, a store selector modal, and checkout pickup steps. On PDP, show availability at nearby stores with stock badges and a Change store action. Checkout adds a Pickup person step and replaces shipping with Ready for pickup messaging. The locator itself is a split view—search + list on the left, map with pins on the right (stacked on mobile). Reuse saved addresses form patterns for pickup contact fields and order tracking for ready notifications. Start from the Figma guides hub and templates pillar.
Who this is for
- Product designers on omnichannel retail, grocery, apparel, and electronics with ship-to-home and pickup options.
- Design system teams aligning web, kiosk, and associate tools around one store entity model.
- Engineers integrating geolocation, store inventory APIs, curbside flows, and pickup SLA timers.
Pickup journey map
| Step | Surface | Key UI |
|---|---|---|
| Discover | PDP / PLP | Stock badge, “Pickup available” |
| Select store | StoreSelectorModal | Search, list, map pins |
| Cart | Cart summary | Selected store line + change link |
| Checkout | Delivery method | Ship vs pickup radio group |
| Pickup details | Checkout step | Name, phone, SMS opt-in |
| Payment | Order summary | No shipping line; pickup fee if any |
| Confirmation | Thank you page | Store address, hours, pickup code |
| Post-purchase | Email + account | Order tracking with ready state |
Verdict: store selection must be reversible until payment—always expose “Change store” in cart and checkout summary without forcing users back to PDP.
StoreLocator layout
| Zone | Desktop | Mobile |
|---|---|---|
| Search | Top bar: city, ZIP, or “Use my location” | Full-width search; location icon |
| Filters | Chips: Open now, Curbside, In stock | Horizontal scroll chips |
| Store list | Left column 40% | Full-width list below search |
| Map | Right 60% with pins | Collapsible map or full-screen toggle |
| Selected store card | Sticky detail at list bottom | Bottom sheet on pin tap |
StoreLocator
├── Variant: layout=split | mobileStack
├── Variant: context=pdp | standalone | checkout
├── Property: skuId (optional)
└── Layers:
├── SearchBar
├── FilterChips
├── StoreList
│ └── StoreListItem × n
├── MapCanvas
│ └── MapPin × n
└── SelectedStoreCard
Use Auto Layout for list items. Map is usually a static placeholder in Figma with annotated pin states—engineering swaps the live map SDK.
StoreListItem anatomy
| Part | Spec | Notes |
|---|---|---|
| Store name | Primary line | ”Downtown Kamloops” |
| Distance | ”2.4 km” | From geolocation or searched ZIP |
| Address | Single line truncated | Link opens native maps |
| Hours line | ”Open until 9 PM” or “Closed” | Real-time from API |
| Stock badge | In stock / Low / Out | Per SKU when skuId set |
| Services chips | Curbside, Locker | Reuse badge tokens |
| Select button | Primary on selected row | ”Select store” vs “Selected” |
StoreListItem
├── Variant: stock=in | low | out | unknown
├── Variant: selected=true | false
├── Property: storeId
├── Property: distanceKm=2.4
└── Layers:
├── StoreName
├── MetaRow (distance · hours)
├── AddressLine
├── StockBadge
├── ServiceChips
└── SelectButton
Out-of-stock rows may remain visible with disabled select and link to Ship to home—do not hide the store entirely unless policy requires it.
MapPin states
| Pin state | Visual | Interaction |
|---|---|---|
| Default | Brand color dot | Hover shows mini card |
| Selected | Larger pin + ring | Syncs list selection |
| Out of stock | Muted pin | Still selectable for ship-from-store rules |
| Cluster | Number bubble | Zoom to expand |
| User location | Distinct blue dot | Not selectable |
Annotate z-index and anchor point for engineering. Pair with search UI patterns when locator includes product search.
PDP pickup availability block
| Element | Purpose |
|---|---|
| Fulfillment toggle | Ship / Pickup tabs or radio |
| Selected store line | Name + change link → StoreSelectorModal |
| Stock message | ”Available today at Downtown” |
| Pickup SLA | ”Ready in 2 hours” vs “Ready tomorrow” |
| Unavailable fallback | Ship option or other stores link |
Place below size selector and above add to cart on PDP frames. Low stock should use the same semantic colors as PLP badges.
Checkout: ship vs pickup
| Delivery option | Summary changes | Hidden fields |
|---|---|---|
| Ship to address | Shipping line, address form | Store selector |
| Pickup in store | Store address block, pickup person | Shipping address |
| Curbside | Vehicle note optional | Same as pickup + spot field |
DeliveryMethodSelector
├── Variant: selected=ship | pickup | curbside
└── Layers:
├── OptionCard (ship)
├── OptionCard (pickup)
└── OptionCard (curbside, optional)
Order summary on checkout UI replaces Shipping with Pickup at Downtown and shows $0.00 or a pickup fee. Free shipping progress should hide when pickup is selected.
Pickup person form
| Field | Required | Notes |
|---|---|---|
| First / last name | Yes | May differ from account name |
| Phone | Yes | For ready SMS |
| Often optional | Receipt still goes to account email | |
| SMS notifications | Opt-in checkbox | Link to policy |
| Alternate pickup | Optional toggle | Second name field |
Reuse form input states and validation error patterns. Curbside add Vehicle color / plate only if operations require it—keep optional by default.
Confirmation and ready-for-pickup states
| State | User message | UI |
|---|---|---|
| Order placed | ”We’ll email when ready” | Store map thumbnail |
| Preparing | Progress in tracking UI | Stepper: Placed → Preparing |
| Ready | ”Ready for pickup” + code | Large pickup code, QR optional |
| Picked up | Completed | Archive in history |
| Expired / cancelled | Policy message | Link to support |
Ready state should show store hours, entrance instructions, and Add to calendar optional action. Use toasts only for ephemeral copy-to-clipboard on pickup code—not for the primary ready banner.
Standalone locator page vs modal
| Pattern | Best for | Drawbacks |
|---|---|---|
| Modal | PDP change store, checkout | Limited map space on mobile |
| Full page | SEO “Stores near me”, kiosk | Extra navigation step |
| Embedded iframe | Legacy retail stacks | Harder to style—avoid in new designs |
Verdict: one StoreSelectorModal component with density=compact for PDP and density=full for standalone page—same list item and pin components inside.
Handoff checklist
| Item | Dev Mode annotation |
|---|---|
| Store entity fields | id, name, lat, lng, hours, services |
| Inventory API | Per-SKU quantity, SLA minutes |
| Geolocation permission | Fallback to manual ZIP search |
| Selected store persistence | Session vs account saved store |
| Map provider | Pin assets, cluster rules |
| Pickup fee rules | Free vs flat vs waived over threshold |
| Analytics | store_search, store_select, fulfillment_pickup, fulfillment_ship |
| a11y | List selectable by keyboard; pins have text equivalent in list |
| Error states | Location denied, no stores, API timeout |
Use Dev Mode checklist and align store address formatting with saved addresses for consistency.
Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Store selected but cart still shows ship | Wrong fulfillment at checkout | Single selectedStoreId in cart model |
| Map-only locator on mobile | List is faster to scan | Default to list; map optional |
| No stock on list rows | Users select empty stores | StockBadge on every row when SKU known |
| Pickup code only in email | User at store without inbox | Show code in app + account |
| Hours static in designs | Closed store selected | Live hours + “Closed” disabled state |
| Curbside copy on every store | Wrong service promise | ServiceChips per store |
| Reusing shipping address form | Confusing labels | Dedicated pickup person fields |
| Locator pins with no list sync | Accessibility failure | Selection syncs both directions |
Recommended workflow
- Define fulfillment types with ops—pickup, curbside, locker, ship-from-store.
- Build
StoreListItem,MapPin, andStockBadgewith stock and selected variants. - Compose
StoreSelectorModaldesktop split and mobile stack frames. - Add PDP pickup block to product detail templates.
- Extend checkout with delivery selector and pickup person step on cart/checkout frames.
- Design confirmation and tracking ready states on order history rows.
- Hide or adapt shipping progress when pickup selected.
- Document API fields and analytics in Dev Mode.
FAQ
Show all stores or only stores with stock?
Default to stores with stock first, with toggle “Show all stores” for transparency. Exact sort is a product decision—annotate preferred order.
Guest checkout pickup?
Allow pickup with phone verification; prompt account creation after order with saved store preference.
Same-day vs next-day SLA?
Show dynamic SLA string from API—never hard-code “2 hours” in component defaults.
International stores?
Add country filter on locator search; currency on pricing stays checkout-scoped.
Associate-held inventory?
Optional Low stock — confirm at store badge variant when API confidence is partial.
Next steps
- Design saved addresses and address book UI in Figma — parallel form patterns
- Design shopping cart and checkout UI in Figma — fulfillment summary lines
- Design order history and order tracking UI in Figma — ready-for-pickup states
- Design product detail pages in Figma — PDP pickup block placement
- Design search UI in Figma — locator search bar patterns
§ Keep reading