Saltar al contenido principal

<PriceChangedWarning>

Surfaced when useReservation().priceChanged is true — the server's authoritative reservation.subtotal (line items as actually held) differs from the estimate.subtotal the UI captured pre-reservation. Default UI shows the old/new totals + the delta + accept/cancel buttons. Returns null when there's nothing to warn about — safe to mount unconditionally.

Import

import { PriceChangedWarning } from "@feelrift/react";

Basic usage

import {
CheckoutForm,
PriceChangedWarning,
ReservationSummary,
RiftEvent,
RiftProvider,
} from "@feelrift/react";

<RiftProvider>
<RiftEvent eventId="evt_summerfest_2026">
<ReservationSummary />
<PriceChangedWarning />
<CheckoutForm returnUrl="https://your.site/checkout/return" />
</RiftEvent>
</RiftProvider>;

Props

Accepts all HTMLAttributes<HTMLDivElement> plus:

NameTypeRequiredDefaultDescription
asChildbooleanNofalseSwap the wrapping <div> via Radix Slot.
childrenReactNodeNoReplace the default rendering. Composed inside the wrapper.
acceptLabelReactNodeNot("reservation.priceChangedAccept")One-off label for the accept button.
cancelLabelReactNodeNot("reservation.priceChangedCancel")One-off label for the cancel button.
onAccept() => voidNoFires when the user accepts the new price. Consumer typically does nothing (the reservation is already at the new price).
onCancel() => voidNoclearReservation()Fires when the user cancels. Default clears the reservation; override to navigate back, etc.
classNamestringNoAppended to the SDK's rift-price-changed-warning class.
…restHTMLAttributes<HTMLDivElement>NoForwarded to the root element.

onAccept / onCancel

The reservation is already at the server's new price — accepting just means the user proceeds to checkout. Cancel clears the reservation by default, which forces the user back through the picker to re-confirm intent against the new price.

<PriceChangedWarning
onAccept={() => track("price_change_accepted")}
onCancel={() => router.push("/availability")}
/>

Render output

<div role="alert" aria-atomic="true" class="rift-price-changed-warning">
<div class="rift-price-changed-warning__title">Price has changed</div>
<div class="rift-price-changed-warning__detail">
The total updated from $40.00 to $45.00 between reservation and checkout.
<span class="rift-price-changed-warning__delta--up"> (+$5.00)</span>
</div>
<div class="rift-price-changed-warning__actions">
<button class="rift-price-changed-warning__accept">Accept new price</button>
<button class="rift-price-changed-warning__cancel">Cancel</button>
</div>
</div>

role="alert" + aria-atomic="true" so the entire region (title + detail + delta) announces as a single update on the first render where priceChanged flips to true.

Behavior

  • Conditional render. Returns null unless useReservation().priceChanged is true AND both data and estimate are present. Safe to mount unconditionally.
  • Price comparison. Compares reservation.data.subtotal against reservation.estimate.subtotal — both are line-item totals (sum of quantity × unitPrice across reserved holds), so the warning fires only when the actual reserved line items diverge from what the picker showed. Server modifiers (fees, taxes) appear in the checkout breakdown, not here.
  • Default cancel = clear. clearReservation() removes the reservation slot from SDK state, forcing the user to restart selection. Override onCancel when "cancel" should navigate instead.

Examples

Custom layout, default data

<PriceChangedWarning>
<p>
The price changed. <strong>Please re-confirm</strong>.
</p>
</PriceChangedWarning>

Track delta to analytics

function TrackedWarning() {
const { priceDelta } = useReservation();
return (
<PriceChangedWarning
onAccept={() => track("price_change_accepted", { delta: priceDelta })}
/>
);
}
  • useReservation — populates priceChanged, priceDelta, data, estimate. Public types exported from @feelrift/react.
  • <ReservationSummary> — usually rendered above this warning to show the new totals in context.
  • <CheckoutForm> — the next step after the user accepts.