@sonordev/site-kit 4.0.1 → 4.1.0
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/agent-manifest.json +6 -1
- package/dist/AnalyticsProvider-G5P5RQOA.js +31 -0
- package/dist/{AnalyticsProvider-UE34SYF2.js.map → AnalyticsProvider-G5P5RQOA.js.map} +1 -1
- package/dist/AnalyticsProvider-NGQLQL5N.mjs +10 -0
- package/dist/{AnalyticsProvider-NSXC6IOO.mjs.map → AnalyticsProvider-NGQLQL5N.mjs.map} +1 -1
- package/dist/ChatWidget-AYKZBKJH.js +20 -0
- package/dist/{ChatWidget-OW37OU3Z.js.map → ChatWidget-AYKZBKJH.js.map} +1 -1
- package/dist/ChatWidget-LPFHRK7U.mjs +11 -0
- package/dist/{ChatWidget-ASWCGCJJ.mjs.map → ChatWidget-LPFHRK7U.mjs.map} +1 -1
- package/dist/DatePicker-4WNKNNCV.mjs +4 -0
- package/dist/DatePicker-4WNKNNCV.mjs.map +1 -0
- package/dist/DatePicker-VPZR7RU3.js +13 -0
- package/dist/DatePicker-VPZR7RU3.js.map +1 -0
- package/dist/EngageWidget-HKPAJAMR.js +18 -0
- package/dist/{EngageWidget-MXOCMVBQ.js.map → EngageWidget-HKPAJAMR.js.map} +1 -1
- package/dist/EngageWidget-KDE7BYAK.mjs +9 -0
- package/dist/{EngageWidget-67UZ3P5P.mjs.map → EngageWidget-KDE7BYAK.mjs.map} +1 -1
- package/dist/FileField-DDDNSRMR.js +91 -0
- package/dist/FileField-DDDNSRMR.js.map +1 -0
- package/dist/FileField-SU4HTY4F.mjs +85 -0
- package/dist/FileField-SU4HTY4F.mjs.map +1 -0
- package/dist/{FormSpotlight-6MXGX6TU.mjs → FormSpotlight-B6TJPNYN.mjs} +7 -6
- package/dist/FormSpotlight-B6TJPNYN.mjs.map +1 -0
- package/dist/{FormSpotlight-LOR57ENP.js → FormSpotlight-M4S57VC6.js} +20 -19
- package/dist/FormSpotlight-M4S57VC6.js.map +1 -0
- package/dist/{FormStage-H35FBWTX.js → FormStage-2ASJGNOX.js} +16 -16
- package/dist/FormStage-2ASJGNOX.js.map +1 -0
- package/dist/{FormStage-ZLZD5EW4.mjs → FormStage-GH7SA6FQ.mjs} +6 -6
- package/dist/FormStage-GH7SA6FQ.mjs.map +1 -0
- package/dist/ManagedForm-D2JT3QV3.js +23 -0
- package/dist/ManagedForm-D2JT3QV3.js.map +1 -0
- package/dist/ManagedForm-RCC7NEV2.mjs +14 -0
- package/dist/ManagedForm-RCC7NEV2.mjs.map +1 -0
- package/dist/{SignalCore-HEXXYFSX.mjs → SignalCore-36PY3SRB.mjs} +5 -5
- package/dist/{SignalCore-HEXXYFSX.mjs.map → SignalCore-36PY3SRB.mjs.map} +1 -1
- package/dist/{SignalCore-EUMJIPDK.js → SignalCore-7H4ZGFZO.js} +11 -11
- package/dist/{SignalCore-EUMJIPDK.js.map → SignalCore-7H4ZGFZO.js.map} +1 -1
- package/dist/SitemapSync-AYVBNCH4.js +17 -0
- package/dist/{SitemapSync-HKUEDDG6.js.map → SitemapSync-AYVBNCH4.js.map} +1 -1
- package/dist/SitemapSync-HKAG3JU3.mjs +8 -0
- package/dist/{SitemapSync-T4QDPMFG.mjs.map → SitemapSync-HKAG3JU3.mjs.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- package/dist/{chunk-ZGQUIL7L.js → chunk-2ACKOMAL.js} +105 -514
- package/dist/chunk-2ACKOMAL.js.map +1 -0
- package/dist/{chunk-52K556WM.js → chunk-2IH5FM2A.js} +14 -14
- package/dist/{chunk-52K556WM.js.map → chunk-2IH5FM2A.js.map} +1 -1
- package/dist/{chunk-PVE6G5XQ.mjs → chunk-2RJ5UHAC.mjs} +3 -3
- package/dist/{chunk-PVE6G5XQ.mjs.map → chunk-2RJ5UHAC.mjs.map} +1 -1
- package/dist/{chunk-VL2WAC22.js → chunk-3GJBSUVS.js} +14 -14
- package/dist/{chunk-VL2WAC22.js.map → chunk-3GJBSUVS.js.map} +1 -1
- package/dist/chunk-4ROQDPUE.mjs +60 -0
- package/dist/chunk-4ROQDPUE.mjs.map +1 -0
- package/dist/{chunk-4JEJTQYC.mjs → chunk-5GAOZTMW.mjs} +3 -3
- package/dist/{chunk-4JEJTQYC.mjs.map → chunk-5GAOZTMW.mjs.map} +1 -1
- package/dist/{chunk-NU5DJUVI.js → chunk-5JFJJNWS.js} +12 -192
- package/dist/chunk-5JFJJNWS.js.map +1 -0
- package/dist/{chunk-JGTIVQIN.mjs → chunk-7CYSA5EN.mjs} +3 -3
- package/dist/{chunk-JGTIVQIN.mjs.map → chunk-7CYSA5EN.mjs.map} +1 -1
- package/dist/{chunk-CTZHLX2B.mjs → chunk-7JES77WC.mjs} +5 -182
- package/dist/chunk-7JES77WC.mjs.map +1 -0
- package/dist/{chunk-DG34TZ6T.mjs → chunk-A4E6EOU4.mjs} +5 -5
- package/dist/{chunk-DG34TZ6T.mjs.map → chunk-A4E6EOU4.mjs.map} +1 -1
- package/dist/{chunk-YNIZKOEW.js → chunk-A624YYDG.js} +2 -2
- package/dist/{chunk-YNIZKOEW.js.map → chunk-A624YYDG.js.map} +1 -1
- package/dist/chunk-ANTVZSQI.mjs +183 -0
- package/dist/chunk-ANTVZSQI.mjs.map +1 -0
- package/dist/{chunk-2LKWN26R.mjs → chunk-D7IY27X5.mjs} +3 -3
- package/dist/{chunk-2LKWN26R.mjs.map → chunk-D7IY27X5.mjs.map} +1 -1
- package/dist/{chunk-QXIVUWQZ.js → chunk-DAGLPS6P.js} +8 -8
- package/dist/{chunk-QXIVUWQZ.js.map → chunk-DAGLPS6P.js.map} +1 -1
- package/dist/{chunk-XAMUTD4I.mjs → chunk-DBZU2TRZ.mjs} +3 -3
- package/dist/{chunk-XAMUTD4I.mjs.map → chunk-DBZU2TRZ.mjs.map} +1 -1
- package/dist/{chunk-I424AZPT.js → chunk-DCITIONV.js} +4 -4
- package/dist/{chunk-I424AZPT.js.map → chunk-DCITIONV.js.map} +1 -1
- package/dist/chunk-DVYYGHSG.js +285 -0
- package/dist/chunk-DVYYGHSG.js.map +1 -0
- package/dist/{chunk-62QRWS2I.mjs → chunk-FJ5EMPCK.mjs} +8 -8
- package/dist/{chunk-62QRWS2I.mjs.map → chunk-FJ5EMPCK.mjs.map} +1 -1
- package/dist/{chunk-6SHBMFYM.mjs → chunk-FNOCLT4A.mjs} +3 -3
- package/dist/{chunk-6SHBMFYM.mjs.map → chunk-FNOCLT4A.mjs.map} +1 -1
- package/dist/chunk-FQ4BDJXG.js +46 -0
- package/dist/chunk-FQ4BDJXG.js.map +1 -0
- package/dist/{chunk-EDFZ6EMM.js → chunk-FYPA5GLS.js} +15 -15
- package/dist/{chunk-EDFZ6EMM.js.map → chunk-FYPA5GLS.js.map} +1 -1
- package/dist/chunk-G7IMEY5T.mjs +44 -0
- package/dist/chunk-G7IMEY5T.mjs.map +1 -0
- package/dist/chunk-GJVC7KKL.mjs +508 -0
- package/dist/chunk-GJVC7KKL.mjs.map +1 -0
- package/dist/{chunk-Q7HLRTZA.js → chunk-HK33JRWA.js} +16 -16
- package/dist/{chunk-Q7HLRTZA.js.map → chunk-HK33JRWA.js.map} +1 -1
- package/dist/{chunk-ARBOKZAU.mjs → chunk-IUZ2RH4V.mjs} +3 -4
- package/dist/chunk-IUZ2RH4V.mjs.map +1 -0
- package/dist/{chunk-62RQTXHX.js → chunk-L6WWNP2N.js} +5 -5
- package/dist/{chunk-62RQTXHX.js.map → chunk-L6WWNP2N.js.map} +1 -1
- package/dist/chunk-LAWESLXJ.js +511 -0
- package/dist/chunk-LAWESLXJ.js.map +1 -0
- package/dist/{chunk-LYDTOFXJ.mjs → chunk-LB7LHVWI.mjs} +107 -503
- package/dist/chunk-LB7LHVWI.mjs.map +1 -0
- package/dist/{chunk-OIBQYBEL.mjs → chunk-LMKDQCU7.mjs} +3 -3
- package/dist/{chunk-OIBQYBEL.mjs.map → chunk-LMKDQCU7.mjs.map} +1 -1
- package/dist/{chunk-RZW4XVG5.js → chunk-LRHECSZK.js} +14 -14
- package/dist/{chunk-RZW4XVG5.js.map → chunk-LRHECSZK.js.map} +1 -1
- package/dist/{chunk-L5Q2ZJJM.js → chunk-MKQZVTD3.js} +6 -6
- package/dist/{chunk-L5Q2ZJJM.js.map → chunk-MKQZVTD3.js.map} +1 -1
- package/dist/chunk-MU3D5IO7.mjs +283 -0
- package/dist/chunk-MU3D5IO7.mjs.map +1 -0
- package/dist/{chunk-Z74IVGJB.mjs → chunk-MXPGAJLM.mjs} +4 -4
- package/dist/{chunk-Z74IVGJB.mjs.map → chunk-MXPGAJLM.mjs.map} +1 -1
- package/dist/{chunk-7QDTXT4N.js → chunk-NF3QVKWU.js} +6 -7
- package/dist/chunk-NF3QVKWU.js.map +1 -0
- package/dist/chunk-NSIRG3C3.js +148 -0
- package/dist/chunk-NSIRG3C3.js.map +1 -0
- package/dist/{chunk-WHGVQJG4.js → chunk-NTFLRRTQ.js} +8 -8
- package/dist/{chunk-WHGVQJG4.js.map → chunk-NTFLRRTQ.js.map} +1 -1
- package/dist/{chunk-NDB7EIOI.js → chunk-O554YMPI.js} +3 -3
- package/dist/{chunk-NDB7EIOI.js.map → chunk-O554YMPI.js.map} +1 -1
- package/dist/chunk-PKCEJWLD.mjs +6 -0
- package/dist/{chunk-6GFEJH4F.mjs.map → chunk-PKCEJWLD.mjs.map} +1 -1
- package/dist/{chunk-MJY7LYOV.mjs → chunk-QYLGVXRX.mjs} +4 -4
- package/dist/{chunk-MJY7LYOV.mjs.map → chunk-QYLGVXRX.mjs.map} +1 -1
- package/dist/chunk-R35CW6MM.js +8 -0
- package/dist/{chunk-34WY5XN2.js.map → chunk-R35CW6MM.js.map} +1 -1
- package/dist/chunk-S4U44UUD.mjs +138 -0
- package/dist/chunk-S4U44UUD.mjs.map +1 -0
- package/dist/{chunk-LDRE2ELU.js → chunk-SEH2K6NG.js} +12 -12
- package/dist/{chunk-LDRE2ELU.js.map → chunk-SEH2K6NG.js.map} +1 -1
- package/dist/chunk-TH2ANDPK.mjs +104 -0
- package/dist/chunk-TH2ANDPK.mjs.map +1 -0
- package/dist/{chunk-KHJYA64F.mjs → chunk-U2CJZ6O5.mjs} +2 -2
- package/dist/{chunk-KHJYA64F.mjs.map → chunk-U2CJZ6O5.mjs.map} +1 -1
- package/dist/{chunk-5GPFPMDQ.mjs → chunk-UDHQNYBD.mjs} +4 -4
- package/dist/{chunk-5GPFPMDQ.mjs.map → chunk-UDHQNYBD.mjs.map} +1 -1
- package/dist/chunk-UTANIZUO.js +110 -0
- package/dist/chunk-UTANIZUO.js.map +1 -0
- package/dist/{chunk-QABZPSHD.js → chunk-VJAUA77N.js} +5 -5
- package/dist/{chunk-QABZPSHD.js.map → chunk-VJAUA77N.js.map} +1 -1
- package/dist/{chunk-CBUK2XB3.js → chunk-VOYLJCHB.js} +9 -9
- package/dist/{chunk-CBUK2XB3.js.map → chunk-VOYLJCHB.js.map} +1 -1
- package/dist/{chunk-XCCW4Y3B.mjs → chunk-VPBLW4ZN.mjs} +5 -5
- package/dist/{chunk-XCCW4Y3B.mjs.map → chunk-VPBLW4ZN.mjs.map} +1 -1
- package/dist/{chunk-6535RSF5.mjs → chunk-WJJQWAG2.mjs} +3 -3
- package/dist/{chunk-6535RSF5.mjs.map → chunk-WJJQWAG2.mjs.map} +1 -1
- package/dist/chunk-WNUUVBD7.js +64 -0
- package/dist/chunk-WNUUVBD7.js.map +1 -0
- package/dist/{chunk-DPTNQVMK.mjs → chunk-XCCMVJUA.mjs} +3 -3
- package/dist/{chunk-DPTNQVMK.mjs.map → chunk-XCCMVJUA.mjs.map} +1 -1
- package/dist/chunk-XRQ47XDA.js +188 -0
- package/dist/chunk-XRQ47XDA.js.map +1 -0
- package/dist/{chunk-YGWWLTH5.js → chunk-ZDXGB3UC.js} +4 -4
- package/dist/{chunk-YGWWLTH5.js.map → chunk-ZDXGB3UC.js.map} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.mjs +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.mjs +4 -4
- package/dist/cms/index.d.ts +23 -0
- package/dist/cms/index.d.ts.map +1 -1
- package/dist/cms/index.js +2 -2
- package/dist/cms/index.mjs +1 -1
- package/dist/cms/server-api.d.ts.map +1 -1
- package/dist/cms/server.js +4 -4
- package/dist/cms/server.mjs +1 -1
- package/dist/commerce/index.js +56 -56
- package/dist/commerce/index.mjs +5 -5
- package/dist/engage/EngageWidget.d.ts.map +1 -1
- package/dist/engage/dependency-contract.test.d.ts +2 -0
- package/dist/engage/dependency-contract.test.d.ts.map +1 -0
- package/dist/engage/index.js +10 -9
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +7 -6
- package/dist/engage/index.mjs.map +1 -1
- package/dist/engage/socket-loader.d.ts +13 -0
- package/dist/engage/socket-loader.d.ts.map +1 -1
- package/dist/fleet/index.js +9 -9
- package/dist/fleet/index.mjs +5 -5
- package/dist/forms/FileField.d.ts +31 -0
- package/dist/forms/FileField.d.ts.map +1 -0
- package/dist/forms/FormClient.d.ts +10 -1
- package/dist/forms/FormClient.d.ts.map +1 -1
- package/dist/forms/FormEnhancer.d.ts +72 -0
- package/dist/forms/FormEnhancer.d.ts.map +1 -0
- package/dist/forms/FormField.d.ts +26 -3
- package/dist/forms/FormField.d.ts.map +1 -1
- package/dist/forms/FormSpotlight.d.ts.map +1 -1
- package/dist/forms/FormStage.d.ts.map +1 -1
- package/dist/forms/HoneypotField.d.ts +8 -2
- package/dist/forms/HoneypotField.d.ts.map +1 -1
- package/dist/forms/ManagedForm.d.ts +1 -1
- package/dist/forms/ManagedForm.d.ts.map +1 -1
- package/dist/forms/ServerForm.d.ts +73 -0
- package/dist/forms/ServerForm.d.ts.map +1 -0
- package/dist/forms/StaticForm.d.ts +50 -0
- package/dist/forms/StaticForm.d.ts.map +1 -0
- package/dist/forms/field-controls.d.ts +7 -0
- package/dist/forms/field-controls.d.ts.map +1 -0
- package/dist/forms/index.d.ts +7 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +33 -557
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +14 -550
- package/dist/forms/index.mjs.map +1 -1
- package/dist/forms/normalize-config.d.ts +18 -0
- package/dist/forms/normalize-config.d.ts.map +1 -0
- package/dist/forms/server.d.ts +5 -0
- package/dist/forms/server.d.ts.map +1 -1
- package/dist/forms/server.js +47 -0
- package/dist/forms/server.js.map +1 -1
- package/dist/forms/server.mjs +44 -1
- package/dist/forms/server.mjs.map +1 -1
- package/dist/forms/static-form.test.d.ts +2 -0
- package/dist/forms/static-form.test.d.ts.map +1 -0
- package/dist/forms/static.d.ts +17 -0
- package/dist/forms/static.d.ts.map +1 -0
- package/dist/forms/static.js +20 -0
- package/dist/forms/static.js.map +1 -0
- package/dist/forms/static.mjs +11 -0
- package/dist/forms/static.mjs.map +1 -0
- package/dist/forms/types.d.ts +7 -0
- package/dist/forms/types.d.ts.map +1 -1
- package/dist/forms/useForm.d.ts.map +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +109 -109
- package/dist/index.mjs +9 -9
- package/dist/layout/client.js +9 -9
- package/dist/layout/client.mjs +8 -8
- package/dist/layout/index.js +11 -11
- package/dist/layout/index.mjs +9 -9
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +14 -14
- package/dist/seo/index.mjs +6 -6
- package/dist/seo/server.js +5 -5
- package/dist/seo/server.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/build-entries.d.ts +6 -0
- package/dist/shared/build-entries.d.ts.map +1 -1
- package/dist/shared/no-cjs-require.test.d.ts +2 -0
- package/dist/shared/no-cjs-require.test.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/{socket-loader-YEAQZ3XC.js → socket-loader-2NYBMBFQ.js} +2 -2
- package/dist/socket-loader-2NYBMBFQ.js.map +1 -0
- package/dist/{socket-loader-JHNN2QK4.mjs → socket-loader-JA2DI2RT.mjs} +2 -2
- package/dist/socket-loader-JA2DI2RT.mjs.map +1 -0
- package/dist/sync/index.js +16 -16
- package/dist/sync/index.mjs +4 -4
- package/package.json +28 -11
- package/dist/AnalyticsProvider-NSXC6IOO.mjs +0 -10
- package/dist/AnalyticsProvider-UE34SYF2.js +0 -31
- package/dist/ChatWidget-ASWCGCJJ.mjs +0 -10
- package/dist/ChatWidget-OW37OU3Z.js +0 -19
- package/dist/EngageWidget-67UZ3P5P.mjs +0 -9
- package/dist/EngageWidget-MXOCMVBQ.js +0 -18
- package/dist/FormSpotlight-6MXGX6TU.mjs.map +0 -1
- package/dist/FormSpotlight-LOR57ENP.js.map +0 -1
- package/dist/FormStage-H35FBWTX.js.map +0 -1
- package/dist/FormStage-ZLZD5EW4.mjs.map +0 -1
- package/dist/SitemapSync-HKUEDDG6.js +0 -17
- package/dist/SitemapSync-T4QDPMFG.mjs +0 -8
- package/dist/chunk-34WY5XN2.js +0 -8
- package/dist/chunk-6GFEJH4F.mjs +0 -6
- package/dist/chunk-7QDTXT4N.js.map +0 -1
- package/dist/chunk-ARBOKZAU.mjs.map +0 -1
- package/dist/chunk-CTZHLX2B.mjs.map +0 -1
- package/dist/chunk-LYDTOFXJ.mjs.map +0 -1
- package/dist/chunk-NU5DJUVI.js.map +0 -1
- package/dist/chunk-ZGQUIL7L.js.map +0 -1
- package/dist/socket-loader-JHNN2QK4.mjs.map +0 -1
- package/dist/socket-loader-YEAQZ3XC.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/forms/delight.tsx","../src/forms/FormField.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-LB7LHVWI.mjs","sourcesContent":["'use client'\n\n/**\n * Form delight primitives — the interaction layer that makes filling a form\n * feel like progress instead of paperwork. Forms capture the lead; this is\n * conversion surface, not decoration.\n *\n * The bar: AAA-game onboarding. Nothing on screen is inert — the focused\n * field is lit, completing a field LOCKS IN, progress reads like a meter you\n * want to fill, and when the last requirement clears the submit button wakes\n * up. The arc: aura -> lock-in tick -> bar surges -> READY -> press start ->\n * celebration.\n *\n * - FieldValidTick: a check that draws itself the moment a field becomes\n * valid (touched + non-empty + no error), with a ripple ring. The field\n * wrap also flashes a one-shot lock-in ring via [data-sk-valid].\n * - FormMomentum: a fields-completed meter (not steps) — endowed progress;\n * people finish bars they've started. Live sheen, advance flash, leading-\n * edge spark, \"N of M\" label that flips to READY and charges the bar.\n * - [data-sk-ready] (set by FormClient when every required field validates\n * on the final step) wakes the submit button: pop, then breathing glow.\n *\n * Same construction rules as FormCelebration: zero deps, one deduped style\n * tag, data-sk-part on everything, --sk-primary theming, reduced-motion\n * collapses animation to instant states.\n *\n * Contrast guarantee: forms routinely live in sections painted with the\n * brand color itself, where pure --sk-primary chrome is invisible (found\n * live: fill rgb(173,29,37) on section rgb(173,29,37)). Everything here\n * mixes toward currentColor — the section's text color must contrast with\n * the section background, so the mix guarantees the chrome does too.\n */\n\nimport React from 'react'\n\nconst STYLE_ID = 'sk-delight-css'\n\nconst CSS = `\n/* Every frame must carry the centering translateY: the animation fills both\n directions, so a keyframe transform of scale() alone REPLACES the rule's\n translateY(-50%) and drops the tick half its height below center. */\n@keyframes sk-tick-in {\n 0% { transform: translateY(-50%) scale(.3); opacity: 0 }\n 70% { transform: translateY(-50%) scale(1.15) }\n 100% { transform: translateY(-50%) scale(1); opacity: 1 }\n}\n@keyframes sk-tick-draw { to { stroke-dashoffset: 0 } }\n@keyframes sk-tick-ring { 0% { transform: scale(.5); opacity: .7 } 100% { transform: scale(2.2); opacity: 0 } }\n@keyframes sk-lock-in { 0% { opacity: .85; transform: scale(.985) } 100% { opacity: 0; transform: scale(1.012) } }\n@keyframes sk-momentum-sheen { 0% { transform: translateX(-120%) } 100% { transform: translateX(360%) } }\n@keyframes sk-momentum-flash { 0% { opacity: .55 } 100% { opacity: 0 } }\n@keyframes sk-spark-pulse {\n 0%, 100% { box-shadow: 0 0 4px 1px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor) }\n 50% { box-shadow: 0 0 11px 2px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor) }\n}\n@keyframes sk-fill-charge {\n 0%, 100% { box-shadow: 0 0 5px 0 color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor) }\n 50% { box-shadow: 0 0 13px 2px color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor) }\n}\n@keyframes sk-label-pop { 0% { transform: scale(.8) } 60% { transform: scale(1.15) } 100% { transform: scale(1) } }\n@keyframes sk-btn-wake { 0% { transform: scale(1) } 40% { transform: scale(1.04) } 100% { transform: scale(1) } }\n@keyframes sk-btn-breathe {\n 0%, 100% { filter: drop-shadow(0 0 0 transparent) }\n 50% { filter: drop-shadow(0 0 9px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor)) }\n}\n@keyframes sk-submit-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .6 } }\n\n/* ---- Field: aura, lift, lock-in, tick ---- */\n/* Flex, not the default inline formatting context: an <input> is inline-block,\n so the wrapper would be a few px taller than the input (baseline descender\n gap) and the absolutely-centered tick would sit visibly low. */\n[data-sk-part=\"field-input-wrap\"] { display: flex; align-items: center; transition: transform .18s ease; }\n[data-sk-part=\"field-input-wrap\"]:focus-within { transform: translateY(-2px); }\n/* Focus aura — the active field is the lit one. Glow-only pseudo (its own\n box is transparent), so it never occludes the input. */\n[data-sk-part=\"field-input-wrap\"]::before {\n content: ''; position: absolute; inset: -3px;\n border-radius: calc(var(--sk-input-radius, 6px) + 3px);\n box-shadow: 0 0 16px color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor);\n opacity: 0; transition: opacity .25s ease; pointer-events: none;\n}\n[data-sk-part=\"field-input-wrap\"]:focus-within::before { opacity: .5; }\n/* One-shot lock-in ring when the field validates ([data-sk-valid] appears). */\n[data-sk-part=\"field-input-wrap\"]::after {\n content: ''; position: absolute; inset: 0;\n border-radius: var(--sk-input-radius, 6px);\n border: 2px solid color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n opacity: 0; pointer-events: none;\n}\n[data-sk-part=\"field-input-wrap\"][data-sk-valid=\"true\"]::after { animation: sk-lock-in .55s ease-out both; }\n.sk-tick {\n position: absolute; right: 10px; top: 50%; transform: translateY(-50%);\n width: 20px; height: 20px; border-radius: 50%;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n display: flex; align-items: center; justify-content: center;\n animation: sk-tick-in .28s cubic-bezier(.22,1.4,.36,1) both;\n pointer-events: none;\n}\n.sk-tick::after {\n content: ''; position: absolute; inset: 0; border-radius: 50%;\n border: 2px solid color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n animation: sk-tick-ring .55s ease-out .06s both;\n}\n.sk-tick path { stroke-dasharray: 14; stroke-dashoffset: 14; animation: sk-tick-draw .22s ease-out .12s forwards; }\n\n/* ---- Momentum meter ---- */\n.sk-momentum { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }\n.sk-momentum-track {\n flex: 1; position: relative; height: 8px; border-radius: 999px;\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n.sk-momentum-fill {\n position: relative; overflow: hidden;\n height: 100%; border-radius: 999px;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n transition: width .45s cubic-bezier(.22,1,.36,1);\n}\n/* Continuous sheen sweep — the bar reads as live, not static chrome. */\n.sk-momentum-fill::after {\n content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 45%;\n background: linear-gradient(105deg, transparent, rgba(255,255,255,.4), transparent);\n animation: sk-momentum-sheen 2.6s ease-in-out infinite;\n}\n/* One-shot white flash on each advance (keyed remount restarts it). */\n.sk-momentum-flash {\n position: absolute; inset: 0; border-radius: 999px;\n background: #fff; opacity: 0;\n animation: sk-momentum-flash .5s ease-out;\n}\n/* Leading-edge spark rides the fill tip. */\n.sk-momentum-spark {\n position: absolute; top: 50%; width: 10px; height: 10px; margin-top: -5px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor);\n animation: sk-spark-pulse 1.6s ease-in-out infinite;\n transition: left .45s cubic-bezier(.22,1,.36,1);\n pointer-events: none;\n}\n.sk-momentum[data-sk-momentum=\"0\"] .sk-momentum-spark { opacity: 0; }\n.sk-momentum-label {\n font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;\n opacity: .75; font-variant-numeric: tabular-nums; white-space: nowrap;\n}\n/* Charged state: every requirement met — bar glows, sheen accelerates,\n label flips to READY in brand. */\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill { animation: sk-fill-charge 1.8s ease-in-out infinite; }\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill::after { animation-duration: 1.4s; }\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-label {\n opacity: 1;\n color: color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor);\n animation: sk-label-pop .4s cubic-bezier(.22,1.4,.36,1);\n}\n\n/* ---- DatePicker: the calendar morphs out of its tile and morphs back in\n on selection (container-transform), and the picked date stamps in. ---- */\n@keyframes sk-cal-out { 0% { opacity: 0; transform: scale(.92) translateY(-8px) } 100% { opacity: 1; transform: scale(1) translateY(0) } }\n@keyframes sk-cal-in { 0% { opacity: 1; transform: scale(1) translateY(0) } 100% { opacity: 0; transform: scale(.94) translateY(-6px) } }\n@keyframes sk-cal-stamp { 0% { transform: scale(.9) } 60% { transform: scale(1.06) } 100% { transform: scale(1) } }\n.sk-datepicker__pop { transform-origin: top center; animation: sk-cal-out .28s cubic-bezier(.22,1.4,.36,1) both; }\n.sk-datepicker__pop[data-sk-closing=\"true\"] { animation: sk-cal-in .18s ease-in both; }\n.sk-datepicker__value--stamp { display: inline-block; animation: sk-cal-stamp .3s cubic-bezier(.22,1.4,.36,1); }\n\n/* ---- Submit: wake on ready, pulse while submitting ---- */\n.sk-form__btn--submit { transition: transform .12s ease; }\n.sk-form__btn--submit:active { transform: scale(.97); }\n[data-sk-ready=\"true\"] .sk-form__btn--submit {\n animation: sk-btn-wake .5s cubic-bezier(.22,1.4,.36,1),\n sk-btn-breathe 2.4s ease-in-out .5s infinite;\n}\n[data-sk-state=\"submitting\"] .sk-form__btn--submit { animation: sk-submit-pulse 1.1s ease-in-out infinite; }\n[data-sk-state=\"submitting\"] .sk-momentum-fill::after { animation-duration: .8s; }\n\n@media (prefers-reduced-motion: reduce) {\n .sk-datepicker__pop { animation: none }\n .sk-datepicker__pop[data-sk-closing=\"true\"] { animation: none }\n .sk-datepicker__value--stamp { animation: none }\n .sk-tick { animation: none }\n .sk-tick::after { animation: none; opacity: 0 }\n .sk-tick path { animation: none; stroke-dashoffset: 0 }\n [data-sk-part=\"field-input-wrap\"] { transition: none }\n [data-sk-part=\"field-input-wrap\"]:focus-within { transform: none }\n [data-sk-part=\"field-input-wrap\"]::before { transition: none }\n [data-sk-part=\"field-input-wrap\"][data-sk-valid=\"true\"]::after { animation: none }\n .sk-momentum-fill { transition: none }\n .sk-momentum-fill::after { animation: none; opacity: 0 }\n .sk-momentum-flash { animation: none }\n .sk-momentum-spark { animation: none; transition: none }\n .sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill { animation: none }\n .sk-momentum[data-sk-complete=\"true\"] .sk-momentum-label { animation: none }\n .sk-form__btn--submit { transition: none }\n [data-sk-ready=\"true\"] .sk-form__btn--submit { animation: none }\n [data-sk-state=\"submitting\"] .sk-form__btn--submit { animation: none }\n}\n`\n\nexport function DelightStyles() {\n return <style id={STYLE_ID} dangerouslySetInnerHTML={{ __html: CSS }} />\n}\n\n/** Draw-in check shown inside a field wrapper once the value validates. */\nexport function FieldValidTick() {\n return (\n <span className=\"sk-tick\" data-sk-part=\"field-valid-tick\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M3.5 8.5l3 3 6-6.5\"\n stroke=\"var(--sk-form-success-check, #fff)\"\n strokeWidth=\"2.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n )\n}\n\nexport interface FormMomentumProps {\n /** Completed required+visible fields. */\n done: number\n /** Total required+visible fields. */\n total: number\n}\n\n/**\n * Fields-completed meter. Hidden when there is nothing to measure (0-1\n * required fields) — a bar that fills in one keystroke reads as noise.\n */\nexport function FormMomentum({ done, total }: FormMomentumProps) {\n if (total < 2) return null\n const pct = Math.round((Math.min(done, total) / total) * 100)\n const ready = done >= total\n return (\n <div\n className=\"sk-momentum\"\n data-sk-part=\"momentum\"\n data-sk-momentum={pct}\n data-sk-complete={ready ? 'true' : undefined}\n role=\"progressbar\"\n aria-valuenow={done}\n aria-valuemin={0}\n aria-valuemax={total}\n aria-label=\"Form progress\"\n >\n <div className=\"sk-momentum-track\" data-sk-part=\"momentum-track\">\n <div className=\"sk-momentum-fill\" data-sk-part=\"momentum-fill\" style={{ width: `${pct}%` }}>\n {/* keyed by pct: remounts on every advance, replaying the flash */}\n <span key={pct} className=\"sk-momentum-flash\" data-sk-part=\"momentum-flash\" aria-hidden=\"true\" />\n </div>\n <span\n className=\"sk-momentum-spark\"\n data-sk-part=\"momentum-spark\"\n style={{ left: `calc(${pct}% - 5px)` }}\n aria-hidden=\"true\"\n />\n </div>\n <span className=\"sk-momentum-label\" data-sk-part=\"momentum-label\" aria-hidden=\"true\">\n {ready ? 'Ready' : `${done} of ${total}`}\n </span>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/forms - Form Field Component\n *\n * Renders individual form fields based on type.\n *\n * Styling Options:\n * 1. Use CSS variables to customize the default styles\n * 2. Use the `className` prop on ManagedForm for scoped styles\n * 3. Use the custom render function for complete control\n *\n * CSS Variables (set these in your stylesheet or import brand.css):\n * --sk-input-bg: #ffffff\n * --sk-input-text: #111827 (always set alongside --sk-input-bg — they pair)\n * --sk-input-border: #d1d5db\n * --sk-input-border-w: 1px\n * --sk-input-border-focus: #2563eb\n * --sk-input-border-error: #dc2626\n * --sk-input-radius: 0.375rem\n * --sk-input-padding: 10px 12px\n * --sk-label-color: inherit\n * --sk-label-weight: 500\n * --sk-error: #dc2626\n * --sk-text-tertiary: #6b7280\n * --sk-font-size: 16px\n */\n\nimport React from 'react'\nimport { FieldValidTick } from './delight'\nimport type { FormField as FormFieldType } from './types'\n\ninterface FormFieldProps {\n /** Render the valid-state tick (touched + validated). Text-like fields only. */\n showValid?: boolean\n field: FormFieldType\n value?: unknown\n error?: string\n /**\n * Omit to render STATIC mode: uncontrolled native controls with\n * `defaultValue`, no React state, no event handlers. That is what lets a\n * Server Component render a complete, submittable form with zero client\n * JavaScript (see StaticForm.tsx). Pass a handler for the usual controlled\n * behaviour once the enhancement hydrates.\n *\n * The two modes MUST emit the same element/class structure — the\n * enhancement replaces the shell in place, and a mismatch shows up as a\n * visible jump. field-parity.test.tsx pins this.\n */\n onChange?: (value: unknown) => void\n /** Optional class name prefix for custom styling */\n classPrefix?: string\n /**\n * Client-only controls, injected by FormClient. DatePicker and FileField\n * carry hooks; importing them here would pull them into this module's chunk\n * and the build would stamp the whole thing `'use client'`, so a Server\n * Component rendering one text input would ship the date picker too.\n * Injection keeps this file hook-free and therefore server-renderable.\n * Absent = static mode falls back to the native control.\n */\n controls?: {\n Date?: React.ComponentType<any>\n File?: React.ComponentType<any>\n }\n}\n\n/**\n * Normalize options from various DB formats into [{value, label}]\n * Handles:\n * - [{value, label}] → pass through\n * - {choices: [\"A\", \"B\"]} → [{value: \"A\", label: \"A\"}, ...]\n * - [\"A\", \"B\"] → [{value: \"A\", label: \"A\"}, ...]\n */\nfunction normalizeOptions(options: unknown): { value: string; label: string }[] {\n if (!options) return []\n if (Array.isArray(options)) {\n return options.map((opt) => {\n if (typeof opt === 'string') return { value: opt, label: opt }\n if (typeof opt === 'object' && opt !== null && 'value' in opt && 'label' in opt) return opt as { value: string; label: string }\n if (typeof opt === 'object' && opt !== null && 'label' in opt) return { value: (opt as any).label, label: (opt as any).label }\n return { value: String(opt), label: String(opt) }\n })\n }\n if (typeof options === 'object' && options !== null) {\n const obj = options as Record<string, unknown>\n if (Array.isArray(obj.choices)) return normalizeOptions(obj.choices)\n if (Array.isArray(obj.items)) return normalizeOptions(obj.items)\n if (Array.isArray(obj.options)) return normalizeOptions(obj.options)\n }\n return []\n}\n\nexport function FormField({ field, value, error, onChange, classPrefix = 'sk-form' , showValid, controls }: FormFieldProps) {\n // Static mode: no handler, so render native uncontrolled controls. The\n // browser owns the value and a native form POST still carries it.\n const interactive = typeof onChange === 'function'\n const emit = (v: unknown) => onChange?.(v)\n /** value/onChange when interactive, defaultValue when static. */\n const bind = (v: string) =>\n interactive\n ? { value: v, onChange: (e: any) => emit(e.target.value) }\n : { defaultValue: v || undefined }\n // Stable id from field (no hooks - avoids \"Rendered fewer hooks than expected\" with early returns)\n const inputId = `sk-${(field as { id?: string }).id || field.slug}`\n // Normalize options once\n const options = normalizeOptions(field.options)\n // Use CSS variables with inline style fallbacks\n const baseInputStyle: React.CSSProperties = {\n width: '100%',\n padding: 'var(--sk-input-padding, 10px 12px)',\n fontSize: 'var(--sk-font-size, 16px)',\n border: error\n ? 'var(--sk-input-border-w, 1px) solid var(--sk-input-border-error, #dc2626)'\n : 'var(--sk-input-border-w, 1px) solid var(--sk-input-border, #d1d5db)',\n borderRadius: 'var(--sk-input-radius, 6px)',\n backgroundColor: 'var(--sk-input-bg, #ffffff)',\n // fg and bg MUST come from the same source. Inlining bg but letting color\n // cascade from the section produced cream-on-white on brand-colored panels\n // (found live). Default pairs with the white bg; theme both via vars.\n color: 'var(--sk-input-text, #111827)',\n outline: 'none',\n fontFamily: 'inherit',\n }\n \n const labelStyle: React.CSSProperties = {\n display: 'block',\n marginBottom: 6,\n fontWeight: 'var(--sk-label-weight, 500)' as any,\n color: 'var(--sk-label-color, inherit)',\n }\n \n const errorStyle: React.CSSProperties = {\n color: 'var(--sk-error, #dc2626)',\n fontSize: 14,\n marginTop: 4,\n }\n \n const helpStyle: React.CSSProperties = {\n color: 'var(--sk-text-tertiary, #6b7280)',\n fontSize: 14,\n marginTop: 4,\n }\n \n // Heading / Section Header (display only)\n if (field.field_type === 'heading' || field.field_type === 'section_header') {\n return <h3 className={`${classPrefix}__heading`} style={{ margin: '16px 0 8px', fontWeight: 600, fontSize: 18 }}>{field.label}</h3>\n }\n \n // Paragraph (display only)\n if (field.field_type === 'paragraph') {\n return <p className={`${classPrefix}__paragraph`} style={{ color: 'var(--sk-text-tertiary, #6b7280)', margin: '8px 0' }}>{field.help_text || field.label}</p>\n }\n \n // Hidden field\n if (field.field_type === 'hidden') {\n return interactive\n ? <input type=\"hidden\" name={field.slug} value={String(value || '')} readOnly />\n : <input type=\"hidden\" name={field.slug} defaultValue={String(value || '')} />\n }\n\n const hideLabel = !!(field as { hide_label?: boolean }).hide_label\n const effectivePlaceholder = hideLabel ? field.label : field.placeholder\n\n return (\n <div className={`${classPrefix}__field ${classPrefix}__field--${field.field_type}`}>\n <label htmlFor={inputId} className={`${classPrefix}__label`} style={{ ...labelStyle, ...(hideLabel ? { position: 'absolute', width: 1, height: 1, padding: 0, margin: -1, overflow: 'hidden', clip: 'rect(0,0,0,0)', whiteSpace: 'nowrap', border: 0 } : {}) }}>\n {field.label}\n {field.is_required && <span style={{ color: 'var(--sk-error, #dc2626)' }}> *</span>}\n </label>\n \n {/* Text, Email, Phone/Tel, Number — relative wrapper hosts the valid tick */}\n {['text', 'email', 'phone', 'tel', 'number'].includes(field.field_type) && (\n <div style={{ position: 'relative' }} data-sk-part=\"field-input-wrap\" data-sk-valid={showValid ? 'true' : undefined}>\n <input\n id={inputId}\n className={`${classPrefix}__input`}\n type={field.field_type === 'phone' || field.field_type === 'tel' ? 'tel' : field.field_type}\n name={field.slug}\n {...bind(String(value || ''))}\n placeholder={effectivePlaceholder}\n required={field.is_required}\n style={baseInputStyle}\n />\n {showValid && <FieldValidTick />}\n </div>\n )}\n \n {/* Textarea */}\n {field.field_type === 'textarea' && (\n <textarea\n id={inputId}\n className={`${classPrefix}__textarea`}\n name={field.slug}\n {...bind(String(value || ''))}\n placeholder={effectivePlaceholder}\n required={field.is_required}\n rows={4}\n style={{ ...baseInputStyle, resize: 'vertical' }}\n />\n )}\n \n {/* Select */}\n {field.field_type === 'select' && (\n <select\n id={inputId}\n className={`${classPrefix}__select`}\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n >\n <option value=\"\">{effectivePlaceholder || 'Select an option'}</option>\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n \n {/* Multi-select */}\n {field.field_type === 'multi-select' && (\n <select\n id={inputId}\n className={`${classPrefix}__select ${classPrefix}__select--multi`}\n name={field.slug}\n {...(interactive\n ? {\n value: Array.isArray(value) ? (value as string[]) : [],\n onChange: (e: any) =>\n emit(Array.from(e.target.selectedOptions, (opt: any) => opt.value)),\n }\n : { defaultValue: Array.isArray(value) ? (value as string[]) : [] })}\n required={field.is_required}\n multiple\n style={{ ...baseInputStyle, height: 120 }}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n \n {/* Radio */}\n {field.field_type === 'radio' && (\n <div className={`${classPrefix}__radio-group`} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {options.map((option) => (\n <label key={option.value} className={`${classPrefix}__radio-option`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"radio\"\n name={field.slug}\n value={option.value}\n {...(interactive\n ? { checked: value === option.value, onChange: () => emit(option.value) }\n : { defaultChecked: value === option.value })}\n required={field.is_required}\n />\n {option.label}\n </label>\n ))}\n </div>\n )}\n \n {/* Checkbox (single) */}\n {field.field_type === 'checkbox' && options.length === 0 && (\n <label className={`${classPrefix}__checkbox`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"checkbox\"\n name={field.slug}\n {...(interactive\n ? { checked: !!value, onChange: (e: any) => emit(e.target.checked) }\n : { defaultChecked: !!value })}\n required={field.is_required}\n />\n {field.help_text || field.label}\n </label>\n )}\n \n {/* Checkbox (multiple options) */}\n {field.field_type === 'checkbox' && options.length > 0 && (\n <div className={`${classPrefix}__checkbox-group`} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {options.map((option) => {\n const selectedValues = Array.isArray(value) ? value : []\n const isChecked = selectedValues.includes(option.value)\n \n return (\n <label key={option.value} className={`${classPrefix}__checkbox-option`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"checkbox\"\n name={field.slug}\n value={option.value}\n {...(interactive\n ? {\n checked: isChecked,\n onChange: () =>\n emit(\n isChecked\n ? selectedValues.filter((v) => v !== option.value)\n : [...selectedValues, option.value],\n ),\n }\n : { defaultChecked: isChecked })}\n />\n {option.label}\n </label>\n )\n })}\n </div>\n )}\n \n {/* Date - Custom calendar picker */}\n {field.field_type === 'date' && (\n interactive && controls?.Date ? (\n <controls.Date\n id={inputId}\n name={field.slug}\n value={String(value || '')}\n onChange={emit}\n required={field.is_required}\n placeholder={field.placeholder || 'Select a date'}\n className={`${classPrefix}__input ${classPrefix}__input--date`}\n />\n ) : (\n // Static: the browser's own date control. Same name and class, so\n // the swap to DatePicker on enhancement is in place.\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--date`}\n type=\"date\"\n name={field.slug}\n defaultValue={String(value || '') || undefined}\n required={field.is_required}\n style={baseInputStyle}\n />\n )\n )}\n \n {/* Time */}\n {field.field_type === 'time' && (\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--time`}\n type=\"time\"\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n />\n )}\n \n {/* DateTime */}\n {field.field_type === 'datetime' && (\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--datetime`}\n type=\"datetime-local\"\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n />\n )}\n \n {/* File */}\n {field.field_type === 'file' && (\n interactive && controls?.File ? (\n <controls.File\n field={field}\n inputId={inputId}\n classPrefix={classPrefix}\n baseInputStyle={baseInputStyle}\n onChange={emit}\n />\n ) : (\n // Static: a real file input so the field is visible and labelled,\n // but the Sonor upload only happens once enhanced. Forms with a file\n // field are excluded from native POST for exactly this reason\n // (see nativeEligible in native-fallback.tsx).\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n style={baseInputStyle}\n />\n )\n )}\n \n {/* Rating */}\n {field.field_type === 'rating' && (\n <div className={`${classPrefix}__rating`} style={{ display: 'flex', gap: 4 }} role={interactive ? undefined : 'radiogroup'} aria-label={interactive ? undefined : field.label}>\n {!interactive && [1, 2, 3, 4, 5].map((star) => (\n // Static: a real radio group. Submits natively, and is reachable\n // by keyboard and screen readers without any script.\n <label key={`s${star}`} className={`${classPrefix}__rating-star`} style={{ fontSize: 24, cursor: 'pointer', color: (value as number) >= star ? 'var(--sk-rating-active, #fbbf24)' : 'var(--sk-rating-inactive, #d1d5db)' }}>\n <input\n type=\"radio\"\n name={field.slug}\n value={star}\n defaultChecked={(value as number) === star}\n required={field.is_required && star === 1}\n style={{ position: 'absolute', width: 1, height: 1, opacity: 0 }}\n />\n <span aria-label={`${star} star${star > 1 ? 's' : ''}`}>★</span>\n </label>\n ))}\n {interactive && [1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => emit(star)}\n className={`${classPrefix}__rating-star`}\n style={{\n background: 'none',\n border: 'none',\n fontSize: 24,\n cursor: 'pointer',\n color: (value as number) >= star ? 'var(--sk-rating-active, #fbbf24)' : 'var(--sk-rating-inactive, #d1d5db)',\n }}\n >\n ★\n </button>\n ))}\n </div>\n )}\n \n {/* Slider */}\n {field.field_type === 'slider' && (\n <div className={`${classPrefix}__slider`}>\n <input\n id={inputId}\n type=\"range\"\n name={field.slug}\n {...(interactive\n ? { value: Number(value || 50), onChange: (e: any) => emit(Number(e.target.value)) }\n : { defaultValue: Number(value || 50) })}\n min={field.validation?.min || 0}\n max={field.validation?.max || 100}\n style={{ width: '100%' }}\n />\n <div className={`${classPrefix}__slider-value`} style={{ textAlign: 'center', marginTop: 4 }}>{String(value || 50)}</div>\n </div>\n )}\n \n {/* Error message */}\n {error && <p className={`${classPrefix}__error`} style={errorStyle}>{error}</p>}\n \n {/* Help text */}\n {field.help_text && !error && field.field_type !== 'checkbox' && (\n <p className={`${classPrefix}__help`} style={helpStyle}>{field.help_text}</p>\n )}\n </div>\n )\n}\n"]}
|
|
@@ -54,7 +54,7 @@ function useSignal() {
|
|
|
54
54
|
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
55
55
|
}
|
|
56
56
|
var LazySignalCore = dynamic(
|
|
57
|
-
() => import('./SignalCore-
|
|
57
|
+
() => import('./SignalCore-36PY3SRB.mjs').then((m) => ({ default: m.SignalCore })),
|
|
58
58
|
{ ssr: false }
|
|
59
59
|
);
|
|
60
60
|
function SignalBridge({
|
|
@@ -161,5 +161,5 @@ function useSignalExperiment(experimentId) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome };
|
|
164
|
-
//# sourceMappingURL=chunk-
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
164
|
+
//# sourceMappingURL=chunk-LMKDQCU7.mjs.map
|
|
165
|
+
//# sourceMappingURL=chunk-LMKDQCU7.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":[],"mappings":"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","file":"chunk-OIBQYBEL.mjs","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":[],"mappings":";;;;;AAyBA,IAAM,gBAAwC,EAAC;AAC/C,IAAM,kBAAmC,EAAC;AAC1C,IAAM,WAAA,GAAc,GAAA;AACpB,IAAI,cAAA,GAAiB,KAAA;AAGrB,IAAM,IAAA,GAA2B,OAAO,MAAA,CAAO;AAAA,EAC7C,MAAA,EAAQ,IAAA;AAAA,EACR,OAAA,EAAS,IAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,UAAA,EAAY,CAAC,KAAA,KAAgC;AAC3C,IAAA,IAAI,aAAA,CAAc,MAAA,GAAS,WAAA,EAAa,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,SAAA,IACvD,CAAC,cAAA,EAAgB;AACxB,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,OAAA,CAAQ,KAAK,iHAA4G,CAAA;AAAA,IAC3H;AAAA,EACF,CAAA;AAAA,EACA,YAAA,EAAc,CAAC,OAAA,KAA2B;AACxC,IAAA,IAAI,eAAA,CAAgB,MAAA,GAAS,WAAA,EAAa,eAAA,CAAgB,KAAK,OAAO,CAAA;AAAA,EACxE,CAAA;AAAA,EACA,eAAe,MAAM,IAAA;AAAA,EACrB,eAAe,YAAY;AAAA,EAAC;AAC9B,CAAC,CAAA;AAED,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,SAAS,IAAA,GAAO;AACd,EAAA,KAAA,MAAW,CAAA,IAAK,WAAW,CAAA,EAAE;AAC/B;AAGO,SAAS,cAAc,KAAA,EAAiC;AAC7D,EAAA,MAAM,eAAe,OAAA,KAAY,IAAA;AACjC,EAAA,OAAA,GAAU,KAAA;AACV,EAAA,IAAI,YAAA,EAAc;AAGhB,IAAA,aAAA,CAAc,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAK,KAAA,CAAM,UAAA,CAAW,CAAC,CAAC,CAAA;AACxD,IAAA,eAAA,CAAgB,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAK,KAAA,CAAM,YAAA,CAAa,CAAC,CAAC,CAAA;AAAA,EAC9D;AACA,EAAA,IAAA,EAAK;AACP;AAGO,SAAS,WAAA,GAAoB;AAClC,EAAA,OAAA,GAAU,IAAA;AACV,EAAA,IAAA,EAAK;AACP;AAEA,SAAS,UAAU,QAAA,EAAsB;AACvC,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AACxC;AAEA,IAAM,cAAc,MAAM,OAAA;AAC1B,IAAM,oBAAoB,MAAM,IAAA;AAMzB,SAAS,SAAA,GAAgC;AAC9C,EAAA,OAAO,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,iBAAiB,CAAA;AACvE;ACnDA,IAAM,cAAA,GAAiB,OAAA;AAAA,EACrB,MAAM,OAAO,2BAAc,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,UAAA,EAAW,CAAE,CAAA;AAAA,EAClE,EAAE,KAAK,KAAA;AACT,CAAA;AAcO,SAAS,YAAA,CAAa;AAAA,EAC3B,OAAA,GAAU,IAAA;AAAA,EACV,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,gBAAA,GAAmB,IAAA;AAAA,EACnB,SAAA,EAAW,iBAAA;AAAA,EACX,SAAA,EAAW,iBAAA;AAAA,EACX,eAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA8B,IAAI,CAAA;AAC9D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,OAAA,GAAU,OAA6B,IAAI,CAAA;AAGjD,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAA+B,EAAE,CAAA;AAC1D,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAwB,EAAE,CAAA;AAErD,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,CAAC,KAAA,KAA2B;AAC1D,IAAA,SAAA,CAAU,MAAM,MAAM,CAAA;AACtB,IAAA,UAAA,CAAW,MAAM,OAAO,CAAA;AACxB,IAAA,QAAA,CAAS,MAAM,KAAK,CAAA;AAAA,EACtB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,CAAC,GAAA,KAA8B;AAChE,IAAA,OAAA,CAAQ,OAAA,GAAU,GAAA;AAClB,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,gBAAA,CAAiB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAA,KAAA,KAAS,GAAA,CAAI,UAAA,CAAW,KAAK,CAAC,CAAA;AACzE,MAAA,kBAAA,CAAmB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAA,OAAA,KAAW,GAAA,CAAI,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,IACnF;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,KAAA,KAAgC;AAC9D,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,OAAA,CAAQ,WAAW,KAAK,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,gBAAA,CAAiB,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IACrC;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,CAAC,OAAA,KAA2B;AAC3D,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,OAAA,CAAQ,aAAa,OAAO,CAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,kBAAA,CAAmB,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IACzC;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,YAAA,KAAsD;AAGvF,IAAA,OAAO,OAAA,CAAQ,OAAA,EAAS,aAAA,CAAc,YAAY,CAAA,IAAK,IAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgB,YAAY,YAAY;AAC5C,IAAA,MAAM,OAAA,CAAQ,SAAS,aAAA,EAAc;AAAA,EACvC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GAAe,QAA4B,OAAO;AAAA,IACtD,MAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,CAAA,EAAI,CAAC,MAAA,EAAQ,OAAA,EAAS,OAAO,UAAA,EAAY,YAAA,EAAc,aAAA,EAAe,aAAa,CAAC,CAAA;AAIpF,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,aAAA,CAAc,YAAY,CAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AACjB,EAAA,SAAA,CAAU,MAAM,MAAM,WAAA,EAAY,EAAG,EAAE,CAAA;AAEvC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,OAAA,oBACC,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,gBAAA;AAAA,QACA,iBAAA;AAAA,QACA,iBAAA;AAAA,QACA,eAAA;AAAA,QACA,UAAA,EAAY,cAAA;AAAA,QACZ,OAAA,EAAS;AAAA;AAAA;AACX,GAAA,EAEJ,CAAA;AAEJ;AASO,SAAS,eAAA,GAAuC;AACrD,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,cAAA,GAAiB;AAC/B,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,SAAA,EAAU;AACjC,EAAA,OAAO,UAAA;AACT;AAKO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,SAAA,EAAU;AACnC,EAAA,OAAO,EAAE,YAAA,EAAa;AACxB;AAKO,SAAS,oBAAoB,YAAA,EAIlC;AACA,EAAA,MAAM,EAAE,aAAA,EAAe,MAAA,EAAO,GAAI,SAAA,EAAU;AAC5C,EAAA,MAAM,UAAA,GAAa,cAAc,YAAY,CAAA;AAG7C,EAAA,MAAM,aAAa,MAAA,EAAQ,WAAA,EAAa,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,YAAY,CAAA;AACvE,EAAA,MAAM,SAAA,GAAY,YAAY,MAAA,KAAW,SAAA;AAEzC,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,YAAY,UAAA,GAAa,IAAA;AAAA,IACrC,OAAA,EAAS,SAAA,IAAa,UAAA,GAAa,UAAA,CAAW,WAAA,GAAc,IAAA;AAAA,IAC5D,SAAA,EAAW,CAAC,UAAA,IAAc,UAAA,CAAW,WAAA,KAAgB;AAAA,GACvD;AACF","file":"chunk-LMKDQCU7.mjs","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkFYPA5GLS_js = require('./chunk-FYPA5GLS.js');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
|
|
@@ -40,7 +40,7 @@ function ManagedImage({
|
|
|
40
40
|
}
|
|
41
41
|
try {
|
|
42
42
|
const params = new URLSearchParams({ page_path: currentPath });
|
|
43
|
-
const res = await
|
|
43
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
44
44
|
`${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
|
|
45
45
|
{ headers: { "Content-Type": "application/json" } },
|
|
46
46
|
{ apiKey }
|
|
@@ -214,7 +214,7 @@ function ImagePickerModal({
|
|
|
214
214
|
const params = new URLSearchParams();
|
|
215
215
|
if (currentFolder) params.set("folder", currentFolder);
|
|
216
216
|
if (search) params.set("search", search);
|
|
217
|
-
const res = await
|
|
217
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
218
218
|
`${config.apiUrl}/public/images/files?${params}`,
|
|
219
219
|
{ headers: { "Content-Type": "application/json" } },
|
|
220
220
|
{ apiKey: config.apiKey }
|
|
@@ -236,7 +236,7 @@ function ImagePickerModal({
|
|
|
236
236
|
const handleSelectFile = async (file) => {
|
|
237
237
|
if (!config?.apiKey || !config?.apiUrl) return;
|
|
238
238
|
try {
|
|
239
|
-
const res = await
|
|
239
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
240
240
|
`${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,
|
|
241
241
|
{
|
|
242
242
|
method: "POST",
|
|
@@ -267,7 +267,7 @@ function ImagePickerModal({
|
|
|
267
267
|
formData.append("page_path", pagePath);
|
|
268
268
|
formData.append("folder", currentFolder || "Website/Images");
|
|
269
269
|
if (altText) formData.append("alt_text", altText);
|
|
270
|
-
const res = await
|
|
270
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
|
|
271
271
|
method: "POST",
|
|
272
272
|
body: formData
|
|
273
273
|
}, { apiKey: config.apiKey, retries: 0, timeoutMs: 6e4 });
|
|
@@ -284,7 +284,7 @@ function ImagePickerModal({
|
|
|
284
284
|
if (!config?.apiKey || !config?.apiUrl) return;
|
|
285
285
|
try {
|
|
286
286
|
const params = new URLSearchParams({ page_path: pagePath });
|
|
287
|
-
await
|
|
287
|
+
await chunkFYPA5GLS_js.sonorFetch(
|
|
288
288
|
`${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
|
|
289
289
|
{ method: "DELETE" },
|
|
290
290
|
{ apiKey: config.apiKey, retries: 0 }
|
|
@@ -428,7 +428,7 @@ function ImagePickerModal({
|
|
|
428
428
|
async function fetchManagedImage(config, slotId, pagePath) {
|
|
429
429
|
const params = new URLSearchParams();
|
|
430
430
|
if (pagePath) params.set("page_path", pagePath);
|
|
431
|
-
const res = await
|
|
431
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
432
432
|
`${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
|
|
433
433
|
{ headers: { "Content-Type": "application/json" } },
|
|
434
434
|
{ apiKey: config.apiKey }
|
|
@@ -443,7 +443,7 @@ async function fetchManagedImages(config, options) {
|
|
|
443
443
|
if (options?.pagePath) params.set("page_path", options.pagePath);
|
|
444
444
|
if (options?.category) params.set("category", options.category);
|
|
445
445
|
if (options?.includePlaceholders) params.set("include_placeholders", "true");
|
|
446
|
-
const res = await
|
|
446
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
447
447
|
`${config.apiUrl}/public/images?${params}`,
|
|
448
448
|
{ headers: { "Content-Type": "application/json" } },
|
|
449
449
|
{ apiKey: config.apiKey }
|
|
@@ -457,7 +457,7 @@ async function listImageFiles(config, options) {
|
|
|
457
457
|
const params = new URLSearchParams();
|
|
458
458
|
if (options?.folder) params.set("folder", options.folder);
|
|
459
459
|
if (options?.search) params.set("search", options.search);
|
|
460
|
-
const res = await
|
|
460
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
461
461
|
`${config.apiUrl}/public/images/files?${params}`,
|
|
462
462
|
{ headers: { "Content-Type": "application/json" } },
|
|
463
463
|
{ apiKey: config.apiKey }
|
|
@@ -474,7 +474,7 @@ async function uploadImage(config, file, options) {
|
|
|
474
474
|
if (options?.pagePath) formData.append("page_path", options.pagePath);
|
|
475
475
|
if (options?.folder) formData.append("folder", options.folder);
|
|
476
476
|
if (options?.altText) formData.append("alt_text", options.altText);
|
|
477
|
-
const res = await
|
|
477
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
|
|
478
478
|
method: "POST",
|
|
479
479
|
body: formData
|
|
480
480
|
}, { apiKey: config.apiKey, retries: 0, timeoutMs: 6e4 });
|
|
@@ -484,7 +484,7 @@ async function uploadImage(config, file, options) {
|
|
|
484
484
|
return res.json();
|
|
485
485
|
}
|
|
486
486
|
async function assignImageToSlot(config, slotId, options) {
|
|
487
|
-
const res = await
|
|
487
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
488
488
|
`${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,
|
|
489
489
|
{
|
|
490
490
|
method: "POST",
|
|
@@ -511,7 +511,7 @@ async function assignImageToSlot(config, slotId, options) {
|
|
|
511
511
|
async function clearImageSlot(config, slotId, pagePath) {
|
|
512
512
|
const params = new URLSearchParams();
|
|
513
513
|
if (pagePath) params.set("page_path", pagePath);
|
|
514
|
-
const res = await
|
|
514
|
+
const res = await chunkFYPA5GLS_js.sonorFetch(
|
|
515
515
|
`${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
|
|
516
516
|
{ method: "DELETE" },
|
|
517
517
|
{ apiKey: config.apiKey, retries: 0 }
|
|
@@ -529,5 +529,5 @@ exports.fetchManagedImage = fetchManagedImage;
|
|
|
529
529
|
exports.fetchManagedImages = fetchManagedImages;
|
|
530
530
|
exports.listImageFiles = listImageFiles;
|
|
531
531
|
exports.uploadImage = uploadImage;
|
|
532
|
-
//# sourceMappingURL=chunk-
|
|
533
|
-
//# sourceMappingURL=chunk-
|
|
532
|
+
//# sourceMappingURL=chunk-LRHECSZK.js.map
|
|
533
|
+
//# sourceMappingURL=chunk-LRHECSZK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["useState","useCallback","sonorFetch","useEffect","jsx","jsxs"],"mappings":"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","file":"chunk-RZW4XVG5.js","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["useState","useCallback","sonorFetch","useEffect","jsx","jsxs"],"mappings":"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","file":"chunk-LRHECSZK.js","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkRC4WWQXR_js = require('./chunk-RC4WWQXR.js');
|
|
5
|
-
var
|
|
5
|
+
var chunkFYPA5GLS_js = require('./chunk-FYPA5GLS.js');
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var ReactDOM = require('react-dom');
|
|
8
8
|
var dynamic = require('next/dynamic');
|
|
@@ -275,7 +275,7 @@ function DesignRenderer({
|
|
|
275
275
|
)) });
|
|
276
276
|
}
|
|
277
277
|
var LazyChatWidget = dynamic__default.default(
|
|
278
|
-
() => import('./ChatWidget-
|
|
278
|
+
() => import('./ChatWidget-AYKZBKJH.js').then((m) => ({ default: m.ChatWidget })),
|
|
279
279
|
{ ssr: false }
|
|
280
280
|
);
|
|
281
281
|
function getApiConfig() {
|
|
@@ -311,7 +311,7 @@ function EngageWidget({
|
|
|
311
311
|
const visitorId = chunkRC4WWQXR_js.getOrCreateVisitorId();
|
|
312
312
|
const url = typeof window !== "undefined" ? window.location.href : "";
|
|
313
313
|
try {
|
|
314
|
-
const response = await
|
|
314
|
+
const response = await chunkFYPA5GLS_js.sonorFetch(
|
|
315
315
|
`${apiUrl.replace(/\/$/, "")}/engage/widget/elements?url=${encodeURIComponent(url)}&visitorId=${encodeURIComponent(visitorId)}`,
|
|
316
316
|
{},
|
|
317
317
|
{ apiKey }
|
|
@@ -455,7 +455,7 @@ function EngageWidget({
|
|
|
455
455
|
function trackEngageEvent(apiUrl, apiKey, endpoint, data) {
|
|
456
456
|
if (!apiKey) return;
|
|
457
457
|
const visitorId = typeof localStorage !== "undefined" ? localStorage.getItem("_sk_vid") : null;
|
|
458
|
-
|
|
458
|
+
chunkFYPA5GLS_js.sonorFetch(`${apiUrl.replace(/\/$/, "")}/engage/widget/${endpoint}`, {
|
|
459
459
|
method: "POST",
|
|
460
460
|
headers: { "Content-Type": "application/json" },
|
|
461
461
|
body: JSON.stringify({ ...data, visitorId, pageUrl: window.location.href }),
|
|
@@ -726,5 +726,5 @@ function getDeviceType() {
|
|
|
726
726
|
|
|
727
727
|
exports.DesignRenderer = DesignRenderer;
|
|
728
728
|
exports.EngageWidget = EngageWidget;
|
|
729
|
-
//# sourceMappingURL=chunk-
|
|
730
|
-
//# sourceMappingURL=chunk-
|
|
729
|
+
//# sourceMappingURL=chunk-MKQZVTD3.js.map
|
|
730
|
+
//# sourceMappingURL=chunk-MKQZVTD3.js.map
|