@mohasinac/appkit 4.41.14 → 4.41.15

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.
@@ -26,6 +26,8 @@ interface FAQPageContentProps {
26
26
  resultCount: (count: number) => string;
27
27
  inCategory: (categoryLabel: string) => string;
28
28
  loading: string;
29
+ emptyTitle?: string;
30
+ emptyDescription?: string;
29
31
  contactTitle: string;
30
32
  contactDescription: string;
31
33
  contactEmailUs: string;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Alert, Div, Heading, Input, SlottedListingView, Text } from "../../../ui";
3
+ import { Alert, Div, EmptyState, Heading, Input, SlottedListingView, Text } from "../../../ui";
4
4
  import { sortBy } from "../../../constants/sort";
5
5
  import { FAQCategorySidebar } from "./FAQCategorySidebar";
6
6
  import { FAQSortDropdown } from "./FAQSortDropdown";
@@ -69,7 +69,24 @@ export function FAQPageContent({ initialCategory = "all", categories, routeHelpe
69
69
  * Saying so costs nothing and makes the next index gap
70
70
  * self-reporting rather than a phantom empty state.
71
71
  */
72
- _jsx(Alert, { variant: "error", title: "Couldn't load questions", children: "Something went wrong fetching these FAQs. Try a different sort or reload the page." })) : renderAccordion ? (renderAccordion(faqs)) : (_jsx(FAQAccordion, { faqs: faqs })), renderPagination: () => renderPagination?.(total) ?? null, total: total, isLoading: isLoading }), faqs.length > 0 ? (_jsx(Div, { className: "mt-12", children: _jsx(ContactCTA, { email: contact.email, phone: contact.phone, contactHref: routeHelpers.contactHref, labels: {
72
+ _jsx(Alert, { variant: "error", title: "Couldn't load questions", children: "Something went wrong fetching these FAQs. Try a different sort or reload the page." })) : faqs.length === 0 ? (
73
+ /*
74
+ * 🛑 AN EXPLICIT EMPTY BRANCH — without it the page rendered a
75
+ * BARE WHITE AREA.
76
+ *
77
+ * The chain fell through to <FAQAccordion faqs={[]} />, which
78
+ * renders nothing at all. Measured on /faqs?q=zzzznope: the
79
+ * page showed "0 questions", the search box, a divider, and
80
+ * then blank space — no message anywhere in the DOM.
81
+ *
82
+ * A blank region is the worst possible answer here because it
83
+ * is indistinguishable from a page that failed to load, which
84
+ * is exactly the confusion the isError branch above exists to
85
+ * prevent. Three states, three distinct renderings: loading,
86
+ * failed, and genuinely nothing found.
87
+ */
88
+ _jsx(EmptyState, { title: labels.emptyTitle ?? "No questions found", description: labels.emptyDescription ??
89
+ "Try a different search term, or pick another category from the list." })) : renderAccordion ? (renderAccordion(faqs)) : (_jsx(FAQAccordion, { faqs: faqs })), renderPagination: () => renderPagination?.(total) ?? null, total: total, isLoading: isLoading }), faqs.length > 0 ? (_jsx(Div, { className: "mt-12", children: _jsx(ContactCTA, { email: contact.email, phone: contact.phone, contactHref: routeHelpers.contactHref, labels: {
73
90
  title: labels.contactTitle,
74
91
  description: labels.contactDescription,
75
92
  emailUs: labels.contactEmailUs,
@@ -55,8 +55,32 @@ export function AnnouncementBar({ message, link, className = "", onDismiss, over
55
55
  }, [message, userAlreadyDismissed]);
56
56
  if (dismissed)
57
57
  return null;
58
+ /*
59
+ * 🛑 THE OVERLAY IS md AND UP ONLY — IT PAINTED OVER THE HERO HEADING ON
60
+ * EVERY PHONE WIDTH.
61
+ *
62
+ * `absolute` reserves no space, which is the whole point of the overlay: the
63
+ * hero's own top padding is sized to sit a ONE-LINE banner over it. A real
64
+ * announcement wraps on a narrow screen, grows downward, and there is
65
+ * nothing to stop it.
66
+ *
67
+ * Measured on production against the live announcement, against the <h1>:
68
+ *
69
+ * 320px → 30px overlap 768px → 10px clear
70
+ * 390px → 10px overlap 1280px → 10px clear
71
+ * 430px → 10px overlap
72
+ *
73
+ * So it was every phone width and no tablet or desktop width — which is why
74
+ * it survived: the breakpoints people check it at are the ones where the
75
+ * message still fits on one line.
76
+ *
77
+ * Below `md` it is an ordinary in-flow bar that pushes the hero down, with a
78
+ * SOLID background (the translucent + blur treatment only reads as
79
+ * deliberate when there is artwork behind it). From `md` up, the designed
80
+ * overlay is unchanged.
81
+ */
58
82
  const positionCls = overlay
59
- ? "absolute inset-x-0 top-0 z-20 bg-primary-700/85 backdrop-blur-sm"
83
+ ? "relative md:absolute inset-x-0 top-0 z-20 bg-primary-700 md:bg-primary-700/85 md:backdrop-blur-sm"
60
84
  : "relative left-1/2 right-1/2 w-screen -translate-x-1/2 bg-primary-700";
61
85
  return (_jsx(Div, { className: `${positionCls} transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: _jsxs(Row, { textWeight: "medium", textSize: "sm", className: "relative text-left text-white", padding: "y-xs", align: "center", justify: "start", children: [link ? (_jsx(TextLink, { href: link, className: "text-white underline", children: message })) : (_jsx(Span, { children: message })), _jsx(IconButton, { type: "button", onClick: () => {
62
86
  saveLocalDismissal(message);