Skip to content
KismetKismetDevelopers
llms.txt

The search island

View .md

Set the stay’s dates and guests once. The search-island contract is the floating island custom sites share with the Elements ActionBar: it collapses into an Add dates · 2 guests pill on a phone, docks as a bar on a desktop, carries the stay in the canonical stay URL, and once dated it re-runs availability for whatever page it is on.

The behavior ships as one headless hook from @kismet-tech/sdk/react. You render everything — pill, fields, sheet, bar — and the hook owns the stay state, the summary line, and the scoped availability request:

'use client';
import { useSearchIsland } from '@kismet-tech/sdk/react';
function GroupIsland({ groupSlug }: { groupSlug: string }) {
const island = useSearchIsland({
scope: { kind: 'group', groupSlug },
});
if (!island.isEditorOpen) {
return (
<button data-kismet-island-pill aria-expanded="false" onClick={island.openEditor}>
{island.summaryLabel}
</button>
);
}
return (
<form data-island-editor onSubmit={(event) => event.preventDefault()}>
<label htmlFor="check-in">Check-in</label>
<input id="check-in" type="date" onChange={(event) =>
island.applyStaySettings({ checkIn: event.target.value || undefined })} />
{/* check-out and guests likewise */}
</form>
);
}
  • summaryLabel is the collapsed line — Add dates · 2 guests undated, 12–15 Oct · 4 guests dated — produced by formatStaySelectionSummary, so every site reads the same.
  • applyStaySettings({ checkIn, checkOut, guests }) writes the canonical stay URL through useStayQuery. Dates travel as a pair; a reload, a shared link, or the move to a property page keeps them.
  • availabilityRequest is undefined while undated, then { checkIn, checkOut, guests, group? } — the exact options for vacationRental.availability.get. The group key is present only when the scope is a group, so a group page re-runs availability for that group and a results page re-runs it for the current set.

Pass the scope the page is on:

Page Scope Availability request
Group landing { kind: 'group', groupSlug } carries group: groupSlug
Results { kind: 'results' } no group key

When the stay is dated, cards show the before-tax stay total from vacationRental.availability.get — totalBeforeTaxMinor per vacation rental — never a final quote. Confirmed-unavailable vacation rentals are marked (Not available for your dates) or sink to the bottom of the list through sortVacationRentals; a rental whose availability is unknown stays in place and is never treated as unavailable. Those rendered-results rules are owned by the browse channel, property-card, and results-page contracts — the island contract governs where the stay lives, not how results react.

search-island@1 builds on the stay-query contract. State ownership is the MUST, enforced statically on every site that runs kismet recipes check — both starters do — and on rendered pages by the two must-severity criteria of the search-island recipe scenario:

Requirement Level Check
Stay settings live in the canonical stay URL (static) MUST recipes/stay-query-source
Never hold the stay dates or guest count in local component state MUST NOT recipes/search-island-source
Applied settings reach the canonical URL (rendered) MUST conformance/search-island-stay-url
Stay survives a reload (rendered) MUST conformance/search-island-persistence
Collapsed summary pill reflects the observed stay SHOULD conformance/search-island-pill
Fields labelled and keyboard-enterable SHOULD conformance/search-island-fields
Availability rebinds to the active scope SHOULD conformance/search-island-scope

The recipe scenario grades a page that declares search-island: the runner fills the canonical stay form with the keyboard, reads the URL keys the page writes, reloads, and correlates the availability requests in that window. The pill SHOULD is scoped to pages that render the optional data-kismet-island-pill hook. A MUST miss fails the site; a SHOULD miss warns and never blocks a declaration.

Placement is free space: dock the bar, float the pill, restyle the sheet.