@flamingo-stack/openframe-frontend-core 0.0.575 → 0.0.576

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flamingo-stack/openframe-frontend-core",
3
- "version": "0.0.575",
3
+ "version": "0.0.576",
4
4
  "description": "Shared design system and components for all Flamingo platforms",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,6 +39,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
39
39
  import { useIsHydrated } from '../../hooks/ui/use-is-hydrated';
40
40
  import { useHumanitySignals } from '../../hooks/use-humanity-signals';
41
41
  import { useMeetingBooking } from '../../hooks/use-meeting-booking';
42
+ import { useToast } from '../../hooks/use-toast';
42
43
  import {
43
44
  isSupportedFormField,
44
45
  type BookingConfirmation,
@@ -56,11 +57,11 @@ import { SlotPicker, SlotPickerSkeleton, dayKeyInZone } from './slot-picker';
56
57
 
57
58
  /**
58
59
  * Visitor-facing copy per booking-error code. Everything except SLOT_TAKEN
59
- * renders in a prominent `<Alert>` ABOVE the form the visitor just submitted
60
- * (an inline alert is deterministic in every embed context — a toast needs a
61
- * host-mounted provider this widget cannot assume). SLOT_TAKEN renders above
62
- * the calendar instead: its recovery flow returns the visitor there.
63
- * An unrecognized code (newer host than widget) falls back to the VALIDATION
60
+ * surfaces as an error TOAST at submit time, and ONLY as a toast (owner
61
+ * decision 2026-08-27 — no inline duplicate; hosts must mount the lib
62
+ * Toaster, as every hub platform does globally). SLOT_TAKEN renders above
63
+ * the calendar instead: its recovery flow returns the visitor there. An
64
+ * unrecognized code (newer host than widget) falls back to the VALIDATION
64
65
  * copy — fail-safe, never blank.
65
66
  */
66
67
  const BOOKING_ERROR_COPY: Record<Exclude<MeetingBookingErrorCode, 'SLOT_TAKEN'>, string> = {
@@ -304,6 +305,7 @@ export function HubSpotMeetingScheduler({
304
305
  const [bookingError, setBookingError] = useState<MeetingBookingErrorCode | null>(null);
305
306
 
306
307
  const { honeypotInputProps, getSignals, resetSignals } = useHumanitySignals();
308
+ const { toast } = useToast();
307
309
 
308
310
  // Reset the machine when the host switches links. Adjusted while rendering —
309
311
  // React's documented pattern for a prop-driven reset — so the swapped-in link
@@ -413,9 +415,17 @@ export function HubSpotMeetingScheduler({
413
415
  setStep('slot');
414
416
  resetSignals();
415
417
  void refetchAvailability();
418
+ } else {
419
+ // The error surface is the TOAST, full stop (host-mounted Toaster —
420
+ // every hub platform mounts it globally; embedders must too).
421
+ toast({
422
+ variant: 'error',
423
+ title: 'Booking failed',
424
+ description: BOOKING_ERROR_COPY[code] ?? BOOKING_ERROR_COPY.VALIDATION,
425
+ });
416
426
  }
417
427
  },
418
- [book, onBooked, refetchAvailability, resetSignals],
428
+ [book, onBooked, refetchAvailability, resetSignals, toast],
419
429
  );
420
430
 
421
431
  const escapeHatch = fallbackUrl ? (
@@ -525,14 +535,6 @@ export function HubSpotMeetingScheduler({
525
535
  }).format(new Date(selectedSlot))}{' '}
526
536
  · {formatDurationCompact(durationMs / 1000)}
527
537
  </p>
528
- {bookingError && bookingError !== 'SLOT_TAKEN' && (
529
- <Alert variant="error" className="flex flex-col items-start gap-[var(--spacing-system-xs)]">
530
- <AlertDescription>
531
- {BOOKING_ERROR_COPY[bookingError] ?? BOOKING_ERROR_COPY.VALIDATION}
532
- </AlertDescription>
533
- {escapeHatch}
534
- </Alert>
535
- )}
536
538
  <BookingForm
537
539
  availability={availability}
538
540
  meetingId={meetingId}