keystone-design-bootstrap 1.0.57 → 1.0.59

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.
Files changed (48) hide show
  1. package/dist/blog-post-vWzW8yFb.d.ts +50 -0
  2. package/dist/contexts/index.d.ts +13 -0
  3. package/dist/design_system/elements/index.d.ts +383 -0
  4. package/dist/design_system/logo/keystone-logo.d.ts +6 -0
  5. package/dist/design_system/sections/index.d.ts +232 -0
  6. package/dist/design_system/sections/index.js +25 -37
  7. package/dist/design_system/sections/index.js.map +1 -1
  8. package/dist/index.d.ts +69 -0
  9. package/dist/index.js +25 -37
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/component-registry.d.ts +13 -0
  12. package/dist/lib/hooks/index.d.ts +83 -0
  13. package/dist/lib/server-api.d.ts +44 -0
  14. package/dist/package-CB1tENyG.d.ts +148 -0
  15. package/dist/photos-CmBdWiuZ.d.ts +27 -0
  16. package/dist/themes/index.d.ts +16 -0
  17. package/dist/types/index.d.ts +312 -0
  18. package/dist/utils/cx.d.ts +15 -0
  19. package/dist/utils/gradient-placeholder.d.ts +8 -0
  20. package/dist/utils/is-react-component.d.ts +21 -0
  21. package/dist/utils/markdown-toc.d.ts +14 -0
  22. package/dist/utils/phone-helpers.d.ts +24 -0
  23. package/dist/utils/photo-helpers.d.ts +38 -0
  24. package/dist/website-photos-Cl1YqAno.d.ts +21 -0
  25. package/package.json +1 -1
  26. package/src/design_system/portal/PortalPage.tsx +107 -91
  27. package/src/design_system/portal/PortalTabTracker.tsx +24 -0
  28. package/src/design_system/sections/contact-section-form.aman.tsx +2 -2
  29. package/src/design_system/sections/contact-section-form.balance.tsx +2 -2
  30. package/src/design_system/sections/contact-section-form.barelux.tsx +2 -2
  31. package/src/design_system/sections/contact-section-form.tsx +2 -2
  32. package/src/design_system/sections/header-navigation.aman.tsx +1 -4
  33. package/src/design_system/sections/header-navigation.balance.tsx +1 -4
  34. package/src/design_system/sections/header-navigation.barelux.tsx +1 -4
  35. package/src/design_system/sections/header-navigation.tsx +1 -8
  36. package/src/index.ts +1 -1
  37. package/src/lib/cta-urls.ts +15 -38
  38. package/src/next/layouts/root-layout.tsx +6 -7
  39. package/src/next/routes/consumer-auth.ts +2 -4
  40. package/src/tracking/MetaPixelTracker.tsx +17 -12
  41. package/src/tracking/firePixelEvent.ts +26 -0
  42. package/src/tracking/index.ts +2 -6
  43. package/src/types/api/company-information.ts +2 -0
  44. package/src/tracking/BookingCtaTracker.tsx +0 -32
  45. package/src/tracking/ViewContentTracker.tsx +0 -21
  46. package/src/tracking/trackInitiateCheckout.ts +0 -16
  47. package/src/tracking/trackMetaLead.ts +0 -14
  48. package/src/tracking/trackViewContent.ts +0 -19
