Headless / Location
Find and confirm an address
Build address search using the selected address and geocoder capabilities.
50 public parts · 4examples
@slices.sh/geocoder/headlessView as Markdown ↗Your design. Our behavior.
Explore the tree to see what each part controls. Gates reveal the relevant state; roots outline their scope.
Address.Root · Scope
Installation
Choose what your component needs. Run these commands in an initialized Next.js app.
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the service registry
Adds services/index.ts, which import "@/services" loads. A provider setup writes the same file, so skip this if your app has one.
npx add servicesInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/geocoder@^0.1.3Import from @slices.sh/geocoder/headless.
Install the service
Connect the parts to a provider. Skip this step if this service is already configured in your app.
npx add geocoder.photonAdds service configuration and API routes to your app, with the provider dependencies. For a headless composition, add import "@/services" after "use client".
The slices CLI installs the service and provisions its required resources in one command.
Start small
Parts bring the behavior. Use their default elements, or supply your own with render.
"use client"// services/index.ts comes from https://slices.sh/r/services.json (or any provider setup)import "@/services"import { Address } from "@slices.sh/geocoder/headless"export function Example() { return ( <Address.Root country="FR"> <Address.Label>Address</Address.Label> <Address.Input /> <Address.Popup> <Address.Suggestions> <Address.Items> <Address.Suggestion> {({ primary, secondary }) => ( <span> {primary} · {secondary} </span> )} </Address.Suggestion> </Address.Items> </Address.Suggestions> <Address.Attribution /> </Address.Popup> <Address.Value name="address" /> </Address.Root> )}Selection, keyboard navigation and the structured value stay connected.
API reference
Every public part used by this experience is listed below. Gates render children without adding an element. Element parts accept native element props and render; function children receive the state declared in their props. Scopes provide context rather than a visual element.
Address.Rootscope
An address field. The popup, its keyboard and its ARIA are Base UI's Autocomplete rather than this family's: the hand-rolled version this replaces latched shut after a blur, an Escape or a selection and never showed a suggestion again. Autocomplete and not Combobox because the value has to be allowed to be anything — plenty of real addresses are in no database, which is this family's whole argument — and `filter={null}` because the filtering is the provider's. Base UI's own context holds the open state and the highlight. That is a primitive's internal state rather than a slices concern, the same relationship `lib/part` already has with `use-render`, and the hooks below still own one thing each. → docs/rules/one-hook-one-concern.md
Props
18 documented props
| Prop | Type | Default |
|---|---|---|
layout | "card" | "box" | "form" | — |
fields | readonly AddressDetailFieldName[] | — |
markOptional | boolean | — |
scope | AutofillScope | — |
countryBias towards a country, as ISO 3166-1 alpha-2. | string | — |
countries | readonly string[] | null | — |
countryScope | "bias" | "restrict" | — |
enabledLeft out or | Enabled | — |
configThe geocoder config, | string | — |
languageThe language the names come back in. Absent asks with the browser's own. | string | — |
enterPicksFirstEnter selects the first suggestion only when explicitly enabled. | boolean | false |
undoWindow | number | — |
nearBias towards a place. "Use my location" supplies one as soon as it is allowed. | Point | — |
kindsOnly these kinds, where a form wants nothing coarser than a street. | AddressKind[] | — |
recent | RecentAddressSource | — |
recentStorageKey | string | — |
initial | Address | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/address-root.tsx
Address.UndoScopecontent · <div>
No document listener: another address or another form keeps its own undo history.
Required scope
Address.UndoScope must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/undo-scope.tsx
Address.Labelcontent · <label>
The visible label for the box, or for one of the fields beside it. A visible one, not an `aria-label`: a label somebody can click is a bigger target, which is the whole point on a phone.
Required scope
Address fields must be inside <Address.Root>.
Address.Label must be inside <Address.Root>.
Props
3 documented props · Native <label> attributes supported
| Prop | Type | Default |
|---|---|---|
field | AddressDetailFieldName | — |
childrenContent rendered inside this part. | ReactNode | ((state: { optional: boolean; kind: string | null }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/label.tsx
Address.Inputinput · <input>
The box itself, and the street line of the address. `role`, `aria-expanded`, `aria-controls` and `aria-activedescendant` are the primitive's now. What is set here is what the primitive has no opinion about: the autofill token, so the browser's own one-tap address fill works and SC 1.3.5 is satisfied; the keyboard hints a phone reads; and the link to the notes underneath, which have no other way to be heard.
Required scope
Address.Input must be inside <Address.Root>.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/address-input.tsx
Address.Clearaction · <button>
Empties the box. The primitive's own Clear, which keeps focus in the field rather than dropping it to the body, and hides itself while there is nothing to clear. Emptying the box is an ordinary value change as far as this family is concerned, so there is nothing to do here but let it through.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/clear.tsx
Address.Popupcontent · <div>
Where the suggestions appear. A positioned layer rather than an absolutely-positioned block, which is what buys the three things the hand-rolled list did not have: it flips above the box when there is no room below, it publishes `--anchor-width` and `--available-height` for the skin to size itself by, and it scrolls the highlighted option into view — browsers do not scroll to an `aria-activedescendant`, so somebody has to.
Required scope
Address.Popup must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/popup.tsx
Address.Suggestionscontent · <ul>
The list. Mounted for as long as the popup is, so `aria-controls` on the box names something that exists whenever the box says it is expanded. The element itself comes from the caller — a neutral layer renders no host element — and `role="listbox"` is the primitive's.
Required scope
Address.Suggestions must be inside <Address.Root>.
Props
2 documented props · Native <ul> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/suggestions.tsx
Address.Recentcontent · <li>
A non-selectable heading inside the autocomplete list, never above the field.
Required scope
Address.Recent must be inside <Address.Root>.
Props
2 documented props · Native <li> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/recent.tsx
Address.RecentItemsscope
Only while the street is empty and nothing is chosen. Recent is the non-selectable heading inside the list, RecentItems repeats its children per saved address, RecentAddress is a button that fills the whole address and returns focus to the street, and RecentSeparator divides them from live suggestions.
Required scope
Address.RecentItems must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/recent-items.tsx
Address.RecentAddressaction · <button>
Only while the street is empty and nothing is chosen. Recent is the non-selectable heading inside the list, RecentItems repeats its children per saved address, RecentAddress is a button that fills the whole address and returns focus to the street, and RecentSeparator divides them from live suggestions.
Required scope
Address.RecentAddress must be inside <Address.Root>.
Address.RecentAddress must be inside <Address.RecentItems>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/recent-address.tsx
Address.RecentSeparatorcontent · <li>
Only while the street is empty and nothing is chosen. Recent is the non-selectable heading inside the list, RecentItems repeats its children per saved address, RecentAddress is a button that fills the whole address and returns focus to the street, and RecentSeparator divides them from live suggestions.
Required scope
Address.RecentSeparator must be inside <Address.Root>.
Props
2 documented props · Native <li> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/recent-separator.tsx
Address.Itemsscope
Each suggestion in its own scope.
Required scope
Address.Items must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/suggestion-items.tsx
Address.Suggestioncontent · <li>
One option. The element comes from the caller, because a neutral layer renders no host element, and `role="option"` is the primitive's. `aria-selected` is not: the primitive leaves it off because its list is not a selection. That attribute is load-bearing: Chrome plus VoiceOver announces a moving `aria-activedescendant` only when the option it names carries `aria-selected="true"`, so without it the box is silent on the most common pairing there is.
Required scope
Address.Suggestion must be inside <Address.Items>.
Address.Suggestion must be inside <Address.Root>.
Props
2 documented props · Native <li> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: SuggestionState) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/suggestion.tsx
Address.Matchcontent · <span>
The matched text is styled by a role; neither query nor provider text becomes HTML.
Required scope
Address.Match must be inside <Address.Items>.
Address.Match must be inside <Address.Root>.
Props
3 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
fieldRequired | "primary" | "secondary" | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/match.tsx
Address.Notescontent · <div>
Everything the box has to say, in one place that is always there. One region, because the box's `aria-describedby` has to name an element that exists even when there is nothing to say — and because two live regions announcing at once is how a screen reader ends up reading the result count over the error. WCAG 2.2 SC 4.1.3. Whatever a skin does to it, it must never be `display: none`, `hidden` or `aria-hidden`, not even while it is empty: a region that appears in the same frame as its first words is a region several screen readers say nothing about. Mounted, rendered, and empty is the only shape that announces reliably — which is why everything the field has to say goes in here rather than beside the control it is about.
Required scope
Address.Notes must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/notes.tsx
Address.Searchinggate
A question has been asked and not yet answered.
Required scope
Address.Searching must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/searching.tsx
Address.Resolvinggate
Gates and triggers for each answer. Searching: a question asked and not answered. Resolving: the optional detail lookup after a choice. TooShort: under the three-character floor, children get { least }. NoMatches: the provider answered with nothing. Failed gets { error }, the GeocoderErrorSlug, so a throttle and an outage are not one sentence. Retry appears only after a refusal and asks again.
Required scope
Address.Resolving must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/resolving.tsx
Address.TooShortgate
Typed, but not enough of it to ask yet. The one state with nothing on screen and a reason for it, which is exactly the message no markup can carry and a screen reader therefore never hears unless somebody says it.
Required scope
Address options must be inside <Address.Root>.
Address.TooShort must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { least: number }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/too-short.tsx
Address.NoMatchesgate
The geocoder found nothing. Which is not the end of the road: the fields are there to be typed into, because a geocoder that has never heard of somebody's address must not be the reason they cannot check out.
Required scope
Address options must be inside <Address.Root>.
Address.NoMatches must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/no-matches.tsx
Address.ResultCountcontent · <span>
How many suggestions there are, said out loud. A screen reader hears the highlighted option read out and is told nothing about how many others there are, or that a query is still too short to have asked. The markup does not carry either, which is why this part exists and why `Address.TooShort` has words of its own. WCAG 2.2 SC 4.1.3.
Required scope
Address.ResultCount must be inside <Address.Root>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: CountState) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/result-count.tsx
Address.Failedcontent · <p>
The geocoder refused, with the reason. The reason is handed over rather than flattened into one sentence: telling somebody the service is down when they have been throttled, and there is a Retry beside it, is a small lie. → docs/rules/capability-honesty.md
Required scope
Address.Failed must be inside <Address.Root>.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { error: GeocoderErrorSlug }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/search-failed.tsx
Address.Retryaction · <button>
Asks the same question again, which is the only useful answer to being throttled.
Required scope
Address.Retry must be inside <Address.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/retry.tsx
Address.Attributioncontent · <a>
Always show the active provider's credit, including after its popup closes. It opens in a new tab: following it in this one would leave the form somebody is halfway through.
Props
2 documented props · Native <a> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/attribution.tsx
Address.Layoutcontent
Which of the two shapes this screen is, for the part of a layout CSS cannot reach. Width is a stylesheet's job — every size, column count and hit area here is a media query. Words are not: a button that is the width of a phone says "Use my location" and the same button beside a desktop field says "Use my current location", and no breakpoint can rewrite a sentence. Both are written out, and exactly one of them is in the DOM.
Required scope
Address.Layout must be inside <Address.Root>.
Props
3 documented props
| Prop | Type | Default |
|---|---|---|
modeRequired | "wide" | "narrow" | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/layout.tsx
Address.UseMyLocationaction · <button>
One tap instead of an address. `locating` is handed over because a position takes as long as it takes — ten seconds on a phone that has to wake its radio — and a dimmed button is not an answer to "is it working?". The words change instead. Renders nothing at all where the browser has no geolocation, or the provider cannot reverse a point. A refusal keeps the focused control mounted and disabled, with the explanation in LocationNote. → docs/rules/capability-honesty.md
Capability: reverse
Required scope
Address.UseMyLocation must be inside <Address.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { locating: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/use-my-location.tsx
Address.LocationNotecontent · <p>
What happened when the browser was asked where it is. Three answers worth different words: a permission denied, which nothing here can undo; a point with nothing mapped at it, which for most of the ocean is the truth; and a lookup that simply failed. The state is handed over rather than flattened.
Capability: reverse
Required scope
Address.LocationNote must be inside <Address.Root>.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { state: Told }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/location-note.tsx
Address.EnterByHandaction · <button>
Opens the fields without choosing anything, for an address no geocoder has.
Required scope
Address.EnterByHand must be inside <Address.Root>.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
inPopup | boolean | false |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/enter-by-hand.tsx
Address.Entrycontent · <div>
The address is being filled in, field by field. Open as soon as anything has been chosen, because a lookup nobody can see the rest of is a lookup nobody can correct — and 9% of hand-typed addresses have a typo in them. A group rather than a gate around one, because five boxes in a border are five unrelated boxes to somebody hearing them one at a time. Give it a name and a screen reader says what they belong to on the way in.
Required scope
Address.Entry must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/entry.tsx
Address.FieldOrdercontent · <div>
Reorder keyed field groups in the DOM, so reading and tab order agree with the layout.
Required scope
Address.FieldOrder must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenRequired | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/field-order.tsx
Address.FieldGroupcontent · <div>
The rest of the address. Entry is the group of fields; give it an aria-label. EnterByHand opens it with nothing chosen. Field is one text input with its own autofill token and requiredness from the country's metadata; FieldChoice renders a native select where the metadata lists regions, and FieldSuggestions offers countries without preventing others. FieldGroup holds one field and its label, with details to keep it closed until manual entry; FieldOrder sorts its FieldGroup children into the country's order in the DOM. Save, in the card layout, checks the fields in reading order and folds them into the card.
Required scope
Address.FieldGroup must be inside <Address.Root>.
Props
4 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
fieldRequired | AddressFieldName | — |
details | boolean | false |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/field-group.tsx
Address.Fieldinput · <input>
One field of the address, other than the street line the box itself holds. Each carries its own autofill token, which is what a browser and a password manager fill on, and a postcode carries a number pad only where postcodes in that country are digits.
Required scope
Address fields must be inside <Address.Root>.
Address.Field must be inside <Address.Root>.
Props
5 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
fieldRequired | AddressDetailFieldName | — |
fallback | boolean | false |
invalidMessage | string | "" |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/field.tsx
Address.FieldChoiceinput · <select>
Native keyboard and mobile pickers; unrecognised provider values remain editable choices.
Required scope
Address.FieldChoice must be inside <Address.Root>.
Address fields must be inside <Address.Root>.
Props
4 documented props · Native <select> attributes supported
| Prop | Type | Default |
|---|---|---|
fieldRequired | AddressDetailFieldName | — |
invalidMessage | string | "" |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/field-choice.tsx
Address.FieldSuggestionscontent · <datalist>
Suggestions keep manual entry possible outside the pinned country subset.
Required scope
Address.FieldSuggestions must be inside <Address.Root>.
Props
3 documented props · Native <datalist> attributes supported
| Prop | Type | Default |
|---|---|---|
fieldRequired | AddressDetailFieldName | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/field-suggestions.tsx
Address.NeedsNumbercontent · <p>
The address is not precise enough to deliver to. "Rue de Rivoli" is a real answer to a real query and a parcel cannot be sent to it — the five Rivolis Photon returns have no house number between them, because the street is what was mapped. Saying so beats letting somebody check out and find out later.
Required scope
Address.NeedsNumber must be inside <Address.Root>.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { kind: AddressKind }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/needs-number.tsx
Address.PhoneRootscope
The address's phone number, with its own country list. Its default country is the address's, so a national number is read the way the address writes one, and a new address country moves the default with it. Once somebody picks a country, or types a `+`, the phone keeps that one: a French number goes with a United States address. No phone value goes to the geocoder.
Capability: phone (service, optional)
Required scope
Address.PhoneRoot must be inside <Address.Root>.
Props
6 documented props
| Prop | Type | Default |
|---|---|---|
enabled
| Enabled | — |
defaultCountryWhere a national number is read when the address has no country yet. | string | — |
initialThe number the field starts with, as E.164. | string | — |
allowedCountriesThe countries a number may be in, which are also the ones the list offers. Without it, every country. | readonly string[] | — |
locale | string | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/phone-root.tsx
Address.Phonecontent
The number, typed in its country's own format. Typing it is typing in the form, so it ends an undo's offer.
Capability: phone (service, optional)
Required scope
Address.Phone must be inside <Address.Root>.
Props
3 documented props
| Prop | Type | Default |
|---|---|---|
invalidMessage | string | — |
childrenContent rendered inside this part. | ReactNode | ((state: { invalid: boolean; status: PhoneStatus }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/address-phone.tsx
Address.Saveaction · <button>
Collapses the fields to the card, once what is in them would be accepted. Checked here because this is a button and not the form's submit: nothing else would say that a postcode is wrong until somebody checked out. The first field that is empty or invalid takes focus and says why in the browser's own words. → docs/rules/one-submit-per-form.md
Required scope
Address.Save must be inside <Address.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/save.tsx
Address.FilledMarkcontent · <div>
After a choice or a recent address fills the fields. UndoScope confines Cmd/Ctrl+Z to this address, with no document listener. Undo restores the previous values and focus while its window lasts. FilledMark shows that fields were just filled, as data-state="filled" on their groups.
Required scope
Address.FilledMark must be inside <Address.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/filled-mark.tsx
Address.Undoaction · <button>
After a choice or a recent address fills the fields. UndoScope confines Cmd/Ctrl+Z to this address, with no document listener. Undo restores the previous values and focus while its window lasts. FilledMark shows that fields were just filled, as data-state="filled" on their groups.
Required scope
Address.Undo must be inside <Address.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/undo.tsx
Address.Chosengate
An address has been chosen from the suggestions. In the card layout it waits for the card: while the box and its fields are open the address is being corrected there, and a card beside them would say it twice. For the card of an address nobody chose, typed and saved by hand, see `Address.Settled`.
Required scope
Address.Chosen must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { address: Address }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/chosen.tsx
Address.Settledgate
The card layout has an address and is showing it as a card, in place of the box and the fields. Settled by choosing a suggestion or by saving what was typed, so a hand-typed address that no geocoder has gets the same card as a chosen one.
Required scope
Address.Settled must be inside <Address.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { address: Address }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/settled.tsx
Address.Linesscope
The chosen address, one line per line an envelope would have. Built from whichever fields the provider filled, so an address with no street number has one fewer line rather than a blank one — most of the world has no street number. → docs/rules/capability-honesty.md
Required scope
Address.Lines must be inside <Address.Root>.
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
omitStreet | boolean | false |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/address-lines.tsx
Address.Linecontent · <span>
Chosen opens once an address is chosen from the list, Settled once the card layout shows its card; both give { address }. Lines repeats once per envelope line and Line renders it; omitStreet leaves out the line the box already shows. Change is the pencil: it forgets the choice and focuses the box, or with edit opens the fields on the address as it stands.
Required scope
Address.Line must be inside <Address.Lines>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/line.tsx
Address.Changeaction · <button>
Puts the box back to searching, keeping what was typed. With `edit`, opens the fields on the address as it stands instead, which is what a pencil on a card is for when there are fields to correct it in. Over the primitive's own trigger, which moves focus into the box. This button unmounts as it is pressed — the chosen address is what it exists for — and focus would otherwise fall to the body, leaving somebody who pressed "change" with nowhere to type. A card has unmounted the box as well, so the trigger has nothing to focus there: the box comes back with this press, and takes focus once it has.
Required scope
Address.Change must be inside <Address.Root>.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
edit | boolean | false |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/change.tsx
Address.MapRootscope
A small map of the chosen point. MapRoot renders nothing until there is a point and map-tiles is installed. Map is the surface, role="img" with aria-busy while tiles load. MapStatus gets { status }. MapAttribution renders the map's credits that Attribution does not already show, and nothing when there are none.
Capability: map-tiles (service, optional)
Required scope
Address.MapRoot must be inside <Address.Root>.
Props
3 documented props
| Prop | Type | Default |
|---|---|---|
configThe map-tiles config, | string | — |
enabledLeft out or | Enabled | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/map-root.tsx
Address.Mapcontent · <div>
A small map of the chosen point. MapRoot renders nothing until there is a point and map-tiles is installed. Map is the surface, role="img" with aria-busy while tiles load. MapStatus gets { status }. MapAttribution renders the map's credits that Attribution does not already show, and nothing when there are none.
Capability: map-tiles (service, optional)
Required scope
Address.Map must be inside <Address.MapRoot>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/map.tsx
Address.MapStatuscontent · <p>
A small map of the chosen point. MapRoot renders nothing until there is a point and map-tiles is installed. Map is the surface, role="img" with aria-busy while tiles load. MapStatus gets { status }. MapAttribution renders the map's credits that Attribution does not already show, and nothing when there are none.
Capability: map-tiles (service, optional)
Required scope
Address.MapStatus must be inside <Address.MapRoot>.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { status: MapPreviewStatus }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/map-status.tsx
Address.MapAttributioncontent · <div>
The map's credits that `Address.Attribution` does not already show, each once. Nothing renders when there are none, so a pattern can put its "Map credits" popover inside without ever showing an empty one.
Capability: map-tiles (service, optional)
Required scope
Address.MapAttribution must be inside <Address.MapRoot>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { sources: readonly Source[] }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/map-attribution.tsx
Address.Accuracycontent · <span>
How near the browser thinks it got, in metres. The browser's own number, at 95% confidence, and shown only when it reported one. A browser that says nothing gets no line rather than a plausible-looking estimate, because "accurate to ~40 m" is the difference between the right building and the next one. And only while the address on screen is still the one the browser found: a metre count left over from a position, sitting under an address somebody has since searched for and chosen, is a number about somewhere else. → docs/rules/capability-honesty.md
Capability: reverse
Required scope
Address.Accuracy must be inside <Address.Root>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { metres: number }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/accuracy.tsx
Address.Valueinput · <input>
What the form sends. The whole address as JSON, because the parts of it that matter most have no field of their own: the coordinate, the ISO country code, and which half of the street line was the house number. Give it a `name` and a `<form>` posts it; read it with `JSON.parse` and it is an `Address`. Empty while every field is, which is how a server tells "nothing entered" from "entered nothing useful".
Required scope
Address.Value must be inside <Address.Root>.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/geocoder/src/headless/value.tsx
When something is missing
- No service configuration
- Install the geocoder setup below and import "@/services". Required service roots report missing setup; gates do not replace that configuration.
- Missing capability or parent scope
- Follow each part’s context requirements and the example composition. Capability-aware controls hide when the provider cannot perform their action.