@burdenoff/website-sdk 2026.1031.3 → 2026.1101.2
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/README.md +42 -8
- package/dist/analytics/index.js +19 -69
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +3 -69
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/avatar-live/index.js +1 -0
- package/dist/avatar-live/index.js.map +1 -1
- package/dist/avatar-live/index.mjs +1 -0
- package/dist/avatar-live/index.mjs.map +1 -1
- package/dist/avatar-live-view/index.js +10 -30
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +4 -24
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/chunk-23H4JUL4.js +41 -0
- package/dist/chunk-23H4JUL4.js.map +1 -0
- package/dist/chunk-34RX5P75.mjs +25 -0
- package/dist/chunk-34RX5P75.mjs.map +1 -0
- package/dist/chunk-3LFFY7AZ.js +184 -0
- package/dist/chunk-3LFFY7AZ.js.map +1 -0
- package/dist/chunk-3X26GE4S.js +2794 -0
- package/dist/chunk-3X26GE4S.js.map +1 -0
- package/dist/chunk-45GCA4GG.js +85 -0
- package/dist/chunk-45GCA4GG.js.map +1 -0
- package/dist/chunk-4SAGVLHN.js +876 -0
- package/dist/chunk-4SAGVLHN.js.map +1 -0
- package/dist/chunk-4U6YAII5.js +218 -0
- package/dist/chunk-4U6YAII5.js.map +1 -0
- package/dist/chunk-5GMTBOO6.js +21 -0
- package/dist/chunk-5GMTBOO6.js.map +1 -0
- package/dist/chunk-5JRJ57CL.mjs +329 -0
- package/dist/chunk-5JRJ57CL.mjs.map +1 -0
- package/dist/chunk-6C2DKIC7.js +4 -0
- package/dist/chunk-6C2DKIC7.js.map +1 -0
- package/dist/chunk-6IBFBWC5.mjs +17 -0
- package/dist/chunk-6IBFBWC5.mjs.map +1 -0
- package/dist/chunk-6KY2ZRVI.js +116 -0
- package/dist/chunk-6KY2ZRVI.js.map +1 -0
- package/dist/chunk-6VJT3SM4.mjs +182 -0
- package/dist/chunk-6VJT3SM4.mjs.map +1 -0
- package/dist/chunk-6YZUFMK2.mjs +40 -0
- package/dist/chunk-6YZUFMK2.mjs.map +1 -0
- package/dist/chunk-7A6R7CGG.js +47 -0
- package/dist/chunk-7A6R7CGG.js.map +1 -0
- package/dist/chunk-7PWL4V2R.js +4 -0
- package/dist/chunk-7PWL4V2R.js.map +1 -0
- package/dist/chunk-AA33WDYS.js +161 -0
- package/dist/chunk-AA33WDYS.js.map +1 -0
- package/dist/chunk-AHRGFXV2.js +525 -0
- package/dist/chunk-AHRGFXV2.js.map +1 -0
- package/dist/chunk-B63XLDZH.mjs +109 -0
- package/dist/chunk-B63XLDZH.mjs.map +1 -0
- package/dist/chunk-BX2USEWF.mjs +35 -0
- package/dist/chunk-BX2USEWF.mjs.map +1 -0
- package/dist/chunk-BYSZT35R.js +150 -0
- package/dist/chunk-BYSZT35R.js.map +1 -0
- package/dist/chunk-C6OJIHNO.js +12 -0
- package/dist/chunk-C6OJIHNO.js.map +1 -0
- package/dist/chunk-COOELBX7.mjs +63 -0
- package/dist/chunk-COOELBX7.mjs.map +1 -0
- package/dist/chunk-D2TW7MNC.mjs +2771 -0
- package/dist/chunk-D2TW7MNC.mjs.map +1 -0
- package/dist/chunk-D5KEZ6V6.mjs +3 -0
- package/dist/chunk-D5KEZ6V6.mjs.map +1 -0
- package/dist/chunk-E3GUGJMY.js +46 -0
- package/dist/chunk-E3GUGJMY.js.map +1 -0
- package/dist/chunk-EBZ2HGJ2.mjs +52 -0
- package/dist/chunk-EBZ2HGJ2.mjs.map +1 -0
- package/dist/chunk-EDLTUOIA.mjs +210 -0
- package/dist/chunk-EDLTUOIA.mjs.map +1 -0
- package/dist/chunk-EJQSOT4X.js +4 -0
- package/dist/chunk-EJQSOT4X.js.map +1 -0
- package/dist/chunk-EUPFS6MZ.mjs +2019 -0
- package/dist/chunk-EUPFS6MZ.mjs.map +1 -0
- package/dist/chunk-F3XWDC3B.js +77 -0
- package/dist/chunk-F3XWDC3B.js.map +1 -0
- package/dist/chunk-FFADMVIK.mjs +5127 -0
- package/dist/chunk-FFADMVIK.mjs.map +1 -0
- package/dist/chunk-FJWS7BKT.mjs +3 -0
- package/dist/chunk-FJWS7BKT.mjs.map +1 -0
- package/dist/chunk-FJZJDUOR.mjs +3 -0
- package/dist/chunk-FJZJDUOR.mjs.map +1 -0
- package/dist/chunk-GCFLCO2Z.mjs +145 -0
- package/dist/chunk-GCFLCO2Z.mjs.map +1 -0
- package/dist/chunk-GEXC4LRP.js +61 -0
- package/dist/chunk-GEXC4LRP.js.map +1 -0
- package/dist/chunk-GTRAXQGC.mjs +3 -0
- package/dist/chunk-GTRAXQGC.mjs.map +1 -0
- package/dist/chunk-IKOIRUKW.js +270 -0
- package/dist/chunk-IKOIRUKW.js.map +1 -0
- package/dist/chunk-IXTWOPRN.js +45 -0
- package/dist/chunk-IXTWOPRN.js.map +1 -0
- package/dist/chunk-JDXOXGOK.js +547 -0
- package/dist/chunk-JDXOXGOK.js.map +1 -0
- package/dist/chunk-JSLDWYV7.mjs +558 -0
- package/dist/chunk-JSLDWYV7.mjs.map +1 -0
- package/dist/chunk-JXLSTVBK.js +336 -0
- package/dist/chunk-JXLSTVBK.js.map +1 -0
- package/dist/chunk-KHYXK7FG.mjs +49 -0
- package/dist/chunk-KHYXK7FG.mjs.map +1 -0
- package/dist/chunk-KSMBOWQQ.js +2034 -0
- package/dist/chunk-KSMBOWQQ.js.map +1 -0
- package/dist/chunk-KU2PXHGB.mjs +83 -0
- package/dist/chunk-KU2PXHGB.mjs.map +1 -0
- package/dist/chunk-KZANIV3S.mjs +37 -0
- package/dist/chunk-KZANIV3S.mjs.map +1 -0
- package/dist/chunk-L4BP6YOB.js +20 -0
- package/dist/chunk-L4BP6YOB.js.map +1 -0
- package/dist/chunk-MRKA2OAF.mjs +75 -0
- package/dist/chunk-MRKA2OAF.mjs.map +1 -0
- package/dist/chunk-N5EC53MH.mjs +80 -0
- package/dist/chunk-N5EC53MH.mjs.map +1 -0
- package/dist/chunk-NZANQGDM.mjs +34 -0
- package/dist/chunk-NZANQGDM.mjs.map +1 -0
- package/dist/chunk-O4GS3XPZ.js +10 -0
- package/dist/chunk-O4GS3XPZ.js.map +1 -0
- package/dist/chunk-O76QDGRM.js +5154 -0
- package/dist/chunk-O76QDGRM.js.map +1 -0
- package/dist/chunk-OYEUNZJY.js +114 -0
- package/dist/chunk-OYEUNZJY.js.map +1 -0
- package/dist/chunk-PHXAGQNB.js +74 -0
- package/dist/chunk-PHXAGQNB.js.map +1 -0
- package/dist/chunk-PIHHPP7J.mjs +16 -0
- package/dist/chunk-PIHHPP7J.mjs.map +1 -0
- package/dist/chunk-PXRHVVOU.mjs +499 -0
- package/dist/chunk-PXRHVVOU.mjs.map +1 -0
- package/dist/chunk-QMA6U6AU.js +36 -0
- package/dist/chunk-QMA6U6AU.js.map +1 -0
- package/dist/chunk-R6J7IULF.js +44 -0
- package/dist/chunk-R6J7IULF.js.map +1 -0
- package/dist/chunk-R7G6TWIS.mjs +10 -0
- package/dist/chunk-R7G6TWIS.mjs.map +1 -0
- package/dist/chunk-RUMGFI6L.mjs +544 -0
- package/dist/chunk-RUMGFI6L.mjs.map +1 -0
- package/dist/chunk-S54JWSJF.js +565 -0
- package/dist/chunk-S54JWSJF.js.map +1 -0
- package/dist/chunk-SK5UGG6A.js +2041 -0
- package/dist/chunk-SK5UGG6A.js.map +1 -0
- package/dist/chunk-SKIYDKIS.mjs +70 -0
- package/dist/chunk-SKIYDKIS.mjs.map +1 -0
- package/dist/chunk-SZNS5IK6.mjs +322 -0
- package/dist/chunk-SZNS5IK6.mjs.map +1 -0
- package/dist/chunk-T7JIPZAC.js +66 -0
- package/dist/chunk-T7JIPZAC.js.map +1 -0
- package/dist/chunk-TGYQHO2E.mjs +864 -0
- package/dist/chunk-TGYQHO2E.mjs.map +1 -0
- package/dist/chunk-TT3MHN42.mjs +8 -0
- package/dist/chunk-TT3MHN42.mjs.map +1 -0
- package/dist/chunk-UM55U65W.mjs +268 -0
- package/dist/chunk-UM55U65W.mjs.map +1 -0
- package/dist/chunk-UQ2HALUD.js +72 -0
- package/dist/chunk-UQ2HALUD.js.map +1 -0
- package/dist/chunk-UXWT7G77.js +82 -0
- package/dist/chunk-UXWT7G77.js.map +1 -0
- package/dist/chunk-VNS5WDWO.mjs +7 -0
- package/dist/chunk-VNS5WDWO.mjs.map +1 -0
- package/dist/chunk-VRWZLGR7.js +4 -0
- package/dist/chunk-VRWZLGR7.js.map +1 -0
- package/dist/chunk-VZLDSNH4.mjs +22 -0
- package/dist/chunk-VZLDSNH4.mjs.map +1 -0
- package/dist/chunk-W6P3YETJ.js +92 -0
- package/dist/chunk-W6P3YETJ.js.map +1 -0
- package/dist/chunk-WPKFFQCR.mjs +90 -0
- package/dist/chunk-WPKFFQCR.mjs.map +1 -0
- package/dist/chunk-WTVTI5TO.mjs +22 -0
- package/dist/chunk-WTVTI5TO.mjs.map +1 -0
- package/dist/chunk-XJOBZ4RJ.js +44 -0
- package/dist/chunk-XJOBZ4RJ.js.map +1 -0
- package/dist/chunk-XP2JDNDU.js +325 -0
- package/dist/chunk-XP2JDNDU.js.map +1 -0
- package/dist/chunk-Y4V5CEWD.mjs +112 -0
- package/dist/chunk-Y4V5CEWD.mjs.map +1 -0
- package/dist/chunk-YERN2UWM.js +116 -0
- package/dist/chunk-YERN2UWM.js.map +1 -0
- package/dist/chunk-ZKJQWFAA.mjs +114 -0
- package/dist/chunk-ZKJQWFAA.mjs.map +1 -0
- package/dist/chunk-ZOON3S3Y.mjs +138 -0
- package/dist/chunk-ZOON3S3Y.mjs.map +1 -0
- package/dist/chunk-ZP6QRAYC.mjs +2024 -0
- package/dist/chunk-ZP6QRAYC.mjs.map +1 -0
- package/dist/chunk-ZSTFX7FV.js +9 -0
- package/dist/chunk-ZSTFX7FV.js.map +1 -0
- package/dist/client/index.js +23 -331
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -330
- package/dist/client/index.mjs.map +1 -1
- package/dist/comparison/index.js +28 -111
- package/dist/comparison/index.js.map +1 -1
- package/dist/comparison/index.mjs +2 -107
- package/dist/comparison/index.mjs.map +1 -1
- package/dist/components/contact.js +21 -931
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +12 -909
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/electron-download.js +12 -124
- package/dist/components/electron-download.js.map +1 -1
- package/dist/components/electron-download.mjs +4 -106
- package/dist/components/electron-download.mjs.map +1 -1
- package/dist/components/explore-cta.js +8 -112
- package/dist/components/explore-cta.js.map +1 -1
- package/dist/components/explore-cta.mjs +3 -114
- package/dist/components/explore-cta.mjs.map +1 -1
- package/dist/components/explore.js +62 -7833
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +13 -7800
- package/dist/components/explore.mjs.map +1 -1
- package/dist/components/launch-countdown.js +8 -83
- package/dist/components/launch-countdown.js.map +1 -1
- package/dist/components/launch-countdown.mjs +3 -85
- package/dist/components/launch-countdown.mjs.map +1 -1
- package/dist/components/newsletter.js +20 -993
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +11 -971
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.js +24 -1302
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +15 -1276
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.js +49 -1249
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +8 -1226
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/problems-solved.js +8 -150
- package/dist/components/problems-solved.js.map +1 -1
- package/dist/components/problems-solved.mjs +4 -133
- package/dist/components/problems-solved.mjs.map +1 -1
- package/dist/components/resource-links.js +8 -304
- package/dist/components/resource-links.js.map +1 -1
- package/dist/components/resource-links.mjs +5 -308
- package/dist/components/resource-links.mjs.map +1 -1
- package/dist/components/social-links.js +8 -343
- package/dist/components/social-links.js.map +1 -1
- package/dist/components/social-links.mjs +5 -347
- package/dist/components/social-links.mjs.map +1 -1
- package/dist/components/unsubscribe.js +10 -627
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +6 -611
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.js +21 -1001
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +12 -982
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/components/website-switcher.js +12 -175
- package/dist/components/website-switcher.js.map +1 -1
- package/dist/components/website-switcher.mjs +4 -157
- package/dist/components/website-switcher.mjs.map +1 -1
- package/dist/content/index.js +118 -3616
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +12 -3567
- package/dist/content/index.mjs.map +1 -1
- package/dist/hooks/index.js +37 -2321
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -2318
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.js +4145 -20599
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3766 -20567
- package/dist/index.mjs.map +1 -1
- package/dist/product/index.js +20 -393
- package/dist/product/index.js.map +1 -1
- package/dist/product/index.mjs +5 -394
- package/dist/product/index.mjs.map +1 -1
- package/dist/seo/index.js +8 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +3 -78
- package/dist/seo/index.mjs.map +1 -1
- package/dist/store/index.js +51 -2650
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +13 -2619
- package/dist/store/index.mjs.map +1 -1
- package/dist/utils/index.js +69 -134
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +5 -122
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
var PROSE_CSS = `
|
|
4
|
+
.boff-prose {
|
|
5
|
+
max-width: none;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.boff-prose h1 {
|
|
9
|
+
font-size: 2.25rem;
|
|
10
|
+
font-weight: 800;
|
|
11
|
+
line-height: 1.2;
|
|
12
|
+
margin-top: 0;
|
|
13
|
+
margin-bottom: 1rem;
|
|
14
|
+
color: hsl(var(--foreground));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.boff-prose h2 {
|
|
18
|
+
font-size: 1.75rem;
|
|
19
|
+
font-weight: 700;
|
|
20
|
+
line-height: 1.3;
|
|
21
|
+
margin-top: 2rem;
|
|
22
|
+
margin-bottom: 1rem;
|
|
23
|
+
color: hsl(var(--foreground));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.boff-prose h3 {
|
|
27
|
+
font-size: 1.5rem;
|
|
28
|
+
font-weight: 600;
|
|
29
|
+
line-height: 1.4;
|
|
30
|
+
margin-top: 1.5rem;
|
|
31
|
+
margin-bottom: 0.75rem;
|
|
32
|
+
color: hsl(var(--foreground));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.boff-prose h4 {
|
|
36
|
+
font-size: 1.25rem;
|
|
37
|
+
font-weight: 600;
|
|
38
|
+
line-height: 1.5;
|
|
39
|
+
margin-top: 1.25rem;
|
|
40
|
+
margin-bottom: 0.5rem;
|
|
41
|
+
color: hsl(var(--foreground));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.boff-prose p {
|
|
45
|
+
margin-bottom: 1rem;
|
|
46
|
+
line-height: 1.75;
|
|
47
|
+
color: hsl(var(--foreground));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.boff-prose ul,
|
|
51
|
+
.boff-prose ol {
|
|
52
|
+
margin-bottom: 1rem;
|
|
53
|
+
padding-left: 1.5rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.boff-prose ul {
|
|
57
|
+
list-style-type: disc;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.boff-prose ol {
|
|
61
|
+
list-style-type: decimal;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.boff-prose li {
|
|
65
|
+
margin-bottom: 0.25rem;
|
|
66
|
+
line-height: 1.75;
|
|
67
|
+
color: hsl(var(--foreground));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.boff-prose li > ul,
|
|
71
|
+
.boff-prose li > ol {
|
|
72
|
+
margin-top: 0.25rem;
|
|
73
|
+
margin-bottom: 0.25rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.boff-prose a {
|
|
77
|
+
color: hsl(var(--primary));
|
|
78
|
+
text-decoration: underline;
|
|
79
|
+
text-underline-offset: 2px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.boff-prose a:hover {
|
|
83
|
+
opacity: 0.8;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.boff-prose hr {
|
|
87
|
+
border: none;
|
|
88
|
+
height: 1px;
|
|
89
|
+
background-color: hsl(var(--border));
|
|
90
|
+
margin: 2rem 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.boff-prose blockquote {
|
|
94
|
+
border-left: 4px solid hsl(var(--border));
|
|
95
|
+
padding-left: 1rem;
|
|
96
|
+
margin: 1.5rem 0;
|
|
97
|
+
font-style: italic;
|
|
98
|
+
color: hsl(var(--muted-foreground));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.boff-prose strong {
|
|
102
|
+
font-weight: 700;
|
|
103
|
+
color: hsl(var(--foreground));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.boff-prose code {
|
|
107
|
+
background-color: hsl(var(--muted));
|
|
108
|
+
padding: 0.125rem 0.25rem;
|
|
109
|
+
border-radius: 0.25rem;
|
|
110
|
+
font-size: 0.875em;
|
|
111
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.boff-prose pre {
|
|
115
|
+
background-color: hsl(var(--muted));
|
|
116
|
+
padding: 1rem;
|
|
117
|
+
border-radius: 0.5rem;
|
|
118
|
+
overflow-x: auto;
|
|
119
|
+
margin-bottom: 1rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.boff-prose pre code {
|
|
123
|
+
background-color: transparent;
|
|
124
|
+
padding: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.boff-prose img {
|
|
128
|
+
max-width: 100%;
|
|
129
|
+
height: auto;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.boff-prose table {
|
|
133
|
+
width: 100%;
|
|
134
|
+
border-collapse: collapse;
|
|
135
|
+
margin-bottom: 1rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.boff-prose th,
|
|
139
|
+
.boff-prose td {
|
|
140
|
+
border: 1px solid hsl(var(--border));
|
|
141
|
+
padding: 0.5rem;
|
|
142
|
+
text-align: left;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.boff-prose th {
|
|
146
|
+
font-weight: 600;
|
|
147
|
+
background-color: hsl(var(--muted));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Smaller variant used inside cards and compact panels */
|
|
151
|
+
.boff-prose-sm {
|
|
152
|
+
font-size: 0.875rem;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.boff-prose-sm h1 {
|
|
156
|
+
font-size: 1.75rem;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.boff-prose-sm h2 {
|
|
160
|
+
font-size: 1.5rem;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.boff-prose-sm h3 {
|
|
164
|
+
font-size: 1.25rem;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.boff-prose-sm h4 {
|
|
168
|
+
font-size: 1.125rem;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.boff-prose-sm p,
|
|
172
|
+
.boff-prose-sm li {
|
|
173
|
+
line-height: 1.625;
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
function ProseStyles() {
|
|
177
|
+
return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: PROSE_CSS } });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { ProseStyles };
|
|
181
|
+
//# sourceMappingURL=chunk-6VJT3SM4.mjs.map
|
|
182
|
+
//# sourceMappingURL=chunk-6VJT3SM4.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/content/prose-styles.tsx"],"names":[],"mappings":";;AAUO,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA8KlB,SAAS,WAAA,GAAc;AAC5B,EAAA,2BAAQ,OAAA,EAAA,EAAM,uBAAA,EAAyB,EAAE,MAAA,EAAQ,WAAU,EAAG,CAAA;AAChE","file":"chunk-6VJT3SM4.mjs","sourcesContent":["\"use client\";\n\n/**\n * Self-contained prose styles for SDK content renderers.\n *\n * These components inject a scoped `.boff-prose` stylesheet so markdown content\n * renders correctly even when the host website does not install\n * `@tailwindcss/typography` or define `.prose` CSS.\n */\n\nexport const PROSE_CSS = `\n.boff-prose {\n max-width: none;\n}\n\n.boff-prose h1 {\n font-size: 2.25rem;\n font-weight: 800;\n line-height: 1.2;\n margin-top: 0;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h2 {\n font-size: 1.75rem;\n font-weight: 700;\n line-height: 1.3;\n margin-top: 2rem;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h3 {\n font-size: 1.5rem;\n font-weight: 600;\n line-height: 1.4;\n margin-top: 1.5rem;\n margin-bottom: 0.75rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h4 {\n font-size: 1.25rem;\n font-weight: 600;\n line-height: 1.5;\n margin-top: 1.25rem;\n margin-bottom: 0.5rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose p {\n margin-bottom: 1rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose ul,\n.boff-prose ol {\n margin-bottom: 1rem;\n padding-left: 1.5rem;\n}\n\n.boff-prose ul {\n list-style-type: disc;\n}\n\n.boff-prose ol {\n list-style-type: decimal;\n}\n\n.boff-prose li {\n margin-bottom: 0.25rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose li > ul,\n.boff-prose li > ol {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n\n.boff-prose a {\n color: hsl(var(--primary));\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.boff-prose a:hover {\n opacity: 0.8;\n}\n\n.boff-prose hr {\n border: none;\n height: 1px;\n background-color: hsl(var(--border));\n margin: 2rem 0;\n}\n\n.boff-prose blockquote {\n border-left: 4px solid hsl(var(--border));\n padding-left: 1rem;\n margin: 1.5rem 0;\n font-style: italic;\n color: hsl(var(--muted-foreground));\n}\n\n.boff-prose strong {\n font-weight: 700;\n color: hsl(var(--foreground));\n}\n\n.boff-prose code {\n background-color: hsl(var(--muted));\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n font-size: 0.875em;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n.boff-prose pre {\n background-color: hsl(var(--muted));\n padding: 1rem;\n border-radius: 0.5rem;\n overflow-x: auto;\n margin-bottom: 1rem;\n}\n\n.boff-prose pre code {\n background-color: transparent;\n padding: 0;\n}\n\n.boff-prose img {\n max-width: 100%;\n height: auto;\n}\n\n.boff-prose table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 1rem;\n}\n\n.boff-prose th,\n.boff-prose td {\n border: 1px solid hsl(var(--border));\n padding: 0.5rem;\n text-align: left;\n}\n\n.boff-prose th {\n font-weight: 600;\n background-color: hsl(var(--muted));\n}\n\n/* Smaller variant used inside cards and compact panels */\n.boff-prose-sm {\n font-size: 0.875rem;\n}\n\n.boff-prose-sm h1 {\n font-size: 1.75rem;\n}\n\n.boff-prose-sm h2 {\n font-size: 1.5rem;\n}\n\n.boff-prose-sm h3 {\n font-size: 1.25rem;\n}\n\n.boff-prose-sm h4 {\n font-size: 1.125rem;\n}\n\n.boff-prose-sm p,\n.boff-prose-sm li {\n line-height: 1.625;\n}\n`;\n\nexport function ProseStyles() {\n return <style dangerouslySetInnerHTML={{ __html: PROSE_CSS }} />;\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/analytics/events.ts
|
|
2
|
+
var MAX_PROPERTY_LENGTH = 64;
|
|
3
|
+
var EMAIL_LIKE = /[^\s@]+@[^\s@]+/;
|
|
4
|
+
function sanitizeWebsiteEventProperties(properties) {
|
|
5
|
+
const safe = {};
|
|
6
|
+
if (!properties) return safe;
|
|
7
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
8
|
+
if (typeof value === "boolean") {
|
|
9
|
+
safe[key] = value;
|
|
10
|
+
} else if (typeof value === "number") {
|
|
11
|
+
if (Number.isFinite(value)) safe[key] = value;
|
|
12
|
+
} else if (typeof value === "string") {
|
|
13
|
+
const trimmed = value.trim();
|
|
14
|
+
if (trimmed.length > 0 && trimmed.length <= MAX_PROPERTY_LENGTH && !EMAIL_LIKE.test(trimmed)) {
|
|
15
|
+
safe[key] = trimmed;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return safe;
|
|
20
|
+
}
|
|
21
|
+
function trackWebsiteEvent(name, properties) {
|
|
22
|
+
if (typeof window === "undefined") return false;
|
|
23
|
+
try {
|
|
24
|
+
const rybbit = window.rybbit;
|
|
25
|
+
if (typeof rybbit?.event !== "function") return false;
|
|
26
|
+
const safe = sanitizeWebsiteEventProperties(properties);
|
|
27
|
+
if (Object.keys(safe).length > 0) {
|
|
28
|
+
rybbit.event(name, safe);
|
|
29
|
+
} else {
|
|
30
|
+
rybbit.event(name);
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { MAX_PROPERTY_LENGTH, sanitizeWebsiteEventProperties, trackWebsiteEvent };
|
|
39
|
+
//# sourceMappingURL=chunk-6YZUFMK2.mjs.map
|
|
40
|
+
//# sourceMappingURL=chunk-6YZUFMK2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analytics/events.ts"],"names":[],"mappings":";AAqCO,IAAM,mBAAA,GAAsB;AAEnC,IAAM,UAAA,GAAa,iBAAA;AAKZ,SAAS,+BACd,UAAA,EACwB;AACxB,EAAA,MAAM,OAA+B,EAAC;AACtC,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AACxB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,IAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAAA,IACd,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,EAAU;AACpC,MAAA,IAAI,OAAO,QAAA,CAAS,KAAK,CAAA,EAAG,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAAA,IAC1C,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,EAAU;AACpC,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,MAAA,IACE,OAAA,CAAQ,MAAA,GAAS,CAAA,IACjB,OAAA,CAAQ,MAAA,IAAU,uBAClB,CAAC,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA,EACxB;AACA,QAAA,IAAA,CAAK,GAAG,CAAA,GAAI,OAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAMO,SAAS,iBAAA,CACd,MACA,UAAA,EACS;AACT,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAQ,KAAA,KAAU,UAAA,EAAY,OAAO,KAAA;AAChD,IAAA,MAAM,IAAA,GAAO,+BAA+B,UAAU,CAAA;AACtD,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AAChC,MAAA,MAAA,CAAO,KAAA,CAAM,MAAM,IAAI,CAAA;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-6YZUFMK2.mjs","sourcesContent":["/**\n * Website analytics events (Rybbit custom events).\n *\n * Product websites load the Rybbit script, which records pageviews on its own.\n * Funnel facts that are not a pageview (for example a successful waitlist\n * signup) are sent through `trackWebsiteEvent`, which calls `window.rybbit.event`\n * when the script is present and does nothing otherwise.\n *\n * Privacy rules (BOFF-3167):\n * - Event names come from the closed `WebsiteEventName` union.\n * - Properties are short, low-cardinality strings, numbers or booleans. Strings\n * longer than `MAX_PROPERTY_LENGTH`, values that look like an email address,\n * and any other value type are dropped, so a caller cannot leak an email,\n * name or free text into the analytics provider by mistake.\n * - Tracking never throws: analytics must not break a signup.\n */\n\n/** Custom events product websites emit. */\nexport type WebsiteEventName = \"waitlist.signed_up\";\n\nexport type WebsiteEventPropertyValue = string | number | boolean;\n\nexport type WebsiteEventProperties = Record<string, WebsiteEventPropertyValue>;\n\ndeclare global {\n interface Window {\n /** Set by the Rybbit tracking script (https://app.rybbit.io/api/script.js). */\n rybbit?: {\n event?: (\n name: string,\n properties?: Record<string, WebsiteEventPropertyValue>,\n ) => void;\n };\n }\n}\n\n/** Longest string property value that is forwarded. */\nexport const MAX_PROPERTY_LENGTH = 64;\n\nconst EMAIL_LIKE = /[^\\s@]+@[^\\s@]+/;\n\n/**\n * Keeps only short, non-identifying primitive values. Exported for tests.\n */\nexport function sanitizeWebsiteEventProperties(\n properties: WebsiteEventProperties | undefined,\n): WebsiteEventProperties {\n const safe: WebsiteEventProperties = {};\n if (!properties) return safe;\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === \"boolean\") {\n safe[key] = value;\n } else if (typeof value === \"number\") {\n if (Number.isFinite(value)) safe[key] = value;\n } else if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (\n trimmed.length > 0 &&\n trimmed.length <= MAX_PROPERTY_LENGTH &&\n !EMAIL_LIKE.test(trimmed)\n ) {\n safe[key] = trimmed;\n }\n }\n }\n return safe;\n}\n\n/**\n * Sends a custom event to Rybbit when the tracking script is loaded.\n * Returns true when the event was handed to Rybbit.\n */\nexport function trackWebsiteEvent(\n name: WebsiteEventName,\n properties?: WebsiteEventProperties,\n): boolean {\n if (typeof window === \"undefined\") return false;\n try {\n const rybbit = window.rybbit;\n if (typeof rybbit?.event !== \"function\") return false;\n const safe = sanitizeWebsiteEventProperties(properties);\n if (Object.keys(safe).length > 0) {\n rybbit.event(name, safe);\n } else {\n rybbit.event(name);\n }\n return true;\n } catch {\n // Analytics is best-effort and must never break the page.\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkC6OJIHNO_js = require('./chunk-C6OJIHNO.js');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
|
+
|
|
27
|
+
var Input = React__namespace.forwardRef(
|
|
28
|
+
({ className, type, ...props }, ref) => {
|
|
29
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30
|
+
"input",
|
|
31
|
+
{
|
|
32
|
+
type,
|
|
33
|
+
className: chunkC6OJIHNO_js.cn(
|
|
34
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
35
|
+
className
|
|
36
|
+
),
|
|
37
|
+
ref,
|
|
38
|
+
...props
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
Input.displayName = "Input";
|
|
44
|
+
|
|
45
|
+
exports.Input = Input;
|
|
46
|
+
//# sourceMappingURL=chunk-7A6R7CGG.js.map
|
|
47
|
+
//# sourceMappingURL=chunk-7A6R7CGG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/input.tsx"],"names":["React","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAM,KAAA,GAAcA,gBAAA,CAAA,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACtC,IAAA,uBACEC,cAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA,EAAWC,mBAAA;AAAA,UACT,yWAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-7A6R7CGG.js","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-7PWL4V2R.js"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk7A6R7CGG_js = require('./chunk-7A6R7CGG.js');
|
|
4
|
+
var chunkC6OJIHNO_js = require('./chunk-C6OJIHNO.js');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var DropdownMenu = require('@radix-ui/react-dropdown-menu');
|
|
7
|
+
var lucideReact = require('lucide-react');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
function _interopNamespace(e) {
|
|
11
|
+
if (e && e.__esModule) return e;
|
|
12
|
+
var n = Object.create(null);
|
|
13
|
+
if (e) {
|
|
14
|
+
Object.keys(e).forEach(function (k) {
|
|
15
|
+
if (k !== 'default') {
|
|
16
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return e[k]; }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
n.default = e;
|
|
25
|
+
return Object.freeze(n);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
|
|
29
|
+
|
|
30
|
+
function normalizeSearch(value) {
|
|
31
|
+
return value.toLowerCase().trim();
|
|
32
|
+
}
|
|
33
|
+
function resolveWebsiteProductLogo(product) {
|
|
34
|
+
if (product.logoUrl) return product.logoUrl;
|
|
35
|
+
return `${product.websiteUrl.replace(/\/+$/, "")}/logo-icon.png`;
|
|
36
|
+
}
|
|
37
|
+
function filterProducts(products, query) {
|
|
38
|
+
const normalized = normalizeSearch(query);
|
|
39
|
+
if (!normalized) return products;
|
|
40
|
+
return products.filter((p) => normalizeSearch(p.name).includes(normalized));
|
|
41
|
+
}
|
|
42
|
+
function WebsiteSwitcher({
|
|
43
|
+
products,
|
|
44
|
+
triggerLabel = "Explore products",
|
|
45
|
+
searchPlaceholder = "Find a product\u2026",
|
|
46
|
+
emptyText = "No products match your search.",
|
|
47
|
+
className
|
|
48
|
+
}) {
|
|
49
|
+
const [open, setOpen] = react.useState(false);
|
|
50
|
+
const [query, setQuery] = react.useState("");
|
|
51
|
+
const [failedLogos, setFailedLogos] = react.useState(
|
|
52
|
+
() => /* @__PURE__ */ new Set()
|
|
53
|
+
);
|
|
54
|
+
const filtered = react.useMemo(
|
|
55
|
+
() => filterProducts(products, query),
|
|
56
|
+
[products, query]
|
|
57
|
+
);
|
|
58
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
60
|
+
DropdownMenu__namespace.Trigger,
|
|
61
|
+
{
|
|
62
|
+
className: chunkC6OJIHNO_js.cn(
|
|
63
|
+
"inline-flex items-center gap-1.5 text-sm font-medium transition-colors",
|
|
64
|
+
"text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-md",
|
|
65
|
+
className
|
|
66
|
+
),
|
|
67
|
+
"aria-label": triggerLabel,
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
70
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: triggerLabel }),
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
72
|
+
lucideReact.ChevronDown,
|
|
73
|
+
{
|
|
74
|
+
className: chunkC6OJIHNO_js.cn(
|
|
75
|
+
"h-3.5 w-3.5 transition-transform duration-200",
|
|
76
|
+
open && "rotate-180"
|
|
77
|
+
),
|
|
78
|
+
"aria-hidden": "true"
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
85
|
+
DropdownMenu__namespace.Content,
|
|
86
|
+
{
|
|
87
|
+
className: "z-50 min-w-[16rem] max-w-[20rem] rounded-lg border border-border/60 bg-popover p-2 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2",
|
|
88
|
+
sideOffset: 8,
|
|
89
|
+
align: "end",
|
|
90
|
+
avoidCollisions: true,
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-2 pb-2 pt-1", children: [
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Burdenoff ecosystem" }),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
96
|
+
lucideReact.Search,
|
|
97
|
+
{
|
|
98
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground",
|
|
99
|
+
"aria-hidden": "true"
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
103
|
+
chunk7A6R7CGG_js.Input,
|
|
104
|
+
{
|
|
105
|
+
type: "search",
|
|
106
|
+
value: query,
|
|
107
|
+
onChange: (e) => setQuery(e.target.value),
|
|
108
|
+
placeholder: searchPlaceholder,
|
|
109
|
+
className: "h-8 pl-8 text-sm",
|
|
110
|
+
"aria-label": searchPlaceholder,
|
|
111
|
+
onKeyDown: (e) => {
|
|
112
|
+
if (e.key === "Escape") {
|
|
113
|
+
setQuery("");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
] })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border/60" }),
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[min(60vh,24rem)] overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filtered.map((product) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Item, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
122
|
+
"a",
|
|
123
|
+
{
|
|
124
|
+
href: product.websiteUrl,
|
|
125
|
+
target: "_blank",
|
|
126
|
+
rel: "noopener noreferrer",
|
|
127
|
+
className: chunkC6OJIHNO_js.cn(
|
|
128
|
+
"flex items-center gap-3 rounded-md px-2 py-2 text-sm outline-none",
|
|
129
|
+
"text-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
|
|
130
|
+
),
|
|
131
|
+
children: [
|
|
132
|
+
failedLogos.has(product.slug) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded bg-primary/10 text-[10px] font-bold text-primary", children: product.name.charAt(0) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
"img",
|
|
134
|
+
{
|
|
135
|
+
src: resolveWebsiteProductLogo(product),
|
|
136
|
+
alt: "",
|
|
137
|
+
"aria-hidden": "true",
|
|
138
|
+
loading: "lazy",
|
|
139
|
+
className: "h-5 w-5 shrink-0 rounded object-contain",
|
|
140
|
+
onError: () => setFailedLogos((prev) => {
|
|
141
|
+
const next = new Set(prev);
|
|
142
|
+
next.add(product.slug);
|
|
143
|
+
return next;
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: product.name })
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
) }, product.slug)) }),
|
|
151
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Arrow, { className: "fill-popover" })
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
) })
|
|
155
|
+
] });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
exports.WebsiteSwitcher = WebsiteSwitcher;
|
|
159
|
+
exports.resolveWebsiteProductLogo = resolveWebsiteProductLogo;
|
|
160
|
+
//# sourceMappingURL=chunk-AA33WDYS.js.map
|
|
161
|
+
//# sourceMappingURL=chunk-AA33WDYS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/website-switcher.tsx"],"names":["useState","useMemo","jsxs","DropdownMenu","cn","jsx","Globe","ChevronDown","Search","Input"],"mappings":"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","file":"chunk-AA33WDYS.js","sourcesContent":["\"use client\";\n\n/**\n * WebsiteSwitcher Component\n *\n * A dropdown menu for navigating between Burdenoff ecosystem product websites.\n * Includes a search filter and renders each product with its logo and name.\n *\n * @example\n * ```tsx\n * import { WebsiteSwitcher } from '@burdenoff/website-sdk'\n *\n * <WebsiteSwitcher\n * products={[\n * { slug: 'vibecontrols', name: 'VibeControls', logoUrl: '/vibe.svg', websiteUrl: 'https://vibecontrols.com' },\n * { slug: 'fluidgrids', name: 'FluidGrids', logoUrl: '/fg.svg', websiteUrl: 'https://fluidgrids.com' },\n * ]}\n * />\n * ```\n */\n\nimport { useMemo, useState } from \"react\";\n\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { ChevronDown, Globe, Search } from \"lucide-react\";\n\nimport { Input } from \"../ui/input\";\nimport { cn } from \"../utils/cn\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WebsiteSwitcherProduct {\n /** Stable identifier for the product. */\n slug: string;\n /** Human-readable product name. */\n name: string;\n /** URL to the product logo (absolute or relative). */\n logoUrl?: string | null;\n /** Product marketing site URL. */\n websiteUrl: string;\n}\n\nexport interface WebsiteSwitcherProps {\n /** All Burdenoff ecosystem products to display. */\n products: WebsiteSwitcherProduct[];\n /** Accessible label for the trigger. */\n triggerLabel?: string;\n /** Placeholder text for the search input. */\n searchPlaceholder?: string;\n /** Empty-state text when filtering returns no results. */\n emptyText?: string;\n /** Optional additional CSS class for the trigger. */\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeSearch(value: string): string {\n return value.toLowerCase().trim();\n}\n\n/**\n * Resolve the logo URL for an ecosystem product.\n *\n * Prefers an explicit `logoUrl`; otherwise derives the canonical marketing-site\n * brand mark (`/logo-icon.png`), which every product website publishes. Callers\n * should fall back to the initial chip if the image fails to load.\n */\nexport function resolveWebsiteProductLogo(\n product: WebsiteSwitcherProduct,\n): string {\n if (product.logoUrl) return product.logoUrl;\n return `${product.websiteUrl.replace(/\\/+$/, \"\")}/logo-icon.png`;\n}\n\nfunction filterProducts(\n products: WebsiteSwitcherProduct[],\n query: string,\n): WebsiteSwitcherProduct[] {\n const normalized = normalizeSearch(query);\n if (!normalized) return products;\n return products.filter((p) => normalizeSearch(p.name).includes(normalized));\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function WebsiteSwitcher({\n products,\n triggerLabel = \"Explore products\",\n searchPlaceholder = \"Find a product…\",\n emptyText = \"No products match your search.\",\n className,\n}: WebsiteSwitcherProps) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n // Slugs whose logo image failed to load — fall back to the initial chip.\n const [failedLogos, setFailedLogos] = useState<ReadonlySet<string>>(\n () => new Set<string>(),\n );\n\n const filtered = useMemo(\n () => filterProducts(products, query),\n [products, query],\n );\n\n return (\n <DropdownMenu.Root open={open} onOpenChange={setOpen}>\n <DropdownMenu.Trigger\n className={cn(\n \"inline-flex items-center gap-1.5 text-sm font-medium transition-colors\",\n \"text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-md\",\n className,\n )}\n aria-label={triggerLabel}\n >\n <Globe className=\"h-4 w-4\" aria-hidden=\"true\" />\n <span className=\"hidden sm:inline\">{triggerLabel}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n aria-hidden=\"true\"\n />\n </DropdownMenu.Trigger>\n\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 min-w-[16rem] max-w-[20rem] rounded-lg border border-border/60 bg-popover p-2 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2\"\n sideOffset={8}\n align=\"end\"\n avoidCollisions\n >\n <div className=\"px-2 pb-2 pt-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Burdenoff ecosystem\n </p>\n <div className=\"relative\">\n <Search\n className=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <Input\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={searchPlaceholder}\n className=\"h-8 pl-8 text-sm\"\n aria-label={searchPlaceholder}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setQuery(\"\");\n }\n }}\n />\n </div>\n </div>\n\n <DropdownMenu.Separator className=\"my-1 h-px bg-border/60\" />\n\n <div className=\"max-h-[min(60vh,24rem)] overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <div className=\"px-3 py-4 text-center text-sm text-muted-foreground\">\n {emptyText}\n </div>\n ) : (\n filtered.map((product) => (\n <DropdownMenu.Item key={product.slug} asChild>\n <a\n href={product.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n \"flex items-center gap-3 rounded-md px-2 py-2 text-sm outline-none\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\",\n )}\n >\n {failedLogos.has(product.slug) ? (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded bg-primary/10 text-[10px] font-bold text-primary\">\n {product.name.charAt(0)}\n </span>\n ) : (\n <img\n src={resolveWebsiteProductLogo(product)}\n alt=\"\"\n aria-hidden=\"true\"\n loading=\"lazy\"\n className=\"h-5 w-5 shrink-0 rounded object-contain\"\n onError={() =>\n setFailedLogos((prev) => {\n const next = new Set(prev);\n next.add(product.slug);\n return next;\n })\n }\n />\n )}\n <span className=\"truncate\">{product.name}</span>\n </a>\n </DropdownMenu.Item>\n ))\n )}\n </div>\n\n <DropdownMenu.Arrow className=\"fill-popover\" />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n}\n"]}
|