@@ -0,0 +1,69 @@
1
+ export { AboutHome, BlogCardFullWidthHorizontal, BlogCardFullWidthHorizontalAlt, BlogCardFullWidthHorizontalCompact, BlogCardFullWidthHorizontalMinimal, BlogCardFullWidthVertical, BlogCardFullWidthVerticalAlt, BlogCardFullWidthVerticalCompact, BlogCardFullWidthVerticalMinimal, BlogCardHorizontal, BlogCardHorizontalBadge, BlogCardHorizontalCompact, BlogCardHorizontalMinimal, BlogCardVertical, BlogCardVerticalBadge, BlogCardVerticalCompact, BlogCardVerticalMinimal, BlogGallery, BlogHome, BlogPostSection, BlogSection, ContactHome, ContactSection, EmailSignupSection, EmailSignupSectionProps, FAQGrid, FAQHero, FAQHome, FeatureTabHorizontal, FeatureTabVertical, FeatureTextCentered, FeatureTextFeaturedIconBox, FeatureTextFeaturedIconCard, FeatureTextFeaturedIconLeft, FeatureTextFeaturedIconTopCentered, FeatureTextFeaturedIconTopCenteredBrand, FeatureTextFeaturedIconTopLeft, FeatureTextFeaturedIconTopLeftBrand, FeatureTextIconCard, FeatureTextIconLeft, FeatureTextIconTopCentered, FeatureTextIconTopLeft, FeatureTextIntegrationIconBox, FeatureTextIntegrationIconLeft, FeatureTextIntegrationIconTopCentered, FeatureTextIntegrationIconTopLeft, FeatureTextLeft, FeatureTextLeftBrand, FooterHome, GenericHeaderComponent, GenericTextHero, HeaderNavigation, HeroHome, HomeHeroComponent, JobApplicationForm, JobDetailHero, JobDetailSection, JobGallery, LocationDetailHero, LocationDetailsSection, LocationGrid, PackageForMenu, PolicyDocumentSection, ServiceDetailContent, ServiceDetailHero, ServiceMenuSection, ServiceMenuSectionProps, ServicesGrid, ServicesHome, SocialMediaGrid, SocialMediaHero, StatisticsSection, TeamGrid, TestimonialsGrid, TestimonialsHero, TestimonialsHome, ValuesSection, getBlogPostData } from './design_system/sections/index.js';
2
+ export { Avatar, AvatarLabelGroup, Badge, BadgeGroup, BadgeWithDot, Breadcrumb, Button, ButtonGroup, Carousel, CarouselContext, CarouselSectionWrapper, ComboBox, FeaturedIcon, Form, FormContainer, GoogleMap, HintText, Input, InputBase, InputGroup, Label, MarkdownRenderer, Modal, ModalProps, NativeSelect, Pagination, PaginationPageDefault, PaginationPageMinimalCenter, PhotoWithFallback, PrivacyCheckbox, RatingBadge, RatingStars, RoundButton, Select, SelectItem, SocialIcon, StarIcon, Textarea, Tooltip, VerifiedTick, VideoModal, VideoPlayButton, Wreath, getSocialIcon, getStarProgress, useCarousel } from './design_system/elements/index.js';
3
+ import { C as CompanyInformation } from './package-CB1tENyG.js';
4
+ export { ThemeProvider, useTheme } from './contexts/index.js';
5
+ import React__default from 'react';
6
+ export { Theme } from './themes/index.js';
7
+ import './blog-post-vWzW8yFb.js';
8
+ import './photos-CmBdWiuZ.js';
9
+ import './website-photos-Cl1YqAno.js';
10
+ import 'react-aria-components';
11
+ import 'embla-carousel-react';
12
+
13
+ interface ContactFormResult {
14
+ success: boolean;
15
+ message?: string;
16
+ error?: string;
17
+ /** Present on lead form success; use for Meta Pixel dedup: fbq('track', 'Lead', {}, { eventID: eventId }) */
18
+ eventId?: string;
19
+ }
20
+ declare function submitContactFormAction(formData: FormData): Promise<ContactFormResult>;
21
+ declare function submitLeadFormAction(formData: FormData): Promise<ContactFormResult>;
22
+
23
+ /**
24
+ * Resolves the primary and secondary CTA hrefs used across the site.
25
+ *
26
+ * Resolution order for primaryHref:
27
+ * 1. portal_url — set by backend when account has consumer portal enabled
28
+ * 2. external_management_url — booking platform URL from the API
29
+ * 3. /contact — final fallback
30
+ *
31
+ * No per-site configuration needed. Enable the portal in the admin console and
32
+ * every CTA across the site automatically routes to the portal.
33
+ */
34
+
35
+ /** True when the href is absolute (external); use for target="_blank" and rel="noopener noreferrer". */
36
+ declare function isExternalCtaUrl(href: string): boolean;
37
+ interface ResolvedCtaUrls {
38
+ primaryHref: string;
39
+ secondaryHref: string;
40
+ hasSecondary: boolean;
41
+ }
42
+ declare function resolveCtaUrls(companyInformation?: CompanyInformation | null): ResolvedCtaUrls;
43
+
44
+ interface TeamMember {
45
+ id: number;
46
+ name: string;
47
+ position?: string;
48
+ photo_url?: string;
49
+ }
50
+ interface ChatWidgetProps {
51
+ position?: 'bottom-right' | 'bottom-left';
52
+ primaryColor?: string;
53
+ /**
54
+ * Anonymous session identifier. Used when the visitor is not authenticated.
55
+ * Mutually exclusive with `contactId` — if both are provided, `contactId` wins.
56
+ */
57
+ sessionId?: string;
58
+ /**
59
+ * Authenticated contact ID. When provided, messages are loaded and sent using
60
+ * the contact-driven flow instead of the anonymous session flow.
61
+ * The `/api/chat` route must support `contact_id` (see `createChatRouteHandlers`).
62
+ */
63
+ contactId?: number;
64
+ displayName?: string;
65
+ teamMembers?: TeamMember[];
66
+ }
67
+ declare function ChatWidget({ position, primaryColor, sessionId: providedSessionId, contactId, displayName: providedDisplayName, teamMembers }: ChatWidgetProps): React__default.JSX.Element;
68
+
69
+ export { ChatWidget, type ResolvedCtaUrls, isExternalCtaUrl, resolveCtaUrls, submitContactFormAction, submitLeadFormAction };
package/dist/index.js CHANGED
@@ -6197,16 +6197,19 @@ function DynamicFormFields({ form, jobSlug, privacyPolicyUrl, termsOfServiceUrl
6197
6197
  }), jobSlug ? /* @__PURE__ */ React18.createElement("input", { type: "hidden", name: "jobSlug", value: jobSlug }) : null, showPrivacyCheckbox && /* @__PURE__ */ React18.createElement(PrivacyCheckbox2, null));
