@flamingo-stack/openframe-frontend-core 0.0.523 → 0.0.524-1675.4405.1
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/dist/{chunk-CE4CBCKX.cjs → chunk-25JYFZ6D.cjs} +7 -7
- package/dist/{chunk-CE4CBCKX.cjs.map → chunk-25JYFZ6D.cjs.map} +1 -1
- package/dist/{chunk-3OFRFRBW.cjs → chunk-2JMWI7RE.cjs} +26 -26
- package/dist/{chunk-3OFRFRBW.cjs.map → chunk-2JMWI7RE.cjs.map} +1 -1
- package/dist/{chunk-MYQAF43S.js → chunk-2WNONXFZ.js} +4 -4
- package/dist/{chunk-6MW6ELZQ.cjs → chunk-56NIEVZ4.cjs} +37 -37
- package/dist/{chunk-6MW6ELZQ.cjs.map → chunk-56NIEVZ4.cjs.map} +1 -1
- package/dist/{chunk-M7FGOI4V.cjs → chunk-6CTX5BLD.cjs} +31 -31
- package/dist/{chunk-M7FGOI4V.cjs.map → chunk-6CTX5BLD.cjs.map} +1 -1
- package/dist/{chunk-2ALPHSGU.js → chunk-6S5E5RLR.js} +4 -4
- package/dist/{chunk-TPIF252F.js → chunk-CELZDZP2.js} +2 -2
- package/dist/{chunk-C7T363HO.js → chunk-DFZTO3NG.js} +2 -2
- package/dist/{chunk-OPPGJ4PY.cjs → chunk-DTETRKV6.cjs} +87 -87
- package/dist/{chunk-OPPGJ4PY.cjs.map → chunk-DTETRKV6.cjs.map} +1 -1
- package/dist/{chunk-HM53VV7K.cjs → chunk-H635T5R2.cjs} +1316 -1079
- package/dist/chunk-H635T5R2.cjs.map +1 -0
- package/dist/{chunk-MVYTOP3B.js → chunk-HI7LXHWR.js} +5 -5
- package/dist/{chunk-KSZPPVXT.cjs → chunk-HMYZM3SS.cjs} +11 -11
- package/dist/{chunk-KSZPPVXT.cjs.map → chunk-HMYZM3SS.cjs.map} +1 -1
- package/dist/{chunk-YTLLRLMU.cjs → chunk-I5RARV6I.cjs} +14 -14
- package/dist/{chunk-YTLLRLMU.cjs.map → chunk-I5RARV6I.cjs.map} +1 -1
- package/dist/{chunk-TH4BQCOD.cjs → chunk-JFGAVBWJ.cjs} +26 -26
- package/dist/{chunk-TH4BQCOD.cjs.map → chunk-JFGAVBWJ.cjs.map} +1 -1
- package/dist/{chunk-E2W2XMX2.js → chunk-JHEUPQAF.js} +2 -2
- package/dist/{chunk-JBCNOJMX.cjs → chunk-LEN53CEM.cjs} +3 -3
- package/dist/{chunk-JBCNOJMX.cjs.map → chunk-LEN53CEM.cjs.map} +1 -1
- package/dist/{chunk-QCWVGCT3.js → chunk-MAAN76UX.js} +6 -6
- package/dist/{chunk-HYVYAWUO.js → chunk-N3XPBO6W.js} +2 -2
- package/dist/{chunk-QRYJYZTW.cjs → chunk-NFTLCOJF.cjs} +61 -61
- package/dist/{chunk-QRYJYZTW.cjs.map → chunk-NFTLCOJF.cjs.map} +1 -1
- package/dist/{chunk-4DJL34HL.js → chunk-Q3DK4P3F.js} +2 -2
- package/dist/{chunk-ARCH6RK6.cjs → chunk-RLAS623H.cjs} +4 -4
- package/dist/{chunk-ARCH6RK6.cjs.map → chunk-RLAS623H.cjs.map} +1 -1
- package/dist/{chunk-CBD3IHPF.js → chunk-RNAXQVBK.js} +2 -2
- package/dist/{chunk-2MPS2QY5.cjs → chunk-STJB3XH6.cjs} +5 -5
- package/dist/{chunk-2MPS2QY5.cjs.map → chunk-STJB3XH6.cjs.map} +1 -1
- package/dist/{chunk-LEMU4JMX.js → chunk-WR2XVJ6K.js} +2 -2
- package/dist/{chunk-43MPUCDL.js → chunk-XMROOTCF.js} +2 -2
- package/dist/{chunk-INTFGXHO.js → chunk-Y2BLPCJZ.js} +4979 -4742
- package/dist/chunk-Y2BLPCJZ.js.map +1 -0
- package/dist/{chunk-ZYBBV6CK.js → chunk-Y5MDIJHH.js} +2 -2
- package/dist/{chunk-S4BAM7EC.cjs → chunk-YLWWP46N.cjs} +9 -9
- package/dist/{chunk-S4BAM7EC.cjs.map → chunk-YLWWP46N.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +144 -132
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +23 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/dropdown-button.d.ts +42 -11
- package/dist/components/ui/dropdown-button.d.ts.map +1 -1
- package/dist/components/ui/field.d.ts +38 -0
- package/dist/components/ui/field.d.ts.map +1 -0
- package/dist/components/ui/index.cjs +14 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +4 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +13 -1
- package/dist/components/ui/info-hint.d.ts +23 -0
- package/dist/components/ui/info-hint.d.ts.map +1 -0
- package/dist/components/ui/json-detail-list.d.ts +9 -0
- package/dist/components/ui/json-detail-list.d.ts.map +1 -0
- package/dist/components/ui/modal-guarded-close.d.ts +50 -0
- package/dist/components/ui/modal-guarded-close.d.ts.map +1 -0
- package/dist/components/ui/modal-v2.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +19 -5
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/index.cjs +14 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -1
- package/package.json +3 -2
- package/src/components/ui/dropdown-button.tsx +109 -46
- package/src/components/ui/field.tsx +74 -0
- package/src/components/ui/index.ts +4 -0
- package/src/components/ui/info-hint.tsx +74 -0
- package/src/components/ui/json-detail-list.tsx +112 -0
- package/src/components/ui/modal-guarded-close.tsx +133 -0
- package/src/components/ui/modal-v2.tsx +12 -5
- package/src/components/ui/tabs.tsx +75 -20
- package/src/stories/DropdownButton.stories.tsx +109 -0
- package/src/stories/Field.stories.tsx +70 -0
- package/src/stories/InfoHint.stories.tsx +65 -0
- package/src/stories/JsonDetailList.stories.tsx +73 -0
- package/src/stories/ModalGuardedClose.stories.tsx +82 -0
- package/src/stories/Tabs.stories.tsx +101 -0
- package/dist/chunk-HM53VV7K.cjs.map +0 -1
- package/dist/chunk-INTFGXHO.js.map +0 -1
- /package/dist/{chunk-MYQAF43S.js.map → chunk-2WNONXFZ.js.map} +0 -0
- /package/dist/{chunk-2ALPHSGU.js.map → chunk-6S5E5RLR.js.map} +0 -0
- /package/dist/{chunk-TPIF252F.js.map → chunk-CELZDZP2.js.map} +0 -0
- /package/dist/{chunk-C7T363HO.js.map → chunk-DFZTO3NG.js.map} +0 -0
- /package/dist/{chunk-MVYTOP3B.js.map → chunk-HI7LXHWR.js.map} +0 -0
- /package/dist/{chunk-E2W2XMX2.js.map → chunk-JHEUPQAF.js.map} +0 -0
- /package/dist/{chunk-QCWVGCT3.js.map → chunk-MAAN76UX.js.map} +0 -0
- /package/dist/{chunk-HYVYAWUO.js.map → chunk-N3XPBO6W.js.map} +0 -0
- /package/dist/{chunk-4DJL34HL.js.map → chunk-Q3DK4P3F.js.map} +0 -0
- /package/dist/{chunk-CBD3IHPF.js.map → chunk-RNAXQVBK.js.map} +0 -0
- /package/dist/{chunk-LEMU4JMX.js.map → chunk-WR2XVJ6K.js.map} +0 -0
- /package/dist/{chunk-43MPUCDL.js.map → chunk-XMROOTCF.js.map} +0 -0
- /package/dist/{chunk-ZYBBV6CK.js.map → chunk-Y5MDIJHH.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkH635T5R2cjs = require('./chunk-H635T5R2.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -52,7 +52,7 @@ function UnifiedPagination({
|
|
|
52
52
|
};
|
|
53
53
|
if (totalPages <= 1) return null;
|
|
54
54
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
55
|
-
|
|
55
|
+
_chunkH635T5R2cjs.Pagination,
|
|
56
56
|
{
|
|
57
57
|
currentPage,
|
|
58
58
|
totalPages,
|
|
@@ -65,7 +65,7 @@ var init_unified_pagination = _chunkVRHGVLSLcjs.__esm.call(void 0, {
|
|
|
65
65
|
"use strict";
|
|
66
66
|
"use client";
|
|
67
67
|
_chunkSSJNN5BScjs.init_next_navigation.call(void 0, );
|
|
68
|
-
|
|
68
|
+
_chunkH635T5R2cjs.init_pagination.call(void 0, );
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
|
|
@@ -210,4 +210,4 @@ function EmptyState({
|
|
|
210
210
|
|
|
211
211
|
|
|
212
212
|
exports.EmptyState = EmptyState; exports.UnifiedPagination = UnifiedPagination; exports.unified_pagination_exports = unified_pagination_exports; exports.init_unified_pagination = init_unified_pagination;
|
|
213
|
-
//# sourceMappingURL=chunk-
|
|
213
|
+
//# sourceMappingURL=chunk-RLAS623H.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-ARCH6RK6.cjs","../src/components/unified-pagination.tsx","../src/components/empty-state.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-ARCH6RK6.cjs","sourcesContent":[null,"\"use client\"\n\nimport { useRouter, useSearchParams, usePathname } from \"../embed-shims/next-navigation\"\nimport { Pagination } from \"./pagination\"\n\ninterface UnifiedPaginationProps {\n currentPage: number\n totalPages: number\n onPageChange?: (page: number) => void\n className?: string\n}\n\nexport function UnifiedPagination({ \n currentPage, \n totalPages, \n onPageChange,\n className = \"mt-8 flex justify-center w-full\"\n}: UnifiedPaginationProps) {\n const router = useRouter()\n const searchParams = useSearchParams()\n const pathname = usePathname()\n\n const handlePageChange = (page: number) => {\n // Preserve current scroll position\n const currentScrollY = window.scrollY\n \n // Call the callback to update local state (prevents reload)\n if (onPageChange) {\n onPageChange(page)\n }\n \n // Update URL for bookmarking without navigation\n const params = new URLSearchParams(searchParams.toString())\n params.set(\"page\", page.toString())\n \n // Update URL without navigation (for bookmarking support)\n const newUrl = `${pathname}?${params.toString()}`\n window.history.replaceState(null, '', newUrl)\n \n // Restore scroll position after a brief delay to allow content to render\n setTimeout(() => {\n window.scrollTo({\n top: currentScrollY,\n behavior: 'instant' // Instant to prevent any scroll animation\n })\n }, 0)\n }\n\n // Don't render pagination if there's only one page\n if (totalPages <= 1) return null\n\n return (\n <div className={className}>\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={handlePageChange}\n />\n </div>\n )\n} ","\"use client\";\n\nimport { Search, FileText, Package } from \"lucide-react\"\nimport { Button } from \"./ui/button\"\nimport { useRouter } from \"../embed-shims/next-navigation\"\n\nexport interface EmptyStateProps {\n type: 'vendors' | 'posts' | 'search' | 'generic'\n title?: string\n description?: string\n showBackButton?: boolean\n onGoBack?: () => void\n backButtonText?: string\n // New CTA properties\n showCTA?: boolean\n ctaText?: string\n onCtaClick?: () => void\n /**\n * Link-CTA mode: render the CTA as a navigation link (`href` — plain or\n * `mailto:`). Wins over `onCtaClick`, and SHORT-CIRCUITS the smart-CTA\n * path-sniffing below (which reads `window.location.pathname` — an\n * SSR/client divergence server-rendered pages must never enter).\n */\n ctaHref?: string\n ctaVariant?: 'primary' | 'secondary'\n}\n\nexport function EmptyState({\n type,\n title,\n description,\n showBackButton = false,\n onGoBack,\n backButtonText = \"Go Back\",\n showCTA = true,\n ctaText,\n onCtaClick,\n ctaHref,\n ctaVariant = 'primary'\n}: EmptyStateProps) {\n const router = useRouter()\n\n // Default content based on type\n const getDefaultContent = () => {\n switch (type) {\n case 'vendors':\n return {\n icon: <Package className=\"w-full h-full\" />,\n title: \"No vendors found\",\n description: \"We couldn't find any vendors matching your criteria. Try adjusting your filters or search terms.\"\n }\n case 'posts':\n return {\n icon: <FileText className=\"w-full h-full\" />,\n title: \"No articles found\",\n description: \"We couldn't find any articles matching your criteria. Try different categories, tags, or search terms.\"\n }\n case 'search':\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"No results found\",\n description: \"Your search didn't return any results. Try different keywords or browse our categories.\"\n }\n default:\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"Nothing found\",\n description: \"We couldn't find what you're looking for. Try adjusting your search or filters.\"\n }\n }\n }\n\n // Smart CTA logic based on context\n const getSmartCTA = () => {\n // If custom CTA is provided, use it\n if (ctaText && onCtaClick) {\n return {\n text: ctaText,\n action: onCtaClick\n }\n }\n\n // Check if we're on the client side\n const isClient = typeof window !== 'undefined'\n const currentPath = isClient ? window.location.pathname : ''\n\n // Surgical filter reset (promoted from the hub's diverged clone during\n // the EmptyState convergence): delete ONLY the filter params the surface\n // owns — nuking the whole query string threw away unrelated state — and\n // use `replace` with `scroll: false` so resetting filters neither adds a\n // history entry nor jumps the page.\n const resetParams = (paramsToDelete: string[]) => {\n if (!isClient) return\n const params = new URLSearchParams(window.location.search)\n for (const p of paramsToDelete) params.delete(p)\n const queryString = params.toString()\n // Keep the hash — a filter reset must not clear an unrelated\n // deep-link anchor (e.g. #delivery-123).\n const hash = window.location.hash\n router.replace(\n `${window.location.pathname}${queryString ? `?${queryString}` : ''}${hash}`,\n { scroll: false },\n )\n }\n\n // Smart defaults based on type and context\n switch (type) {\n case 'search':\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page'])\n }\n case 'posts':\n // Blog-style listing pages (blog, case studies) reset their filters\n if (currentPath.includes('/blog') || currentPath.includes('/case-studies')) {\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page', 'category', 'tags'])\n }\n } else if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n return {\n text: \"View All Posts\",\n action: () => router.push('/blog')\n }\n case 'vendors':\n // If we're in profile or other pages, direct to main content\n if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n } else if (currentPath.includes('/vendors') || currentPath.includes('/margin-increase/compare')) {\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page', 'category', 'subcategory'])\n }\n }\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n default:\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n }\n\n const defaultContent = getDefaultContent()\n const displayTitle = title || defaultContent.title\n const displayDescription = description || defaultContent.description\n // ctaHref short-circuits BEFORE getSmartCTA(): the smart defaults read\n // window.location.pathname (SSR-empty, client-real), so a server-rendered\n // page with a link CTA must never enter that branch. Existing callers\n // without ctaHref keep today's smart-default behavior unchanged.\n const smartCTA = ctaHref ? null : getSmartCTA()\n const ctaClassName = ctaVariant === 'primary'\n ? \"w-full bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover transition-all duration-150 font-body font-medium\"\n : \"w-full bg-transparent border border-ods-border text-ods-text-primary hover:border-ods-accent hover:text-ods-accent transition-all duration-150 font-body font-medium\"\n\n return (\n <div className=\"flex flex-col items-center justify-center py-6 md:py-16 px-6 text-center\">\n {/* Icon */}\n <div className=\"mb-3 md:mb-6 flex items-center justify-center\">\n <div className=\"rounded-full bg-ods-card p-3 md:p-6 border border-ods-border\">\n <div className=\"w-8 h-8 md:w-16 md:h-16 text-ods-text-secondary flex items-center justify-center\">\n {defaultContent.icon}\n </div>\n </div>\n </div>\n\n {/* Title */}\n <h2 className=\"mb-2 md:mb-3 text-h3 text-ods-text-primary\">\n {displayTitle}\n </h2>\n\n {/* Description */}\n <p className=\"mb-4 md:mb-8 max-w-md text-h6 text-ods-text-secondary\">\n {displayDescription}\n </p>\n\n {/* Link CTA (ctaHref) — SSR-safe, no path sniffing */}\n {showCTA && ctaHref && (\n <div className=\"w-full max-w-xs mb-3\">\n <Button href={ctaHref} className={ctaClassName}>\n {ctaText || 'Contact us'}\n </Button>\n </div>\n )}\n\n {/* Smart CTA Button */}\n {showCTA && !ctaHref && smartCTA && (\n <div className=\"w-full max-w-xs mb-3\">\n <Button onClick={smartCTA.action} className={ctaClassName}>\n {smartCTA.text}\n </Button>\n </div>\n )}\n\n {/* Optional Back Button */}\n {showBackButton && onGoBack && (\n <div className=\"w-full max-w-xs\">\n <Button\n onClick={onGoBack}\n variant=\"outline\"\n className=\"w-full transition-all duration-150 font-body font-medium\"\n >\n {backButtonText}\n </Button>\n </div>\n )}\n </div>\n )\n} "]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-RLAS623H.cjs","../src/components/unified-pagination.tsx","../src/components/empty-state.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-RLAS623H.cjs","sourcesContent":[null,"\"use client\"\n\nimport { useRouter, useSearchParams, usePathname } from \"../embed-shims/next-navigation\"\nimport { Pagination } from \"./pagination\"\n\ninterface UnifiedPaginationProps {\n currentPage: number\n totalPages: number\n onPageChange?: (page: number) => void\n className?: string\n}\n\nexport function UnifiedPagination({ \n currentPage, \n totalPages, \n onPageChange,\n className = \"mt-8 flex justify-center w-full\"\n}: UnifiedPaginationProps) {\n const router = useRouter()\n const searchParams = useSearchParams()\n const pathname = usePathname()\n\n const handlePageChange = (page: number) => {\n // Preserve current scroll position\n const currentScrollY = window.scrollY\n \n // Call the callback to update local state (prevents reload)\n if (onPageChange) {\n onPageChange(page)\n }\n \n // Update URL for bookmarking without navigation\n const params = new URLSearchParams(searchParams.toString())\n params.set(\"page\", page.toString())\n \n // Update URL without navigation (for bookmarking support)\n const newUrl = `${pathname}?${params.toString()}`\n window.history.replaceState(null, '', newUrl)\n \n // Restore scroll position after a brief delay to allow content to render\n setTimeout(() => {\n window.scrollTo({\n top: currentScrollY,\n behavior: 'instant' // Instant to prevent any scroll animation\n })\n }, 0)\n }\n\n // Don't render pagination if there's only one page\n if (totalPages <= 1) return null\n\n return (\n <div className={className}>\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={handlePageChange}\n />\n </div>\n )\n} ","\"use client\";\n\nimport { Search, FileText, Package } from \"lucide-react\"\nimport { Button } from \"./ui/button\"\nimport { useRouter } from \"../embed-shims/next-navigation\"\n\nexport interface EmptyStateProps {\n type: 'vendors' | 'posts' | 'search' | 'generic'\n title?: string\n description?: string\n showBackButton?: boolean\n onGoBack?: () => void\n backButtonText?: string\n // New CTA properties\n showCTA?: boolean\n ctaText?: string\n onCtaClick?: () => void\n /**\n * Link-CTA mode: render the CTA as a navigation link (`href` — plain or\n * `mailto:`). Wins over `onCtaClick`, and SHORT-CIRCUITS the smart-CTA\n * path-sniffing below (which reads `window.location.pathname` — an\n * SSR/client divergence server-rendered pages must never enter).\n */\n ctaHref?: string\n ctaVariant?: 'primary' | 'secondary'\n}\n\nexport function EmptyState({\n type,\n title,\n description,\n showBackButton = false,\n onGoBack,\n backButtonText = \"Go Back\",\n showCTA = true,\n ctaText,\n onCtaClick,\n ctaHref,\n ctaVariant = 'primary'\n}: EmptyStateProps) {\n const router = useRouter()\n\n // Default content based on type\n const getDefaultContent = () => {\n switch (type) {\n case 'vendors':\n return {\n icon: <Package className=\"w-full h-full\" />,\n title: \"No vendors found\",\n description: \"We couldn't find any vendors matching your criteria. Try adjusting your filters or search terms.\"\n }\n case 'posts':\n return {\n icon: <FileText className=\"w-full h-full\" />,\n title: \"No articles found\",\n description: \"We couldn't find any articles matching your criteria. Try different categories, tags, or search terms.\"\n }\n case 'search':\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"No results found\",\n description: \"Your search didn't return any results. Try different keywords or browse our categories.\"\n }\n default:\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"Nothing found\",\n description: \"We couldn't find what you're looking for. Try adjusting your search or filters.\"\n }\n }\n }\n\n // Smart CTA logic based on context\n const getSmartCTA = () => {\n // If custom CTA is provided, use it\n if (ctaText && onCtaClick) {\n return {\n text: ctaText,\n action: onCtaClick\n }\n }\n\n // Check if we're on the client side\n const isClient = typeof window !== 'undefined'\n const currentPath = isClient ? window.location.pathname : ''\n\n // Surgical filter reset (promoted from the hub's diverged clone during\n // the EmptyState convergence): delete ONLY the filter params the surface\n // owns — nuking the whole query string threw away unrelated state — and\n // use `replace` with `scroll: false` so resetting filters neither adds a\n // history entry nor jumps the page.\n const resetParams = (paramsToDelete: string[]) => {\n if (!isClient) return\n const params = new URLSearchParams(window.location.search)\n for (const p of paramsToDelete) params.delete(p)\n const queryString = params.toString()\n // Keep the hash — a filter reset must not clear an unrelated\n // deep-link anchor (e.g. #delivery-123).\n const hash = window.location.hash\n router.replace(\n `${window.location.pathname}${queryString ? `?${queryString}` : ''}${hash}`,\n { scroll: false },\n )\n }\n\n // Smart defaults based on type and context\n switch (type) {\n case 'search':\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page'])\n }\n case 'posts':\n // Blog-style listing pages (blog, case studies) reset their filters\n if (currentPath.includes('/blog') || currentPath.includes('/case-studies')) {\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page', 'category', 'tags'])\n }\n } else if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n return {\n text: \"View All Posts\",\n action: () => router.push('/blog')\n }\n case 'vendors':\n // If we're in profile or other pages, direct to main content\n if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n } else if (currentPath.includes('/vendors') || currentPath.includes('/margin-increase/compare')) {\n return {\n text: \"Reset Filters\",\n action: () => resetParams(['search', 'page', 'category', 'subcategory'])\n }\n }\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n default:\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n }\n\n const defaultContent = getDefaultContent()\n const displayTitle = title || defaultContent.title\n const displayDescription = description || defaultContent.description\n // ctaHref short-circuits BEFORE getSmartCTA(): the smart defaults read\n // window.location.pathname (SSR-empty, client-real), so a server-rendered\n // page with a link CTA must never enter that branch. Existing callers\n // without ctaHref keep today's smart-default behavior unchanged.\n const smartCTA = ctaHref ? null : getSmartCTA()\n const ctaClassName = ctaVariant === 'primary'\n ? \"w-full bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover transition-all duration-150 font-body font-medium\"\n : \"w-full bg-transparent border border-ods-border text-ods-text-primary hover:border-ods-accent hover:text-ods-accent transition-all duration-150 font-body font-medium\"\n\n return (\n <div className=\"flex flex-col items-center justify-center py-6 md:py-16 px-6 text-center\">\n {/* Icon */}\n <div className=\"mb-3 md:mb-6 flex items-center justify-center\">\n <div className=\"rounded-full bg-ods-card p-3 md:p-6 border border-ods-border\">\n <div className=\"w-8 h-8 md:w-16 md:h-16 text-ods-text-secondary flex items-center justify-center\">\n {defaultContent.icon}\n </div>\n </div>\n </div>\n\n {/* Title */}\n <h2 className=\"mb-2 md:mb-3 text-h3 text-ods-text-primary\">\n {displayTitle}\n </h2>\n\n {/* Description */}\n <p className=\"mb-4 md:mb-8 max-w-md text-h6 text-ods-text-secondary\">\n {displayDescription}\n </p>\n\n {/* Link CTA (ctaHref) — SSR-safe, no path sniffing */}\n {showCTA && ctaHref && (\n <div className=\"w-full max-w-xs mb-3\">\n <Button href={ctaHref} className={ctaClassName}>\n {ctaText || 'Contact us'}\n </Button>\n </div>\n )}\n\n {/* Smart CTA Button */}\n {showCTA && !ctaHref && smartCTA && (\n <div className=\"w-full max-w-xs mb-3\">\n <Button onClick={smartCTA.action} className={ctaClassName}>\n {smartCTA.text}\n </Button>\n </div>\n )}\n\n {/* Optional Back Button */}\n {showBackButton && onGoBack && (\n <div className=\"w-full max-w-xs\">\n <Button\n onClick={onGoBack}\n variant=\"outline\"\n className=\"w-full transition-all duration-150 font-body font-medium\"\n >\n {backButtonText}\n </Button>\n </div>\n )}\n </div>\n )\n} "]}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SelectValue,
|
|
13
13
|
Textarea,
|
|
14
14
|
useChatAttachments
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-Y2BLPCJZ.js";
|
|
16
16
|
import {
|
|
17
17
|
useContactSubmission,
|
|
18
18
|
useHumanitySignals
|
|
@@ -374,4 +374,4 @@ function ContactForm({
|
|
|
374
374
|
export {
|
|
375
375
|
ContactForm
|
|
376
376
|
};
|
|
377
|
-
//# sourceMappingURL=chunk-
|
|
377
|
+
//# sourceMappingURL=chunk-RNAXQVBK.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkH635T5R2cjs = require('./chunk-H635T5R2.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
var _chunkXL4V2PYGcjs = require('./chunk-XL4V2PYG.cjs');
|
|
@@ -50,7 +50,7 @@ function DetailPageSkeleton({
|
|
|
50
50
|
] });
|
|
51
51
|
if (bare) return content;
|
|
52
52
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
53
|
-
|
|
53
|
+
_chunkH635T5R2cjs.PageLayout,
|
|
54
54
|
{
|
|
55
55
|
showHeader: false,
|
|
56
56
|
className: "bg-ods-bg max-w-[1280px] mx-auto py-6 md:py-10 px-6 md:px-20",
|
|
@@ -88,7 +88,7 @@ function ArticleAuthorByline({
|
|
|
88
88
|
}) {
|
|
89
89
|
const runtime = _chunk7OPWSWEJcjs.useChatRuntime.call(void 0, );
|
|
90
90
|
if (!author) return null;
|
|
91
|
-
const proxiedAvatar = avatar ? proxyImageUrl ? proxyImageUrl(avatar) : _nullishCoalesce(
|
|
91
|
+
const proxiedAvatar = avatar ? proxyImageUrl ? proxyImageUrl(avatar) : _nullishCoalesce(_chunkH635T5R2cjs.getProxiedImageUrl.call(void 0, avatar, {
|
|
92
92
|
proxyPrefix: _optionalChain([runtime, 'optionalAccess', _2 => _2.endpoints, 'access', _3 => _3.imageProxyUrlPrefix]),
|
|
93
93
|
skipDomains: _optionalChain([runtime, 'optionalAccess', _4 => _4.endpoints, 'access', _5 => _5.imageProxySkipDomains]),
|
|
94
94
|
directHttps: true
|
|
@@ -96,7 +96,7 @@ function ArticleAuthorByline({
|
|
|
96
96
|
const avatarSizeClass = size === "lg" ? "w-16 h-16" : "w-14 h-14";
|
|
97
97
|
const avatarIconClass = size === "lg" ? "w-8 h-8" : "w-7 h-7";
|
|
98
98
|
const avatarDim = size === "lg" ? 64 : 56;
|
|
99
|
-
const formattedBio =
|
|
99
|
+
const formattedBio = _chunkH635T5R2cjs.formatBioText.call(void 0, _nullishCoalesce(bio, () => ( null)));
|
|
100
100
|
const dateLabel = publishedAt ? formatDate(publishedAt) : "";
|
|
101
101
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
102
102
|
"div",
|
|
@@ -146,4 +146,4 @@ function ArticleAuthorByline({
|
|
|
146
146
|
|
|
147
147
|
|
|
148
148
|
exports.DetailPageSkeleton = DetailPageSkeleton; exports.ArticleAuthorByline = ArticleAuthorByline;
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-STJB3XH6.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2MPS2QY5.cjs","../src/components/shared/detail-page-skeleton.tsx","../src/components/shared/article-author-byline.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2MPS2QY5.cjs","sourcesContent":[null,"\"use client\";\n\nimport { PageLayout } from '../layout/page-layout';\n\nexport interface DetailPageSkeletonProps {\n metadataColumns?: number; // Number of metadata grid columns (default 4)\n showImageGallery?: boolean; // Show horizontal image gallery (default true)\n /** Render only the skeleton blocks, WITHOUT the self-contained page wrapper\n * — the caller supplies its own (e.g. `<PageShell>`) so the loading state\n * matches the loaded page's width, padding, and min-height. Default false\n * (self-contained `<PageLayout>` at the hub article width). */\n bare?: boolean;\n}\n\nexport function DetailPageSkeleton({\n metadataColumns = 4,\n showImageGallery = true,\n bare = false\n}: DetailPageSkeletonProps = {}) {\n const content = (\n <div className=\"space-y-6 md:space-y-10 animate-pulse\">\n {/* Title Block */}\n <div className=\"flex flex-col gap-6 w-full\">\n <div className=\"h-16 md:h-20 w-full max-w-3xl bg-ods-card rounded\"></div>\n </div>\n\n {/* Category Tags Skeleton */}\n <div className=\"flex flex-wrap gap-2 w-full\">\n <div className=\"h-8 w-32 bg-ods-card rounded\"></div>\n <div className=\"h-8 w-28 bg-ods-card rounded\"></div>\n <div className=\"h-8 w-36 bg-ods-card rounded\"></div>\n </div>\n\n {/* Metadata Grid Skeleton */}\n <div className={`grid grid-cols-1 md:grid-cols-${metadataColumns} border border-ods-border rounded-md overflow-hidden w-full`}>\n {Array.from({ length: metadataColumns }).map((_, i) => (\n <div key={i} className=\"bg-ods-card border-b md:border-b-0 md:border-r last:border-r-0 border-ods-border p-4\">\n <div className=\"h-6 w-24 bg-ods-border rounded mb-2\"></div>\n <div className=\"h-5 w-20 bg-ods-border rounded\"></div>\n </div>\n ))}\n </div>\n\n {/* Image Gallery Skeleton */}\n {showImageGallery && (\n <div className=\"flex gap-6 overflow-x-auto w-full\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"shrink-0 w-[240px] h-[200px] bg-ods-card rounded-md border border-ods-border\"></div>\n ))}\n </div>\n )}\n\n {/* Featured Image Skeleton (for case studies) */}\n {!showImageGallery && (\n <div className=\"aspect-[2560/1366] w-full bg-ods-card rounded-md\"></div>\n )}\n\n {/* Content Sections Skeleton */}\n {[1, 2, 3].map((section) => (\n <div key={section} className=\"space-y-6\">\n <div className=\"h-16 w-64 bg-ods-card rounded\"></div>\n <div className=\"space-y-3\">\n <div className=\"h-6 w-full bg-ods-card rounded\"></div>\n <div className=\"h-6 w-full bg-ods-card rounded\"></div>\n <div className=\"h-6 w-4/5 bg-ods-card rounded\"></div>\n </div>\n </div>\n ))}\n </div>\n );\n if (bare) return content;\n return (\n <PageLayout\n showHeader={false}\n className=\"bg-ods-bg max-w-[1280px] mx-auto py-6 md:py-10 px-6 md:px-20\"\n >\n {content}\n </PageLayout>\n );\n}\n","'use client'\n\n/**\n * Shared \"author byline\" card used by article-shaped detail pages\n * (blog post, product release, onboarding guide, investor update).\n *\n * MOVED from the hub so any consuming app can embed it; hub call sites\n * import it directly and pass their platform-aware copy explicitly\n * (`fallbackBio={defaultAuthorFallbackBio()}` from the hub's app-config).\n *\n * Embed-readiness contract:\n * - `Link` / `Image` render through the embed-shims (plain `<a>` / `<img>`\n * in non-Next hosts; the real Next primitives once the host registers\n * them at app init).\n * - The avatar is proxied through the OPTIONAL ambient `ChatRuntime`\n * (`endpoints.imageProxyUrlPrefix`, same config `useProxiedImageUrl`\n * reads) — when no runtime is mounted the raw URL renders as-is, so the\n * component never throws outside a provider. Hosts can also inject\n * `proxyImageUrl` to bypass the runtime entirely.\n * - `fallbackBio` is a PLAIN prop (no app-config import): the lib has no\n * platform awareness; pass copy or leave it absent to render nothing.\n *\n * Render order: avatar → name + job title + date → bio (when present).\n * Returns null when `author` is empty (no card rendered).\n */\n\nimport React from 'react'\nimport { Calendar, User } from 'lucide-react'\nimport Image from '../../embed-shims/next-image'\nimport Link from '../../embed-shims/next-link'\nimport { cn } from '../../utils/cn'\nimport { formatBioText } from '../../utils/format'\nimport { getProxiedImageUrl } from '../../utils/image-proxy'\nimport { useChatRuntime } from '../../contexts/chat-runtime-context'\n\nexport interface ArticleAuthorBylineProps {\n /** Author display name. Required — block is hidden when null/empty. */\n author: string | null\n /** Avatar URL. Falls back to a placeholder when null. */\n avatar?: string | null\n /** Optional bio paragraph rendered below the name. */\n bio?: string | null\n /** Optional job title rendered immediately under the name. */\n jobTitle?: string | null\n /** Optional published date (ISO string or Date). Rendered next to the name. */\n publishedAt?: string | Date | null\n /** Optional link target for the author name (e.g. the author page). */\n href?: string | null\n /**\n * Fallback paragraph when `bio` is empty. Plain copy — the lib has no\n * platform/config awareness, so hosts that want a branded default\n * (\"Contributing author on the {platform} platform\") pass it explicitly\n * (the hub wrapper derives it from `getAppConfig()`). Absent/null ⇒\n * nothing renders below the name when `bio` is empty.\n */\n fallbackBio?: string | null\n /** Avatar size variant. `md` = 56px (default), `lg` = 64px. */\n size?: 'md' | 'lg'\n /**\n * Host-injected avatar-URL mapper. Wins over the ambient-runtime proxy\n * resolution. Use when the host proxies images outside the `ChatRuntime`\n * config (e.g. a bespoke CDN rewrite).\n */\n proxyImageUrl?: (url: string) => string\n className?: string\n}\n\nfunction formatDate(value: string | Date): string {\n const d = typeof value === 'string' ? new Date(value) : value\n if (Number.isNaN(d.getTime())) return ''\n // `timeZone: 'UTC'` keeps the SSR (server = UTC) and client (user's local tz)\n // renders identical — without it a published_at near a midnight boundary\n // formats to a different day on each side, triggering a React #418 hydration\n // text mismatch. Matches the convention in blog-metadata.tsx / investor-update.\n return d.toLocaleDateString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n timeZone: 'UTC',\n })\n}\n\nexport function ArticleAuthorByline({\n author,\n avatar,\n bio,\n jobTitle,\n publishedAt,\n href,\n fallbackBio,\n size = 'md',\n proxyImageUrl,\n className,\n}: ArticleAuthorBylineProps) {\n // Optional runtime — `useChatRuntime` returns null outside a provider, so\n // the byline works in bare embeds (raw avatar URL) and proxies whenever the\n // host mounted a runtime with `imageProxyUrlPrefix` (the hub always does).\n const runtime = useChatRuntime()\n if (!author) return null\n\n const proxiedAvatar = avatar\n ? proxyImageUrl\n ? proxyImageUrl(avatar)\n : (getProxiedImageUrl(avatar, {\n proxyPrefix: runtime?.endpoints.imageProxyUrlPrefix,\n skipDomains: runtime?.endpoints.imageProxySkipDomains,\n directHttps: true,\n }) ?? avatar)\n : ''\n\n // Class-driven sizing (md = 56px, lg = 64px). The numeric pair feeds only\n // the Image element's intrinsic width/height attributes (required by the\n // Next image shim) — layout comes from the classes.\n const avatarSizeClass = size === 'lg' ? 'w-16 h-16' : 'w-14 h-14'\n const avatarIconClass = size === 'lg' ? 'w-8 h-8' : 'w-7 h-7'\n const avatarDim = size === 'lg' ? 64 : 56\n const formattedBio = formatBioText(bio ?? null)\n const dateLabel = publishedAt ? formatDate(publishedAt) : ''\n\n return (\n <div\n className={cn(\n 'bg-ods-card border border-ods-border rounded-lg p-6',\n 'flex flex-col md:flex-row gap-4 items-start',\n className,\n )}\n >\n {/* Avatar */}\n <div className=\"flex-shrink-0\">\n {avatar ? (\n <Image\n src={proxiedAvatar || avatar}\n alt={author}\n width={avatarDim}\n height={avatarDim}\n className={cn('rounded-full border-2 border-ods-border object-cover', avatarSizeClass)}\n />\n ) : (\n <div\n className={cn(\n 'rounded-full border-2 border-ods-border bg-ods-bg flex items-center justify-center',\n avatarSizeClass,\n )}\n >\n <User className={cn('text-ods-text-secondary', avatarIconClass)} />\n </div>\n )}\n </div>\n\n {/* Name + meta + bio */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-baseline gap-x-3 gap-y-1\">\n <h3 className=\"text-h5 text-ods-text-primary\">\n {href ? (\n <Link href={href} className=\"hover:text-ods-accent transition-colors\">\n {author}\n </Link>\n ) : (\n author\n )}\n </h3>\n {dateLabel && (\n <span className=\"inline-flex items-center gap-1 font-body text-body-sm text-ods-text-secondary\">\n <Calendar className=\"h-3 w-3\" />\n {dateLabel}\n </span>\n )}\n </div>\n {jobTitle && (\n <p className=\"font-body text-body-sm text-ods-text-secondary mt-0.5\">\n {jobTitle}\n </p>\n )}\n {formattedBio ? (\n <p className=\"font-body text-body-md text-ods-text-secondary leading-relaxed mt-2\">\n {formattedBio}\n </p>\n ) : fallbackBio ? (\n <p className=\"font-body text-body-md text-ods-text-secondary italic mt-2\">\n {fallbackBio}\n </p>\n ) : null}\n </div>\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-STJB3XH6.cjs","../src/components/shared/detail-page-skeleton.tsx","../src/components/shared/article-author-byline.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-STJB3XH6.cjs","sourcesContent":[null,"\"use client\";\n\nimport { PageLayout } from '../layout/page-layout';\n\nexport interface DetailPageSkeletonProps {\n metadataColumns?: number; // Number of metadata grid columns (default 4)\n showImageGallery?: boolean; // Show horizontal image gallery (default true)\n /** Render only the skeleton blocks, WITHOUT the self-contained page wrapper\n * — the caller supplies its own (e.g. `<PageShell>`) so the loading state\n * matches the loaded page's width, padding, and min-height. Default false\n * (self-contained `<PageLayout>` at the hub article width). */\n bare?: boolean;\n}\n\nexport function DetailPageSkeleton({\n metadataColumns = 4,\n showImageGallery = true,\n bare = false\n}: DetailPageSkeletonProps = {}) {\n const content = (\n <div className=\"space-y-6 md:space-y-10 animate-pulse\">\n {/* Title Block */}\n <div className=\"flex flex-col gap-6 w-full\">\n <div className=\"h-16 md:h-20 w-full max-w-3xl bg-ods-card rounded\"></div>\n </div>\n\n {/* Category Tags Skeleton */}\n <div className=\"flex flex-wrap gap-2 w-full\">\n <div className=\"h-8 w-32 bg-ods-card rounded\"></div>\n <div className=\"h-8 w-28 bg-ods-card rounded\"></div>\n <div className=\"h-8 w-36 bg-ods-card rounded\"></div>\n </div>\n\n {/* Metadata Grid Skeleton */}\n <div className={`grid grid-cols-1 md:grid-cols-${metadataColumns} border border-ods-border rounded-md overflow-hidden w-full`}>\n {Array.from({ length: metadataColumns }).map((_, i) => (\n <div key={i} className=\"bg-ods-card border-b md:border-b-0 md:border-r last:border-r-0 border-ods-border p-4\">\n <div className=\"h-6 w-24 bg-ods-border rounded mb-2\"></div>\n <div className=\"h-5 w-20 bg-ods-border rounded\"></div>\n </div>\n ))}\n </div>\n\n {/* Image Gallery Skeleton */}\n {showImageGallery && (\n <div className=\"flex gap-6 overflow-x-auto w-full\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"shrink-0 w-[240px] h-[200px] bg-ods-card rounded-md border border-ods-border\"></div>\n ))}\n </div>\n )}\n\n {/* Featured Image Skeleton (for case studies) */}\n {!showImageGallery && (\n <div className=\"aspect-[2560/1366] w-full bg-ods-card rounded-md\"></div>\n )}\n\n {/* Content Sections Skeleton */}\n {[1, 2, 3].map((section) => (\n <div key={section} className=\"space-y-6\">\n <div className=\"h-16 w-64 bg-ods-card rounded\"></div>\n <div className=\"space-y-3\">\n <div className=\"h-6 w-full bg-ods-card rounded\"></div>\n <div className=\"h-6 w-full bg-ods-card rounded\"></div>\n <div className=\"h-6 w-4/5 bg-ods-card rounded\"></div>\n </div>\n </div>\n ))}\n </div>\n );\n if (bare) return content;\n return (\n <PageLayout\n showHeader={false}\n className=\"bg-ods-bg max-w-[1280px] mx-auto py-6 md:py-10 px-6 md:px-20\"\n >\n {content}\n </PageLayout>\n );\n}\n","'use client'\n\n/**\n * Shared \"author byline\" card used by article-shaped detail pages\n * (blog post, product release, onboarding guide, investor update).\n *\n * MOVED from the hub so any consuming app can embed it; hub call sites\n * import it directly and pass their platform-aware copy explicitly\n * (`fallbackBio={defaultAuthorFallbackBio()}` from the hub's app-config).\n *\n * Embed-readiness contract:\n * - `Link` / `Image` render through the embed-shims (plain `<a>` / `<img>`\n * in non-Next hosts; the real Next primitives once the host registers\n * them at app init).\n * - The avatar is proxied through the OPTIONAL ambient `ChatRuntime`\n * (`endpoints.imageProxyUrlPrefix`, same config `useProxiedImageUrl`\n * reads) — when no runtime is mounted the raw URL renders as-is, so the\n * component never throws outside a provider. Hosts can also inject\n * `proxyImageUrl` to bypass the runtime entirely.\n * - `fallbackBio` is a PLAIN prop (no app-config import): the lib has no\n * platform awareness; pass copy or leave it absent to render nothing.\n *\n * Render order: avatar → name + job title + date → bio (when present).\n * Returns null when `author` is empty (no card rendered).\n */\n\nimport React from 'react'\nimport { Calendar, User } from 'lucide-react'\nimport Image from '../../embed-shims/next-image'\nimport Link from '../../embed-shims/next-link'\nimport { cn } from '../../utils/cn'\nimport { formatBioText } from '../../utils/format'\nimport { getProxiedImageUrl } from '../../utils/image-proxy'\nimport { useChatRuntime } from '../../contexts/chat-runtime-context'\n\nexport interface ArticleAuthorBylineProps {\n /** Author display name. Required — block is hidden when null/empty. */\n author: string | null\n /** Avatar URL. Falls back to a placeholder when null. */\n avatar?: string | null\n /** Optional bio paragraph rendered below the name. */\n bio?: string | null\n /** Optional job title rendered immediately under the name. */\n jobTitle?: string | null\n /** Optional published date (ISO string or Date). Rendered next to the name. */\n publishedAt?: string | Date | null\n /** Optional link target for the author name (e.g. the author page). */\n href?: string | null\n /**\n * Fallback paragraph when `bio` is empty. Plain copy — the lib has no\n * platform/config awareness, so hosts that want a branded default\n * (\"Contributing author on the {platform} platform\") pass it explicitly\n * (the hub wrapper derives it from `getAppConfig()`). Absent/null ⇒\n * nothing renders below the name when `bio` is empty.\n */\n fallbackBio?: string | null\n /** Avatar size variant. `md` = 56px (default), `lg` = 64px. */\n size?: 'md' | 'lg'\n /**\n * Host-injected avatar-URL mapper. Wins over the ambient-runtime proxy\n * resolution. Use when the host proxies images outside the `ChatRuntime`\n * config (e.g. a bespoke CDN rewrite).\n */\n proxyImageUrl?: (url: string) => string\n className?: string\n}\n\nfunction formatDate(value: string | Date): string {\n const d = typeof value === 'string' ? new Date(value) : value\n if (Number.isNaN(d.getTime())) return ''\n // `timeZone: 'UTC'` keeps the SSR (server = UTC) and client (user's local tz)\n // renders identical — without it a published_at near a midnight boundary\n // formats to a different day on each side, triggering a React #418 hydration\n // text mismatch. Matches the convention in blog-metadata.tsx / investor-update.\n return d.toLocaleDateString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n timeZone: 'UTC',\n })\n}\n\nexport function ArticleAuthorByline({\n author,\n avatar,\n bio,\n jobTitle,\n publishedAt,\n href,\n fallbackBio,\n size = 'md',\n proxyImageUrl,\n className,\n}: ArticleAuthorBylineProps) {\n // Optional runtime — `useChatRuntime` returns null outside a provider, so\n // the byline works in bare embeds (raw avatar URL) and proxies whenever the\n // host mounted a runtime with `imageProxyUrlPrefix` (the hub always does).\n const runtime = useChatRuntime()\n if (!author) return null\n\n const proxiedAvatar = avatar\n ? proxyImageUrl\n ? proxyImageUrl(avatar)\n : (getProxiedImageUrl(avatar, {\n proxyPrefix: runtime?.endpoints.imageProxyUrlPrefix,\n skipDomains: runtime?.endpoints.imageProxySkipDomains,\n directHttps: true,\n }) ?? avatar)\n : ''\n\n // Class-driven sizing (md = 56px, lg = 64px). The numeric pair feeds only\n // the Image element's intrinsic width/height attributes (required by the\n // Next image shim) — layout comes from the classes.\n const avatarSizeClass = size === 'lg' ? 'w-16 h-16' : 'w-14 h-14'\n const avatarIconClass = size === 'lg' ? 'w-8 h-8' : 'w-7 h-7'\n const avatarDim = size === 'lg' ? 64 : 56\n const formattedBio = formatBioText(bio ?? null)\n const dateLabel = publishedAt ? formatDate(publishedAt) : ''\n\n return (\n <div\n className={cn(\n 'bg-ods-card border border-ods-border rounded-lg p-6',\n 'flex flex-col md:flex-row gap-4 items-start',\n className,\n )}\n >\n {/* Avatar */}\n <div className=\"flex-shrink-0\">\n {avatar ? (\n <Image\n src={proxiedAvatar || avatar}\n alt={author}\n width={avatarDim}\n height={avatarDim}\n className={cn('rounded-full border-2 border-ods-border object-cover', avatarSizeClass)}\n />\n ) : (\n <div\n className={cn(\n 'rounded-full border-2 border-ods-border bg-ods-bg flex items-center justify-center',\n avatarSizeClass,\n )}\n >\n <User className={cn('text-ods-text-secondary', avatarIconClass)} />\n </div>\n )}\n </div>\n\n {/* Name + meta + bio */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-baseline gap-x-3 gap-y-1\">\n <h3 className=\"text-h5 text-ods-text-primary\">\n {href ? (\n <Link href={href} className=\"hover:text-ods-accent transition-colors\">\n {author}\n </Link>\n ) : (\n author\n )}\n </h3>\n {dateLabel && (\n <span className=\"inline-flex items-center gap-1 font-body text-body-sm text-ods-text-secondary\">\n <Calendar className=\"h-3 w-3\" />\n {dateLabel}\n </span>\n )}\n </div>\n {jobTitle && (\n <p className=\"font-body text-body-sm text-ods-text-secondary mt-0.5\">\n {jobTitle}\n </p>\n )}\n {formattedBio ? (\n <p className=\"font-body text-body-md text-ods-text-secondary leading-relaxed mt-2\">\n {formattedBio}\n </p>\n ) : fallbackBio ? (\n <p className=\"font-body text-body-md text-ods-text-secondary italic mt-2\">\n {fallbackBio}\n </p>\n ) : null}\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Pagination,
|
|
4
4
|
init_pagination
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-Y2BLPCJZ.js";
|
|
6
6
|
import {
|
|
7
7
|
init_next_navigation,
|
|
8
8
|
usePathname,
|
|
@@ -210,4 +210,4 @@ export {
|
|
|
210
210
|
unified_pagination_exports,
|
|
211
211
|
init_unified_pagination
|
|
212
212
|
};
|
|
213
|
-
//# sourceMappingURL=chunk-
|
|
213
|
+
//# sourceMappingURL=chunk-WR2XVJ6K.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
faqSectionSlug,
|
|
12
12
|
parseFaqHash,
|
|
13
13
|
serializeJsonLd
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Y2BLPCJZ.js";
|
|
15
15
|
import {
|
|
16
16
|
STICKY_HEADER_OFFSET_PX,
|
|
17
17
|
navigateSamePageHash,
|
|
@@ -382,4 +382,4 @@ export {
|
|
|
382
382
|
FaqSection,
|
|
383
383
|
FaqDocumentPage
|
|
384
384
|
};
|
|
385
|
-
//# sourceMappingURL=chunk-
|
|
385
|
+
//# sourceMappingURL=chunk-XMROOTCF.js.map
|