6198
6198
  }
6199
6199
 
6200
- // src/tracking/trackMetaLead.ts
6201
- function trackMetaLead(eventId) {
6202
- if (typeof window === "undefined" || !eventId) return;
6200
+ // src/tracking/firePixelEvent.ts
6201
+ function firePixelEvent(event, params) {
6202
+ if (typeof window === "undefined") return;
6203
6203
  const fbq = window.fbq;
6204
6204
  if (!fbq) {
6205
- console.debug("[MetaPixel] Lead skipped \u2014 fbq not loaded", { eventId });
6205
+ console.debug("[MetaPixel] skipped \u2014 fbq not loaded", { event });
6206
6206
  return;
6207
6207
  }
6208
- console.debug("[MetaPixel] Lead", { eventId });
6209
- fbq("track", "Lead", {}, { eventID: eventId });
6208
+ const normalized = {};
6209
+ if (params == null ? void 0 : params.contentName) normalized.content_name = params.contentName;
6210
+ if (params == null ? void 0 : params.contentCategory) normalized.content_category = params.contentCategory;
6211
+ console.debug("[MetaPixel]", event, normalized);
6212
+ fbq("track", event, Object.keys(normalized).length > 0 ? normalized : void 0);
6210
6213
  }
6211
6214
 
6212
6215
  // src/next/contexts/form-definitions.tsx
@@ -6263,7 +6266,7 @@ var ContactSectionForm = ({
6263
6266
  setStatusMessage(result.message || successMessage);
6264
6267
  (_a = formRef.current) == null ? void 0 : _a.reset();
6265
6268
  onSuccess == null ? void 0 : onSuccess();
6266
- trackMetaLead(result.eventId);
6269
+ firePixelEvent("Lead");
6267
6270
  setTimeout(() => setSubmitStatus("idle"), 5e3);
6268
6271
  } else {
6269
6272
  setSubmitStatus("error");
@@ -6480,17 +6483,14 @@ var CONTACT_PATH = "/contact";
6480
6483
  function isExternalCtaUrl(href) {
6481
6484
  return href.startsWith("http://") || href.startsWith("https://");
6482
6485
  }
6483
- function resolveCtaUrls(companyInformation, _ctaButton, overrides) {
6484
- var _a;
6485
- const externalUrl = ((_a = companyInformation == null ? void 0 : companyInformation.external_management_url) == null ? void 0 : _a.trim()) || null;
6486
- const hasSecondary = !!externalUrl;
6487
- const primaryHref = (overrides == null ? void 0 : overrides.primaryHrefOverride) !== void 0 && overrides.primaryHrefOverride !== null ? overrides.primaryHrefOverride : externalUrl || CONTACT_PATH;
6488
- const secondaryHref = (overrides == null ? void 0 : overrides.secondaryHrefOverride) !== void 0 && overrides.secondaryHrefOverride !== null ? overrides.secondaryHrefOverride : CONTACT_PATH;
6489
- return {
6490
- primaryHref,
6491
- secondaryHref,
6492
- hasSecondary
6493
- };
6486
+ function resolveCtaUrls(companyInformation) {
6487
+ var _a, _b, _c;
6488
+ const portalUrl = ((_a = companyInformation == null ? void 0 : companyInformation.portal_url) == null ? void 0 : _a.trim()) || null;
6489
+ const externalUrl = ((_b = companyInformation == null ? void 0 : companyInformation.external_management_url) == null ? void 0 : _b.trim()) || null;
6490
+ const primaryHref = (_c = portalUrl != null ? portalUrl : externalUrl) != null ? _c : CONTACT_PATH;
6491
+ const secondaryHref = CONTACT_PATH;
6492
+ const hasSecondary = primaryHref !== CONTACT_PATH;
6493
+ return { primaryHref, secondaryHref, hasSecondary };
6494
6494
  }
6495
6495
 
6496
6496
  // src/design_system/sections/header-navigation.tsx
@@ -6539,10 +6539,7 @@ function HeaderNavigation({
6539
6539
  const logoImage = logoImageOverride || getLogoUrl(websitePhotos) || ((_b = props == null ? void 0 : props.logo) == null ? void 0 : _b.image);
6540
6540
  const logoText = logoTextOverride || (companyInformation == null ? void 0 : companyInformation.company_name) || ((_c = props == null ? void 0 : props.logo) == null ? void 0 : _c.text) || "";
6541
6541
  const cta_button = props == null ? void 0 : props.cta_button;
6542
- const ctaUrls = resolveCtaUrls(companyInformation, cta_button, {
6543
- primaryHrefOverride: props == null ? void 0 : props.primaryHrefOverride,
6544
- secondaryHrefOverride: props == null ? void 0 : props.secondaryHrefOverride
6545
- });
6542
+ const ctaUrls = resolveCtaUrls(companyInformation);
6546
6543
  const logo = {
6547
6544
  text: logoText || "",
6548
6545
  href: ((_d = props == null ? void 0 : props.logo) == null ? void 0 : _d.href) || "/",
@@ -8564,10 +8561,7 @@ function HeaderNavigation2({
8564
8561
  const logoUrl = logoImageOverride || getLogoUrl(websitePhotos) || ((_a = props == null ? void 0 : props.logo) == null ? void 0 : _a.image);
8565
8562
  const companyName = logoTextOverride || (companyInformation == null ? void 0 : companyInformation.company_name) || ((_b = props == null ? void 0 : props.logo) == null ? void 0 : _b.text) || "";
8566
8563
  const navigation = navigationOverride || ((_c = config == null ? void 0 : config.navigation) == null ? void 0 : _c.header) || [];
8567
- const ctaUrls = resolveCtaUrls(companyInformation, props == null ? void 0 : props.cta_button, {
8568
- primaryHrefOverride: props == null ? void 0 : props.primaryHrefOverride,
8569
- secondaryHrefOverride: props == null ? void 0 : props.secondaryHrefOverride
8570
- });
8564
+ const ctaUrls = resolveCtaUrls(companyInformation);
8571
8565
  const cancelCloseTimeout = useCallback5(() => {
8572
8566
  if (closeTimeoutRef.current) {
8573
8567
  clearTimeout(closeTimeoutRef.current);
@@ -9033,7 +9027,7 @@ var ContactSectionForm2 = ({
9033
9027
  setStatusMessage(result.message || successMessage);
9034
9028
  (_a = formRef.current) == null ? void 0 : _a.reset();
9035
9029
  onSuccess == null ? void 0 : onSuccess();
9036
- trackMetaLead(result.eventId);
9030
+ firePixelEvent("Lead");
9037
9031
  setTimeout(() => setSubmitStatus("idle"), 5e3);
9038
9032
  } else {
9039
9033
  setSubmitStatus("error");
@@ -17648,10 +17642,7 @@ function HeaderNavigation3({
17648
17642
  const logoUrl = logoImageOverride || getLogoUrl(websitePhotos) || ((_a = props == null ? void 0 : props.logo) == null ? void 0 : _a.image);
17649
17643
  const companyName = logoTextOverride || (companyInformation == null ? void 0 : companyInformation.company_name) || ((_b = props == null ? void 0 : props.logo) == null ? void 0 : _b.text) || "";
17650
17644
  const navigation = navigationOverride || ((_c = config == null ? void 0 : config.navigation) == null ? void 0 : _c.header) || [];
17651
- const ctaUrls = resolveCtaUrls(companyInformation, props == null ? void 0 : props.cta_button, {
17652
- primaryHrefOverride: props == null ? void 0 : props.primaryHrefOverride,
17653
- secondaryHrefOverride: props == null ? void 0 : props.secondaryHrefOverride
17654
- });
17645
+ const ctaUrls = resolveCtaUrls(companyInformation);
17655
17646
  const cancelCloseTimeout = useCallback8(() => {
17656
17647
  if (closeTimeoutRef.current) {
17657
17648
  clearTimeout(closeTimeoutRef.current);
@@ -18237,7 +18228,7 @@ var ContactSectionForm3 = ({
18237
18228
  setStatusMessage(result.message || successMessage);
18238
18229
  (_a = formRef.current) == null ? void 0 : _a.reset();
18239
18230
  onSuccess == null ? void 0 : onSuccess();
18240
- trackMetaLead(result.eventId);
18231
+ firePixelEvent("Lead");
18241
18232
  setTimeout(() => setSubmitStatus("idle"), 5e3);
18242
18233
  } else {
18243
18234
  setSubmitStatus("error");
@@ -18440,10 +18431,7 @@ function HeaderNavigation4({
18440
18431
  const logoUrl = logoImageOverride || getLogoUrl(websitePhotos) || ((_a = props == null ? void 0 : props.logo) == null ? void 0 : _a.image);
18441
18432
  const companyName = logoTextOverride || (companyInformation == null ? void 0 : companyInformation.company_name) || ((_b = props == null ? void 0 : props.logo) == null ? void 0 : _b.text) || "";
18442
18433
  const navigation = navigationOverride || ((_c = config == null ? void 0 : config.navigation) == null ? void 0 : _c.header) || [];
18443
- const ctaUrls = resolveCtaUrls(companyInformation, props == null ? void 0 : props.cta_button, {
18444
- primaryHrefOverride: props == null ? void 0 : props.primaryHrefOverride,
18445
- secondaryHrefOverride: props == null ? void 0 : props.secondaryHrefOverride
18446
- });
18434
+ const ctaUrls = resolveCtaUrls(companyInformation);
18447
18435
  const cancelCloseTimeout = useCallback9(() => {
18448
18436
  if (closeTimeoutRef.current) {
18449
18437
  clearTimeout(closeTimeoutRef.current);
@@ -18733,7 +18721,7 @@ var ContactSectionForm4 = ({
18733
18721
  setStatusMessage(result.message || successMessage);
18734
18722
  (_a = formRef.current) == null ? void 0 : _a.reset();
18735
18723
  onSuccess == null ? void 0 : onSuccess();
18736
- trackMetaLead(result.eventId);
18724
+ firePixelEvent("Lead");
18737
18725
  setTimeout(() => setSubmitStatus("idle"), 5e3);
18738
18726
  } else {
18739
18727
  setSubmitStatus("error");