@wix/site-service-interactions 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/cjs/build/implementations/coreInteractions.js +37 -22
  2. package/cjs/build/implementations/coreInteractions.js.map +1 -1
  3. package/cjs/build/implementations/stylesToAdd.d.ts +1 -1
  4. package/cjs/build/implementations/stylesToAdd.js +1 -1
  5. package/cjs/build/implementations/v2/InteractionsScriptElement.d.ts +3 -0
  6. package/cjs/build/implementations/v2/InteractionsScriptElement.js +33 -0
  7. package/cjs/build/implementations/v2/InteractionsScriptElement.js.map +1 -0
  8. package/cjs/build/implementations/v2/cdnUrls.d.ts +2 -0
  9. package/cjs/build/implementations/v2/cdnUrls.js +6 -0
  10. package/cjs/build/implementations/v2/cdnUrls.js.map +1 -0
  11. package/cjs/build/implementations/v2/clickTriggerCss.d.ts +3 -0
  12. package/cjs/build/implementations/v2/clickTriggerCss.js +35 -0
  13. package/cjs/build/implementations/v2/clickTriggerCss.js.map +1 -0
  14. package/cjs/build/implementations/v2/configCss.d.ts +3 -0
  15. package/cjs/build/implementations/v2/configCss.js +50 -0
  16. package/cjs/build/implementations/v2/configCss.js.map +1 -0
  17. package/cjs/build/implementations/v2/configStyleHeadContent.d.ts +1 -0
  18. package/cjs/build/implementations/v2/configStyleHeadContent.js +16 -0
  19. package/cjs/build/implementations/v2/configStyleHeadContent.js.map +1 -0
  20. package/cjs/build/implementations/v2/interactionsScriptContent.d.ts +8 -0
  21. package/cjs/build/implementations/v2/interactionsScriptContent.js +36 -0
  22. package/cjs/build/implementations/v2/interactionsScriptContent.js.map +1 -0
  23. package/dist/implementations/coreInteractions.js +37 -22
  24. package/dist/implementations/coreInteractions.js.map +1 -1
  25. package/dist/implementations/stylesToAdd.d.ts +1 -1
  26. package/dist/implementations/stylesToAdd.js +1 -1
  27. package/dist/implementations/v2/InteractionsScriptElement.d.ts +3 -0
  28. package/dist/implementations/v2/InteractionsScriptElement.js +26 -0
  29. package/dist/implementations/v2/InteractionsScriptElement.js.map +1 -0
  30. package/dist/implementations/v2/cdnUrls.d.ts +2 -0
  31. package/dist/implementations/v2/cdnUrls.js +3 -0
  32. package/dist/implementations/v2/cdnUrls.js.map +1 -0
  33. package/dist/implementations/v2/clickTriggerCss.d.ts +3 -0
  34. package/dist/implementations/v2/clickTriggerCss.js +31 -0
  35. package/dist/implementations/v2/clickTriggerCss.js.map +1 -0
  36. package/dist/implementations/v2/configCss.d.ts +3 -0
  37. package/dist/implementations/v2/configCss.js +13 -0
  38. package/dist/implementations/v2/configCss.js.map +1 -0
  39. package/dist/implementations/v2/configStyleHeadContent.d.ts +1 -0
  40. package/dist/implementations/v2/configStyleHeadContent.js +12 -0
  41. package/dist/implementations/v2/configStyleHeadContent.js.map +1 -0
  42. package/dist/implementations/v2/interactionsScriptContent.d.ts +8 -0
  43. package/dist/implementations/v2/interactionsScriptContent.js +31 -0
  44. package/dist/implementations/v2/interactionsScriptContent.js.map +1 -0
  45. package/package.json +9 -5
  46. package/src/implementations/coreInteractions.ts +43 -25
  47. package/src/implementations/stylesToAdd.ts +1 -1
  48. package/src/implementations/v2/InteractionsScriptElement.tsx +42 -0
  49. package/src/implementations/v2/cdnUrls.ts +3 -0
  50. package/src/implementations/v2/clickTriggerCss.ts +44 -0
  51. package/src/implementations/v2/configCss.ts +19 -0
  52. package/src/implementations/v2/configStyleHeadContent.ts +12 -0
  53. package/src/implementations/v2/interactionsScriptContent.ts +34 -0
@@ -4,11 +4,21 @@ exports.coreInteractions = void 0;
4
4
  const interact_1 = require("@wix/interact");
5
5
  const definition_1 = require("@wix/site-service-device-info/definition");
6
6
  const definition_2 = require("@wix/site-service-experiments/definition");
7
- const definition_3 = require("@wix/site-service-rendering-context/definition");
8
- const definition_4 = require("@wix/site-service-pages/definition");
7
+ // Deliberately the deprecated pages service. Thunderbolt registers the site-service-pages page
8
+ // config only for sites that list it in `requiredServicesMap`, which ordinary sites do not, so
9
+ // `currentPage` falls back to EMPTY_PAGE and the id is ''. The legacy pages feature carries an
10
+ // explicit `interactionsFeature` escape hatch, so its config is populated for us.
11
+ const definition_3 = require("@wix/viewer-service-pages/definition");
12
+ const definition_4 = require("@wix/site-service-head-appender/definition");
13
+ const types_1 = require("@wix/site-service-head-appender/types");
9
14
  const provide_component_1 = require("@wix/services-manager-react/core-services/provide-component");
10
15
  const InteractionsScriptElement_1 = require("./InteractionsScriptElement");
16
+ const InteractionsScriptElement_2 = require("./v2/InteractionsScriptElement");
17
+ const configCss_1 = require("./v2/configCss");
18
+ const configStyleHeadContent_1 = require("./v2/configStyleHeadContent");
19
+ const interactionsScriptContent_1 = require("./v2/interactionsScriptContent");
11
20
  const initInteract = (config, isReducedMotion) => {
21
+ // Bundled runtime is v1. v2 on the client is the CDN loader.
12
22
  interact_1.Interact.forceReducedMotion = isReducedMotion;
13
23
  interact_1.Interact.setup({
14
24
  scrollOptionsGetter: () => globalThis.document.getElementById('site-root'),
@@ -19,45 +29,50 @@ const initInteract = (config, isReducedMotion) => {
19
29
  });
20
30
  interact_1.Interact.create(config);
21
31
  };
22
- const tryInitInteractInSsr = (config, isReducedMotion, getService) => {
23
- const hasInteractions = config.interactions?.length > 0;
24
- if (!hasInteractions) {
25
- return false;
32
+ const initRuntime = (config, isReducedMotion, getService, useV2) => {
33
+ if (!config.interactions?.length) {
34
+ return;
26
35
  }
27
- const { currentPage } = getService(definition_4.PagesDefinition);
28
- const pageId = currentPage?.id;
36
+ const pageId = getService(definition_3.PagesDefinition).currentPageId();
29
37
  if (!pageId) {
30
- return false;
38
+ return;
31
39
  }
32
40
  const { addTopComponent } = getService(provide_component_1.ProvideComponentServiceDefinition);
33
- const ssrScriptElement = (0, InteractionsScriptElement_1.createInteractionsScriptElement)(config, isReducedMotion, pageId);
34
- addTopComponent(ssrScriptElement);
35
- return true;
41
+ const interactionsScript = useV2
42
+ ? (0, InteractionsScriptElement_2.createV2InteractionsScriptElement)(config, isReducedMotion, pageId)
43
+ : (0, InteractionsScriptElement_1.createInteractionsScriptElement)(config, isReducedMotion, pageId);
44
+ addTopComponent(interactionsScript);
36
45
  };
37
46
  const getInteractiveComps = (interactions) => interactions.reduce((acc, { key, effects }) => {
38
47
  // add trigger comp
39
48
  acc.add(key);
40
49
  // add reaction comps
41
50
  // there must be a key
42
- effects.forEach(({ key }) => acc.add(key));
51
+ effects?.forEach(({ key }) => acc.add(key));
43
52
  return acc;
44
53
  }, new Set());
45
54
  const coreInteractions = (config, getService) => {
46
55
  const { reducedMotion: isReducedMotion } = getService(definition_1.DeviceInfoDefinition);
47
56
  const { isOpen } = getService(definition_2.ExperimentsDefinition);
48
- const { SSR } = getService(definition_3.RenderingContextDefinition);
49
- const isSSRExperimentOpen = isOpen('specs.thunderbolt.interactionsInSsr');
50
- if (isSSRExperimentOpen) {
57
+ if (isOpen('specs.thunderbolt.vsm_interactions_v2')) {
58
+ // Both belong in the head: the preload links only help while the document is still parsing,
59
+ // and the generated CSS hides elements before their entrance effect, so it has to apply
60
+ // before the body renders.
61
+ if (!process.env.browser) {
62
+ const css = (0, configCss_1.getV2ConfigCss)(config).trim();
63
+ // GENERAL rather than setHead's AFTER_SECURITY default: thunderbolt only reads the
64
+ // after-security bucket on its SEO path, so the default drops this on every normal
65
+ // request. GENERAL reaches the document as raw markup before `</head>`.
66
+ getService(definition_4.HeadAppenderDefinition).setHead((0, interactionsScriptContent_1.getV2ModulePreloadHeadContent)() + (css ? (0, configStyleHeadContent_1.getV2ConfigStyleHeadContent)(css) : ''), types_1.HeadContentType.GENERAL);
67
+ }
68
+ initRuntime(config, isReducedMotion, getService, true);
69
+ }
70
+ else if (isOpen('specs.thunderbolt.interactionsInSsr')) {
51
71
  // Emits the config and loader scripts. Works in both environments: SSR serves markup the
52
72
  // parser executes, and on the client the loader's ref revives it into a script that runs —
53
73
  // which is what pages rendered only on the client (password-protected / members-only,
54
74
  // client-side navigation) need, since they never get a server-rendered document.
55
- const didInitInteractInSsr = tryInitInteractInSsr(config, isReducedMotion, getService);
56
- // Fall back to direct init on the client if the script element could not be set up
57
- // (e.g. no pageId or no interactions).
58
- if (!didInitInteractInSsr && !SSR) {
59
- initInteract(config, isReducedMotion);
60
- }
75
+ initRuntime(config, isReducedMotion, getService, false);
61
76
  }
62
77
  else {
63
78
  initInteract(config, isReducedMotion);
@@ -1 +1 @@
1
- {"version":3,"file":"coreInteractions.js","sourceRoot":"","sources":["../../../src/implementations/coreInteractions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coreInteractions.js","sourceRoot":"","sources":["../../../src/implementations/coreInteractions.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const wixInteractElementCss = "\n wix-interact-element {\n display: contents;\n }\n ";
1
+ export declare const wixInteractElementCss = "\n interact-element {\n display: contents;\n }\n ";
2
2
  export declare const hasClickTriggerCss = "\n .has-click-trigger {\n cursor: pointer;\n }\n ";
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasClickTriggerCss = exports.wixInteractElementCss = void 0;
4
4
  exports.wixInteractElementCss = `
5
- wix-interact-element {
5
+ interact-element {
6
6
  display: contents;
7
7
  }
8
8
  `;
@@ -0,0 +1,3 @@
1
+ import type { FunctionComponent } from 'react';
2
+ import type { InteractConfig } from '@wix/interact';
3
+ export declare const createV2InteractionsScriptElement: (config: InteractConfig, isReducedMotion: boolean, pageId: string) => FunctionComponent;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createV2InteractionsScriptElement = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const reviveScriptElement_1 = require("../reviveScriptElement");
9
+ const interactionsScriptContent_1 = require("./interactionsScriptContent");
10
+ const DANGEROUSLY_SET_INNER_HTML = ['dangerously', 'Set', 'Inner', 'HTML'];
11
+ /**
12
+ * The config is written as raw markup, so a `</script` inside any string value would close the
13
+ * element early. `\u003c` is valid JSON that `JSON.parse` reads back as `<`.
14
+ */
15
+ const serializeConfigForScriptElement = (config) => JSON.stringify(config).replace(/</g, '\\u003c');
16
+ const createV2InteractionsScriptElement = (config, isReducedMotion, pageId) => () => {
17
+ // This ID is also interpolated into raw module-script text. Percent-encoding removes
18
+ // script delimiters and template-literal syntax while keeping the ID deterministic.
19
+ const safePageId = encodeURIComponent(pageId);
20
+ const configId = `interactions-config-${safePageId}`;
21
+ const interactionsScriptContent = (0, interactionsScriptContent_1.getV2InteractionsScriptContent)(configId, isReducedMotion);
22
+ const configProps = {
23
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: serializeConfigForScriptElement(config) },
24
+ };
25
+ const loaderProps = {
26
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: interactionsScriptContent },
27
+ };
28
+ return (react_1.default.createElement(react_1.default.Fragment, null,
29
+ react_1.default.createElement("script", { type: "application/json", id: configId, ...configProps }),
30
+ react_1.default.createElement("script", { type: "module", id: `interactions-loader-${safePageId}`, ref: reviveScriptElement_1.reviveScriptElement, ...loaderProps })));
31
+ };
32
+ exports.createV2InteractionsScriptElement = createV2InteractionsScriptElement;
33
+ //# sourceMappingURL=InteractionsScriptElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractionsScriptElement.js","sourceRoot":"","sources":["../../../../src/implementations/v2/InteractionsScriptElement.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AAGzB,gEAA4D;AAC5D,2EAA4E;AAE5E,MAAM,0BAA0B,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AAE1E;;;GAGG;AACH,MAAM,+BAA+B,GAAG,CAAC,MAAsB,EAAU,EAAE,CACvE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;AAE5C,MAAM,iCAAiC,GAC1C,CAAC,MAAsB,EAAE,eAAwB,EAAE,MAAc,EAAqB,EAAE,CACxF,GAAG,EAAE;IACD,qFAAqF;IACrF,oFAAoF;IACpF,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,uBAAuB,UAAU,EAAE,CAAA;IACpD,MAAM,yBAAyB,GAAG,IAAA,0DAA8B,EAAC,QAAQ,EAAE,eAAe,CAAC,CAAA;IAC3F,MAAM,WAAW,GAAG;QAChB,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,+BAA+B,CAAC,MAAM,CAAC,EAAE;KAC7F,CAAA;IACD,MAAM,WAAW,GAAG;QAChB,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,yBAAyB,EAAE;KAC/E,CAAA;IAED,OAAO,CACH;QACI,0CAAQ,IAAI,EAAC,kBAAkB,EAAC,EAAE,EAAE,QAAQ,KAAM,WAAW,GAAI;QACjE,0CACI,IAAI,EAAC,QAAQ,EACb,EAAE,EAAE,uBAAuB,UAAU,EAAE,EACvC,GAAG,EAAE,yCAAmB,KACpB,WAAW,GACjB,CACH,CACN,CAAA;AACL,CAAC,CAAA;AA1BQ,QAAA,iCAAiC,qCA0BzC"}
@@ -0,0 +1,2 @@
1
+ export declare const INTERACT_V2_IMPORT_URL = "https://cdn.jsdelivr.net/npm/@wix/interact@2.5.14/dist/es/web.min.js";
2
+ export declare const WIX_MOTION_PRESETS_IMPORT_URL = "https://cdn.jsdelivr.net/npm/@wix/wix-motion-presets@1.0.0/+esm";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WIX_MOTION_PRESETS_IMPORT_URL = exports.INTERACT_V2_IMPORT_URL = void 0;
4
+ exports.INTERACT_V2_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/interact@2.5.14/dist/es/web.min.js';
5
+ exports.WIX_MOTION_PRESETS_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/wix-motion-presets@1.0.0/+esm';
6
+ //# sourceMappingURL=cdnUrls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdnUrls.js","sourceRoot":"","sources":["../../../../src/implementations/v2/cdnUrls.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,sEAAsE,CAAA;AAE/F,QAAA,6BAA6B,GAAG,iEAAiE,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { InteractConfig } from '@wix/interact';
2
+ /** Emits `cursor: pointer` for click interaction triggers (`'activate' || 'click'`), one rule per unique source selector. */
3
+ export declare const getClickTriggerCss: (config: InteractConfig) => string;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getClickTriggerCss = void 0;
4
+ const escapeCssAttr = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
5
+ /**
6
+ * Mirrors `@wix/interact` `getSelector(interaction, { asCombinator: true, useFirstChild: true })`
7
+ * plus the `[data-interact-key="…"]` prefix from `CSSRuleToString`.
8
+ */
9
+ const getInteractionSourceSelector = (interaction) => {
10
+ const { key, selector, listContainer, listItemSelector } = interaction;
11
+ const attrSelector = `[data-interact-key="${escapeCssAttr(key)}"]`;
12
+ if (listContainer) {
13
+ const itemFilter = listItemSelector ? ` > ${listItemSelector}` : '';
14
+ const inner = selector ? `${listContainer}${itemFilter} ${selector}` : `${listContainer}${itemFilter || ' > *'}`;
15
+ return `${attrSelector} ${inner}`;
16
+ }
17
+ if (selector) {
18
+ return `${attrSelector} ${selector}`;
19
+ }
20
+ return `${attrSelector} > :first-child`;
21
+ };
22
+ /** Emits `cursor: pointer` for click interaction triggers (`'activate' || 'click'`), one rule per unique source selector. */
23
+ const getClickTriggerCss = (config) => {
24
+ const selectors = [
25
+ ...new Set(config.interactions
26
+ .filter(({ trigger }) => trigger === 'activate' || trigger === 'click')
27
+ .map(getInteractionSourceSelector)),
28
+ ];
29
+ if (!selectors.length) {
30
+ return '';
31
+ }
32
+ return selectors.map(selector => `${selector} {\ncursor: pointer;\n}`).join('\n');
33
+ };
34
+ exports.getClickTriggerCss = getClickTriggerCss;
35
+ //# sourceMappingURL=clickTriggerCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickTriggerCss.js","sourceRoot":"","sources":["../../../../src/implementations/v2/clickTriggerCss.ts"],"names":[],"mappings":";;;AAEA,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AAElG;;;GAGG;AACH,MAAM,4BAA4B,GAAG,CACjC,WAAyF,EACnF,EAAE;IACR,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,WAAW,CAAA;IACtE,MAAM,YAAY,GAAG,uBAAuB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAA;IAElE,IAAI,aAAa,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,UAAU,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,UAAU,IAAI,MAAM,EAAE,CAAA;QAEhH,OAAO,GAAG,YAAY,IAAI,KAAK,EAAE,CAAA;IACrC,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,GAAG,YAAY,IAAI,QAAQ,EAAE,CAAA;IACxC,CAAC;IAED,OAAO,GAAG,YAAY,iBAAiB,CAAA;AAC3C,CAAC,CAAA;AAED,6HAA6H;AACtH,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACjE,MAAM,SAAS,GAAG;QACd,GAAG,IAAI,GAAG,CACN,MAAM,CAAC,YAAY;aACd,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,OAAO,CAAC;aACtE,GAAG,CAAC,4BAA4B,CAAC,CACzC;KACJ,CAAA;IAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACb,CAAC;IAED,OAAO,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,QAAQ,yBAAyB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACrF,CAAC,CAAA;AAdY,QAAA,kBAAkB,sBAc9B"}
@@ -0,0 +1,3 @@
1
+ import type { InteractConfig } from '@wix/interact';
2
+ /** Emit animation FOUC CSS and click-trigger cursor rules. */
3
+ export declare const getV2ConfigCss: (config: InteractConfig) => string;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getV2ConfigCss = void 0;
37
+ const interact_v2_1 = require("@wix/interact-v2");
38
+ const motionPresets = __importStar(require("@wix/wix-motion-presets"));
39
+ const clickTriggerCss_1 = require("./clickTriggerCss");
40
+ // Interact's registry is process-global. This module is only pulled into the server bundle
41
+ // (`process.env.browser` DCE), so the namespace is registered once per Node process.
42
+ interact_v2_1.Interact.registerEffects(motionPresets);
43
+ /** Emit animation FOUC CSS and click-trigger cursor rules. */
44
+ const getV2ConfigCss = (config) => {
45
+ const animationCss = (0, interact_v2_1.generate)(config, true).trim();
46
+ const clickCss = (0, clickTriggerCss_1.getClickTriggerCss)(config).trim();
47
+ return [animationCss, clickCss].filter(Boolean).join('\n');
48
+ };
49
+ exports.getV2ConfigCss = getV2ConfigCss;
50
+ //# sourceMappingURL=configCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configCss.js","sourceRoot":"","sources":["../../../../src/implementations/v2/configCss.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAqD;AAGrD,uEAAwD;AACxD,uDAAsD;AAItD,2FAA2F;AAC3F,qFAAqF;AACrF,sBAAQ,CAAC,eAAe,CAAC,aAA0C,CAAC,CAAA;AAEpE,8DAA8D;AACvD,MAAM,cAAc,GAAG,CAAC,MAAsB,EAAU,EAAE;IAC7D,MAAM,YAAY,GAAG,IAAA,sBAAQ,EAAC,MAA0B,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IACtE,MAAM,QAAQ,GAAG,IAAA,oCAAkB,EAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IAElD,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC9D,CAAC,CAAA;AALY,QAAA,cAAc,kBAK1B"}
@@ -0,0 +1 @@
1
+ export declare const getV2ConfigStyleHeadContent: (css: string) => string;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getV2ConfigStyleHeadContent = void 0;
4
+ /**
5
+ * Head content is a raw HTML string, so anything tag-like in the generated CSS either closes the
6
+ * style element early or trips the head appender's script-tag guard, which throws. Nothing in CSS
7
+ * opens a tag: `<` appears only in media range queries, followed by a space or a digit. Cutting
8
+ * from the first `<` that could start a tag leaves valid CSS untouched.
9
+ */
10
+ const sanitizeCssForStyleElement = (css) => {
11
+ const tagIndex = css.search(/<[a-zA-Z/]/);
12
+ return tagIndex === -1 ? css : css.slice(0, tagIndex);
13
+ };
14
+ const getV2ConfigStyleHeadContent = (css) => `<style>${sanitizeCssForStyleElement(css)}</style>`;
15
+ exports.getV2ConfigStyleHeadContent = getV2ConfigStyleHeadContent;
16
+ //# sourceMappingURL=configStyleHeadContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configStyleHeadContent.js","sourceRoot":"","sources":["../../../../src/implementations/v2/configStyleHeadContent.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,MAAM,0BAA0B,GAAG,CAAC,GAAW,EAAU,EAAE;IACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACzC,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AACzD,CAAC,CAAA;AAEM,MAAM,2BAA2B,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,UAAU,0BAA0B,CAAC,GAAG,CAAC,UAAU,CAAA;AAA1G,QAAA,2BAA2B,+BAA+E"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
3
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
4
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
5
+ * would download each module twice.
6
+ */
7
+ export declare const getV2ModulePreloadHeadContent: () => string;
8
+ export declare const getV2InteractionsScriptContent: (configId: string, isReducedMotion: boolean) => string;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getV2InteractionsScriptContent = exports.getV2ModulePreloadHeadContent = void 0;
4
+ const cdnUrls_1 = require("./cdnUrls");
5
+ /**
6
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
7
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
8
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
9
+ * would download each module twice.
10
+ */
11
+ const getV2ModulePreloadHeadContent = () => `<link rel="modulepreload" href="${cdnUrls_1.INTERACT_V2_IMPORT_URL}"><link rel="modulepreload" href="${cdnUrls_1.WIX_MOTION_PRESETS_IMPORT_URL}">`;
12
+ exports.getV2ModulePreloadHeadContent = getV2ModulePreloadHeadContent;
13
+ const getV2InteractionsScriptContent = (configId, isReducedMotion) => [
14
+ `const configElement = document.getElementById(\`${configId}\`)`,
15
+ 'if (configElement) {',
16
+ ' const config = JSON.parse(configElement.textContent)',
17
+ ' const [{ Interact }, presets] = await Promise.all([',
18
+ ` import(\`${cdnUrls_1.INTERACT_V2_IMPORT_URL}\`),`,
19
+ ` import(\`${cdnUrls_1.WIX_MOTION_PRESETS_IMPORT_URL}\`),`,
20
+ ' ])',
21
+ ' Interact.registerEffects(presets)',
22
+ ` Interact.forceReducedMotion = ${isReducedMotion}`,
23
+ ' Interact.setup({',
24
+ ' scrollOptionsGetter: function () {',
25
+ ' return document.getElementById(`site-root`)',
26
+ ' },',
27
+ ' allowA11yTriggers: true,',
28
+ ' viewEnter: {',
29
+ ' useSafeViewEnter: true,',
30
+ ' },',
31
+ ' })',
32
+ ' Interact.create(config)',
33
+ '}',
34
+ ].join('\n');
35
+ exports.getV2InteractionsScriptContent = getV2InteractionsScriptContent;
36
+ //# sourceMappingURL=interactionsScriptContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactionsScriptContent.js","sourceRoot":"","sources":["../../../../src/implementations/v2/interactionsScriptContent.ts"],"names":[],"mappings":";;;AAAA,uCAAiF;AAEjF;;;;;GAKG;AACI,MAAM,6BAA6B,GAAG,GAAW,EAAE,CACtD,mCAAmC,gCAAsB,qCAAqC,uCAA6B,IAAI,CAAA;AADtH,QAAA,6BAA6B,iCACyF;AAE5H,MAAM,8BAA8B,GAAG,CAAC,QAAgB,EAAE,eAAwB,EAAU,EAAE,CACjG;IACI,mDAAmD,QAAQ,KAAK;IAChE,sBAAsB;IACtB,wDAAwD;IACxD,uDAAuD;IACvD,gBAAgB,gCAAsB,MAAM;IAC5C,gBAAgB,uCAA6B,MAAM;IACnD,MAAM;IACN,qCAAqC;IACrC,mCAAmC,eAAe,EAAE;IACpD,oBAAoB;IACpB,wCAAwC;IACxC,mDAAmD;IACnD,QAAQ;IACR,8BAA8B;IAC9B,kBAAkB;IAClB,+BAA+B;IAC/B,QAAQ;IACR,MAAM;IACN,2BAA2B;IAC3B,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAtBH,QAAA,8BAA8B,kCAsB3B"}
@@ -1,11 +1,21 @@
1
1
  import { Interact } from '@wix/interact';
2
2
  import { DeviceInfoDefinition } from '@wix/site-service-device-info/definition';
3
3
  import { ExperimentsDefinition } from '@wix/site-service-experiments/definition';
4
- import { RenderingContextDefinition } from '@wix/site-service-rendering-context/definition';
5
- import { PagesDefinition } from '@wix/site-service-pages/definition';
4
+ // Deliberately the deprecated pages service. Thunderbolt registers the site-service-pages page
5
+ // config only for sites that list it in `requiredServicesMap`, which ordinary sites do not, so
6
+ // `currentPage` falls back to EMPTY_PAGE and the id is ''. The legacy pages feature carries an
7
+ // explicit `interactionsFeature` escape hatch, so its config is populated for us.
8
+ import { PagesDefinition } from '@wix/viewer-service-pages/definition';
9
+ import { HeadAppenderDefinition } from '@wix/site-service-head-appender/definition';
10
+ import { HeadContentType } from '@wix/site-service-head-appender/types';
6
11
  import { ProvideComponentServiceDefinition } from '@wix/services-manager-react/core-services/provide-component';
7
12
  import { createInteractionsScriptElement } from './InteractionsScriptElement';
13
+ import { createV2InteractionsScriptElement } from './v2/InteractionsScriptElement';
14
+ import { getV2ConfigCss } from './v2/configCss';
15
+ import { getV2ConfigStyleHeadContent } from './v2/configStyleHeadContent';
16
+ import { getV2ModulePreloadHeadContent } from './v2/interactionsScriptContent';
8
17
  const initInteract = (config, isReducedMotion) => {
18
+ // Bundled runtime is v1. v2 on the client is the CDN loader.
9
19
  Interact.forceReducedMotion = isReducedMotion;
10
20
  Interact.setup({
11
21
  scrollOptionsGetter: () => globalThis.document.getElementById('site-root'),
@@ -16,45 +26,50 @@ const initInteract = (config, isReducedMotion) => {
16
26
  });
17
27
  Interact.create(config);
18
28
  };
19
- const tryInitInteractInSsr = (config, isReducedMotion, getService) => {
20
- const hasInteractions = config.interactions?.length > 0;
21
- if (!hasInteractions) {
22
- return false;
29
+ const initRuntime = (config, isReducedMotion, getService, useV2) => {
30
+ if (!config.interactions?.length) {
31
+ return;
23
32
  }
24
- const { currentPage } = getService(PagesDefinition);
25
- const pageId = currentPage?.id;
33
+ const pageId = getService(PagesDefinition).currentPageId();
26
34
  if (!pageId) {
27
- return false;
35
+ return;
28
36
  }
29
37
  const { addTopComponent } = getService(ProvideComponentServiceDefinition);
30
- const ssrScriptElement = createInteractionsScriptElement(config, isReducedMotion, pageId);
31
- addTopComponent(ssrScriptElement);
32
- return true;
38
+ const interactionsScript = useV2
39
+ ? createV2InteractionsScriptElement(config, isReducedMotion, pageId)
40
+ : createInteractionsScriptElement(config, isReducedMotion, pageId);
41
+ addTopComponent(interactionsScript);
33
42
  };
34
43
  const getInteractiveComps = (interactions) => interactions.reduce((acc, { key, effects }) => {
35
44
  // add trigger comp
36
45
  acc.add(key);
37
46
  // add reaction comps
38
47
  // there must be a key
39
- effects.forEach(({ key }) => acc.add(key));
48
+ effects?.forEach(({ key }) => acc.add(key));
40
49
  return acc;
41
50
  }, new Set());
42
51
  export const coreInteractions = (config, getService) => {
43
52
  const { reducedMotion: isReducedMotion } = getService(DeviceInfoDefinition);
44
53
  const { isOpen } = getService(ExperimentsDefinition);
45
- const { SSR } = getService(RenderingContextDefinition);
46
- const isSSRExperimentOpen = isOpen('specs.thunderbolt.interactionsInSsr');
47
- if (isSSRExperimentOpen) {
54
+ if (isOpen('specs.thunderbolt.vsm_interactions_v2')) {
55
+ // Both belong in the head: the preload links only help while the document is still parsing,
56
+ // and the generated CSS hides elements before their entrance effect, so it has to apply
57
+ // before the body renders.
58
+ if (!process.env.browser) {
59
+ const css = getV2ConfigCss(config).trim();
60
+ // GENERAL rather than setHead's AFTER_SECURITY default: thunderbolt only reads the
61
+ // after-security bucket on its SEO path, so the default drops this on every normal
62
+ // request. GENERAL reaches the document as raw markup before `</head>`.
63
+ getService(HeadAppenderDefinition).setHead(getV2ModulePreloadHeadContent() + (css ? getV2ConfigStyleHeadContent(css) : ''), HeadContentType.GENERAL);
64
+ }
65
+ initRuntime(config, isReducedMotion, getService, true);
66
+ }
67
+ else if (isOpen('specs.thunderbolt.interactionsInSsr')) {
48
68
  // Emits the config and loader scripts. Works in both environments: SSR serves markup the
49
69
  // parser executes, and on the client the loader's ref revives it into a script that runs —
50
70
  // which is what pages rendered only on the client (password-protected / members-only,
51
71
  // client-side navigation) need, since they never get a server-rendered document.
52
- const didInitInteractInSsr = tryInitInteractInSsr(config, isReducedMotion, getService);
53
- // Fall back to direct init on the client if the script element could not be set up
54
- // (e.g. no pageId or no interactions).
55
- if (!didInitInteractInSsr && !SSR) {
56
- initInteract(config, isReducedMotion);
57
- }
72
+ initRuntime(config, isReducedMotion, getService, false);
58
73
  }
59
74
  else {
60
75
  initInteract(config, isReducedMotion);
@@ -1 +1 @@
1
- {"version":3,"file":"coreInteractions.js","sourceRoot":"","sources":["../../src/implementations/coreInteractions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coreInteractions.js","sourceRoot":"","sources":["../../src/implementations/coreInteractions.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const wixInteractElementCss = "\n wix-interact-element {\n display: contents;\n }\n ";
1
+ export declare const wixInteractElementCss = "\n interact-element {\n display: contents;\n }\n ";
2
2
  export declare const hasClickTriggerCss = "\n .has-click-trigger {\n cursor: pointer;\n }\n ";
@@ -1,5 +1,5 @@
1
1
  export const wixInteractElementCss = `
2
- wix-interact-element {
2
+ interact-element {
3
3
  display: contents;
4
4
  }
5
5
  `;
@@ -0,0 +1,3 @@
1
+ import type { FunctionComponent } from 'react';
2
+ import type { InteractConfig } from '@wix/interact';
3
+ export declare const createV2InteractionsScriptElement: (config: InteractConfig, isReducedMotion: boolean, pageId: string) => FunctionComponent;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { reviveScriptElement } from '../reviveScriptElement';
3
+ import { getV2InteractionsScriptContent } from './interactionsScriptContent';
4
+ const DANGEROUSLY_SET_INNER_HTML = ['dangerously', 'Set', 'Inner', 'HTML'];
5
+ /**
6
+ * The config is written as raw markup, so a `</script` inside any string value would close the
7
+ * element early. `\u003c` is valid JSON that `JSON.parse` reads back as `<`.
8
+ */
9
+ const serializeConfigForScriptElement = (config) => JSON.stringify(config).replace(/</g, '\\u003c');
10
+ export const createV2InteractionsScriptElement = (config, isReducedMotion, pageId) => () => {
11
+ // This ID is also interpolated into raw module-script text. Percent-encoding removes
12
+ // script delimiters and template-literal syntax while keeping the ID deterministic.
13
+ const safePageId = encodeURIComponent(pageId);
14
+ const configId = `interactions-config-${safePageId}`;
15
+ const interactionsScriptContent = getV2InteractionsScriptContent(configId, isReducedMotion);
16
+ const configProps = {
17
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: serializeConfigForScriptElement(config) },
18
+ };
19
+ const loaderProps = {
20
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: interactionsScriptContent },
21
+ };
22
+ return (React.createElement(React.Fragment, null,
23
+ React.createElement("script", { type: "application/json", id: configId, ...configProps }),
24
+ React.createElement("script", { type: "module", id: `interactions-loader-${safePageId}`, ref: reviveScriptElement, ...loaderProps })));
25
+ };
26
+ //# sourceMappingURL=InteractionsScriptElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractionsScriptElement.js","sourceRoot":"","sources":["../../../src/implementations/v2/InteractionsScriptElement.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,MAAM,0BAA0B,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AAE1E;;;GAGG;AACH,MAAM,+BAA+B,GAAG,CAAC,MAAsB,EAAU,EAAE,CACvE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;AAEnD,MAAM,CAAC,MAAM,iCAAiC,GAC1C,CAAC,MAAsB,EAAE,eAAwB,EAAE,MAAc,EAAqB,EAAE,CACxF,GAAG,EAAE;IACD,qFAAqF;IACrF,oFAAoF;IACpF,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,uBAAuB,UAAU,EAAE,CAAA;IACpD,MAAM,yBAAyB,GAAG,8BAA8B,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAA;IAC3F,MAAM,WAAW,GAAG;QAChB,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,+BAA+B,CAAC,MAAM,CAAC,EAAE;KAC7F,CAAA;IACD,MAAM,WAAW,GAAG;QAChB,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,yBAAyB,EAAE;KAC/E,CAAA;IAED,OAAO,CACH;QACI,gCAAQ,IAAI,EAAC,kBAAkB,EAAC,EAAE,EAAE,QAAQ,KAAM,WAAW,GAAI;QACjE,gCACI,IAAI,EAAC,QAAQ,EACb,EAAE,EAAE,uBAAuB,UAAU,EAAE,EACvC,GAAG,EAAE,mBAAmB,KACpB,WAAW,GACjB,CACH,CACN,CAAA;AACL,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const INTERACT_V2_IMPORT_URL = "https://cdn.jsdelivr.net/npm/@wix/interact@2.5.14/dist/es/web.min.js";
2
+ export declare const WIX_MOTION_PRESETS_IMPORT_URL = "https://cdn.jsdelivr.net/npm/@wix/wix-motion-presets@1.0.0/+esm";
@@ -0,0 +1,3 @@
1
+ export const INTERACT_V2_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/interact@2.5.14/dist/es/web.min.js';
2
+ export const WIX_MOTION_PRESETS_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/wix-motion-presets@1.0.0/+esm';
3
+ //# sourceMappingURL=cdnUrls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdnUrls.js","sourceRoot":"","sources":["../../../src/implementations/v2/cdnUrls.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,sEAAsE,CAAA;AAE5G,MAAM,CAAC,MAAM,6BAA6B,GAAG,iEAAiE,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { InteractConfig } from '@wix/interact';
2
+ /** Emits `cursor: pointer` for click interaction triggers (`'activate' || 'click'`), one rule per unique source selector. */
3
+ export declare const getClickTriggerCss: (config: InteractConfig) => string;
@@ -0,0 +1,31 @@
1
+ const escapeCssAttr = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
2
+ /**
3
+ * Mirrors `@wix/interact` `getSelector(interaction, { asCombinator: true, useFirstChild: true })`
4
+ * plus the `[data-interact-key="…"]` prefix from `CSSRuleToString`.
5
+ */
6
+ const getInteractionSourceSelector = (interaction) => {
7
+ const { key, selector, listContainer, listItemSelector } = interaction;
8
+ const attrSelector = `[data-interact-key="${escapeCssAttr(key)}"]`;
9
+ if (listContainer) {
10
+ const itemFilter = listItemSelector ? ` > ${listItemSelector}` : '';
11
+ const inner = selector ? `${listContainer}${itemFilter} ${selector}` : `${listContainer}${itemFilter || ' > *'}`;
12
+ return `${attrSelector} ${inner}`;
13
+ }
14
+ if (selector) {
15
+ return `${attrSelector} ${selector}`;
16
+ }
17
+ return `${attrSelector} > :first-child`;
18
+ };
19
+ /** Emits `cursor: pointer` for click interaction triggers (`'activate' || 'click'`), one rule per unique source selector. */
20
+ export const getClickTriggerCss = (config) => {
21
+ const selectors = [
22
+ ...new Set(config.interactions
23
+ .filter(({ trigger }) => trigger === 'activate' || trigger === 'click')
24
+ .map(getInteractionSourceSelector)),
25
+ ];
26
+ if (!selectors.length) {
27
+ return '';
28
+ }
29
+ return selectors.map(selector => `${selector} {\ncursor: pointer;\n}`).join('\n');
30
+ };
31
+ //# sourceMappingURL=clickTriggerCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickTriggerCss.js","sourceRoot":"","sources":["../../../src/implementations/v2/clickTriggerCss.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AAElG;;;GAGG;AACH,MAAM,4BAA4B,GAAG,CACjC,WAAyF,EACnF,EAAE;IACR,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,WAAW,CAAA;IACtE,MAAM,YAAY,GAAG,uBAAuB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAA;IAElE,IAAI,aAAa,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,UAAU,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,UAAU,IAAI,MAAM,EAAE,CAAA;QAEhH,OAAO,GAAG,YAAY,IAAI,KAAK,EAAE,CAAA;IACrC,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,GAAG,YAAY,IAAI,QAAQ,EAAE,CAAA;IACxC,CAAC;IAED,OAAO,GAAG,YAAY,iBAAiB,CAAA;AAC3C,CAAC,CAAA;AAED,6HAA6H;AAC7H,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACjE,MAAM,SAAS,GAAG;QACd,GAAG,IAAI,GAAG,CACN,MAAM,CAAC,YAAY;aACd,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,OAAO,CAAC;aACtE,GAAG,CAAC,4BAA4B,CAAC,CACzC;KACJ,CAAA;IAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACb,CAAC;IAED,OAAO,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,QAAQ,yBAAyB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACrF,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { InteractConfig } from '@wix/interact';
2
+ /** Emit animation FOUC CSS and click-trigger cursor rules. */
3
+ export declare const getV2ConfigCss: (config: InteractConfig) => string;
@@ -0,0 +1,13 @@
1
+ import { generate, Interact } from '@wix/interact-v2';
2
+ import * as motionPresets from '@wix/wix-motion-presets';
3
+ import { getClickTriggerCss } from './clickTriggerCss';
4
+ // Interact's registry is process-global. This module is only pulled into the server bundle
5
+ // (`process.env.browser` DCE), so the namespace is registered once per Node process.
6
+ Interact.registerEffects(motionPresets);
7
+ /** Emit animation FOUC CSS and click-trigger cursor rules. */
8
+ export const getV2ConfigCss = (config) => {
9
+ const animationCss = generate(config, true).trim();
10
+ const clickCss = getClickTriggerCss(config).trim();
11
+ return [animationCss, clickCss].filter(Boolean).join('\n');
12
+ };
13
+ //# sourceMappingURL=configCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configCss.js","sourceRoot":"","sources":["../../../src/implementations/v2/configCss.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAGrD,OAAO,KAAK,aAAa,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAItD,2FAA2F;AAC3F,qFAAqF;AACrF,QAAQ,CAAC,eAAe,CAAC,aAA0C,CAAC,CAAA;AAEpE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAsB,EAAU,EAAE;IAC7D,MAAM,YAAY,GAAG,QAAQ,CAAC,MAA0B,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IACtE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IAElD,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC9D,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const getV2ConfigStyleHeadContent: (css: string) => string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Head content is a raw HTML string, so anything tag-like in the generated CSS either closes the
3
+ * style element early or trips the head appender's script-tag guard, which throws. Nothing in CSS
4
+ * opens a tag: `<` appears only in media range queries, followed by a space or a digit. Cutting
5
+ * from the first `<` that could start a tag leaves valid CSS untouched.
6
+ */
7
+ const sanitizeCssForStyleElement = (css) => {
8
+ const tagIndex = css.search(/<[a-zA-Z/]/);
9
+ return tagIndex === -1 ? css : css.slice(0, tagIndex);
10
+ };
11
+ export const getV2ConfigStyleHeadContent = (css) => `<style>${sanitizeCssForStyleElement(css)}</style>`;
12
+ //# sourceMappingURL=configStyleHeadContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configStyleHeadContent.js","sourceRoot":"","sources":["../../../src/implementations/v2/configStyleHeadContent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,0BAA0B,GAAG,CAAC,GAAW,EAAU,EAAE;IACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACzC,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AACzD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,UAAU,0BAA0B,CAAC,GAAG,CAAC,UAAU,CAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
3
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
4
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
5
+ * would download each module twice.
6
+ */
7
+ export declare const getV2ModulePreloadHeadContent: () => string;
8
+ export declare const getV2InteractionsScriptContent: (configId: string, isReducedMotion: boolean) => string;
@@ -0,0 +1,31 @@
1
+ import { INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL } from './cdnUrls';
2
+ /**
3
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
4
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
5
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
6
+ * would download each module twice.
7
+ */
8
+ export const getV2ModulePreloadHeadContent = () => `<link rel="modulepreload" href="${INTERACT_V2_IMPORT_URL}"><link rel="modulepreload" href="${WIX_MOTION_PRESETS_IMPORT_URL}">`;
9
+ export const getV2InteractionsScriptContent = (configId, isReducedMotion) => [
10
+ `const configElement = document.getElementById(\`${configId}\`)`,
11
+ 'if (configElement) {',
12
+ ' const config = JSON.parse(configElement.textContent)',
13
+ ' const [{ Interact }, presets] = await Promise.all([',
14
+ ` import(\`${INTERACT_V2_IMPORT_URL}\`),`,
15
+ ` import(\`${WIX_MOTION_PRESETS_IMPORT_URL}\`),`,
16
+ ' ])',
17
+ ' Interact.registerEffects(presets)',
18
+ ` Interact.forceReducedMotion = ${isReducedMotion}`,
19
+ ' Interact.setup({',
20
+ ' scrollOptionsGetter: function () {',
21
+ ' return document.getElementById(`site-root`)',
22
+ ' },',
23
+ ' allowA11yTriggers: true,',
24
+ ' viewEnter: {',
25
+ ' useSafeViewEnter: true,',
26
+ ' },',
27
+ ' })',
28
+ ' Interact.create(config)',
29
+ '}',
30
+ ].join('\n');
31
+ //# sourceMappingURL=interactionsScriptContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactionsScriptContent.js","sourceRoot":"","sources":["../../../src/implementations/v2/interactionsScriptContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAA;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAW,EAAE,CACtD,mCAAmC,sBAAsB,qCAAqC,6BAA6B,IAAI,CAAA;AAEnI,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,QAAgB,EAAE,eAAwB,EAAU,EAAE,CACjG;IACI,mDAAmD,QAAQ,KAAK;IAChE,sBAAsB;IACtB,wDAAwD;IACxD,uDAAuD;IACvD,gBAAgB,sBAAsB,MAAM;IAC5C,gBAAgB,6BAA6B,MAAM;IACnD,MAAM;IACN,qCAAqC;IACrC,mCAAmC,eAAe,EAAE;IACpD,oBAAoB;IACpB,wCAAwC;IACxC,mDAAmD;IACnD,QAAQ;IACR,8BAA8B;IAC9B,kBAAkB;IAClB,+BAA+B;IAC/B,QAAQ;IACR,MAAM;IACN,2BAA2B;IAC3B,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/site-service-interactions",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "main": "cjs/build/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,18 +44,22 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@wix/interact": "^1.103.0",
47
+ "@wix/interact-v2": "npm:@wix/interact@^2.5.14",
47
48
  "@wix/services-manager": "^0.2.20",
48
49
  "@wix/services-manager-react": "^0.1.26",
49
50
  "@wix/site-service-device-info": "1.0.2",
50
51
  "@wix/site-service-experiments": "1.0.3",
51
- "@wix/site-service-pages": "1.1.0",
52
+ "@wix/site-service-head-appender": "1.0.1",
52
53
  "@wix/site-service-provide-css": "1.0.1",
53
- "@wix/site-service-rendering-context": "1.0.1",
54
- "@wix/static-service": "1.0.19"
54
+ "@wix/static-service": "1.0.19",
55
+ "@wix/viewer-service-pages": "1.0.11",
56
+ "@wix/wix-motion-presets": "^1.0.0"
55
57
  },
56
58
  "devDependencies": {
57
59
  "@types/react": "^18.3.1",
60
+ "@types/react-dom": "^18.3.1",
58
61
  "react": "^18.3.1",
62
+ "react-dom": "^18.3.1",
59
63
  "typescript": "^5.3.3",
60
64
  "vitest": "4.1.0"
61
65
  },
@@ -90,5 +94,5 @@
90
94
  ]
91
95
  }
92
96
  },
93
- "falconPackageHash": "629f3f89a2fc1e079366d274ab06644e0a74eba7c695c37d6f234e61"
97
+ "falconPackageHash": "734ab56bc526bfeff605dd11b9244ff0ef20ff101b76e970334c2137"
94
98
  }
@@ -2,13 +2,23 @@ import { Interact } from '@wix/interact'
2
2
  import type { InteractConfig } from '@wix/interact'
3
3
  import { DeviceInfoDefinition } from '@wix/site-service-device-info/definition'
4
4
  import { ExperimentsDefinition } from '@wix/site-service-experiments/definition'
5
- import { RenderingContextDefinition } from '@wix/site-service-rendering-context/definition'
6
- import { PagesDefinition } from '@wix/site-service-pages/definition'
5
+ // Deliberately the deprecated pages service. Thunderbolt registers the site-service-pages page
6
+ // config only for sites that list it in `requiredServicesMap`, which ordinary sites do not, so
7
+ // `currentPage` falls back to EMPTY_PAGE and the id is ''. The legacy pages feature carries an
8
+ // explicit `interactionsFeature` escape hatch, so its config is populated for us.
9
+ import { PagesDefinition } from '@wix/viewer-service-pages/definition'
10
+ import { HeadAppenderDefinition } from '@wix/site-service-head-appender/definition'
11
+ import { HeadContentType } from '@wix/site-service-head-appender/types'
7
12
  import { ProvideComponentServiceDefinition } from '@wix/services-manager-react/core-services/provide-component'
8
13
  import type { ServicesManager } from '@wix/services-manager/types'
9
14
  import { createInteractionsScriptElement } from './InteractionsScriptElement'
15
+ import { createV2InteractionsScriptElement } from './v2/InteractionsScriptElement'
16
+ import { getV2ConfigCss } from './v2/configCss'
17
+ import { getV2ConfigStyleHeadContent } from './v2/configStyleHeadContent'
18
+ import { getV2ModulePreloadHeadContent } from './v2/interactionsScriptContent'
10
19
 
11
20
  const initInteract = (config: InteractConfig, isReducedMotion: boolean) => {
21
+ // Bundled runtime is v1. v2 on the client is the CDN loader.
12
22
  Interact.forceReducedMotion = isReducedMotion
13
23
  Interact.setup({
14
24
  scrollOptionsGetter: () => globalThis.document.getElementById('site-root'),
@@ -20,28 +30,28 @@ const initInteract = (config: InteractConfig, isReducedMotion: boolean) => {
20
30
  Interact.create(config)
21
31
  }
22
32
 
23
- const tryInitInteractInSsr = (
33
+ const initRuntime = (
24
34
  config: InteractConfig,
25
35
  isReducedMotion: boolean,
26
- getService: ServicesManager['getService']
36
+ getService: ServicesManager['getService'],
37
+ useV2: boolean
27
38
  ) => {
28
- const hasInteractions = config.interactions?.length > 0
29
- if (!hasInteractions) {
30
- return false
39
+ if (!config.interactions?.length) {
40
+ return
31
41
  }
32
42
 
33
- const { currentPage } = getService(PagesDefinition)
34
- const pageId = currentPage?.id
35
-
43
+ const pageId = getService(PagesDefinition).currentPageId()
36
44
  if (!pageId) {
37
- return false
45
+ return
38
46
  }
39
47
 
40
48
  const { addTopComponent } = getService(ProvideComponentServiceDefinition)
41
- const ssrScriptElement = createInteractionsScriptElement(config, isReducedMotion, pageId)
42
- addTopComponent(ssrScriptElement)
43
49
 
44
- return true
50
+ const interactionsScript = useV2
51
+ ? createV2InteractionsScriptElement(config, isReducedMotion, pageId)
52
+ : createInteractionsScriptElement(config, isReducedMotion, pageId)
53
+
54
+ addTopComponent(interactionsScript)
45
55
  }
46
56
 
47
57
  const getInteractiveComps = (interactions: InteractConfig['interactions']) =>
@@ -50,7 +60,7 @@ const getInteractiveComps = (interactions: InteractConfig['interactions']) =>
50
60
  acc.add(key)
51
61
  // add reaction comps
52
62
  // there must be a key
53
- effects.forEach(({ key }) => acc.add(key!))
63
+ effects?.forEach(({ key }) => acc.add(key!))
54
64
 
55
65
  return acc
56
66
  }, new Set<string>())
@@ -58,21 +68,29 @@ const getInteractiveComps = (interactions: InteractConfig['interactions']) =>
58
68
  export const coreInteractions = (config: InteractConfig, getService: ServicesManager['getService']) => {
59
69
  const { reducedMotion: isReducedMotion } = getService(DeviceInfoDefinition)
60
70
  const { isOpen } = getService(ExperimentsDefinition)
61
- const { SSR } = getService(RenderingContextDefinition)
62
71
 
63
- const isSSRExperimentOpen = isOpen('specs.thunderbolt.interactionsInSsr')
64
- if (isSSRExperimentOpen) {
72
+ if (isOpen('specs.thunderbolt.vsm_interactions_v2')) {
73
+ // Both belong in the head: the preload links only help while the document is still parsing,
74
+ // and the generated CSS hides elements before their entrance effect, so it has to apply
75
+ // before the body renders.
76
+ if (!process.env.browser) {
77
+ const css = getV2ConfigCss(config).trim()
78
+ // GENERAL rather than setHead's AFTER_SECURITY default: thunderbolt only reads the
79
+ // after-security bucket on its SEO path, so the default drops this on every normal
80
+ // request. GENERAL reaches the document as raw markup before `</head>`.
81
+ getService(HeadAppenderDefinition).setHead(
82
+ getV2ModulePreloadHeadContent() + (css ? getV2ConfigStyleHeadContent(css) : ''),
83
+ HeadContentType.GENERAL
84
+ )
85
+ }
86
+
87
+ initRuntime(config, isReducedMotion, getService, true)
88
+ } else if (isOpen('specs.thunderbolt.interactionsInSsr')) {
65
89
  // Emits the config and loader scripts. Works in both environments: SSR serves markup the
66
90
  // parser executes, and on the client the loader's ref revives it into a script that runs —
67
91
  // which is what pages rendered only on the client (password-protected / members-only,
68
92
  // client-side navigation) need, since they never get a server-rendered document.
69
- const didInitInteractInSsr = tryInitInteractInSsr(config, isReducedMotion, getService)
70
-
71
- // Fall back to direct init on the client if the script element could not be set up
72
- // (e.g. no pageId or no interactions).
73
- if (!didInitInteractInSsr && !SSR) {
74
- initInteract(config, isReducedMotion)
75
- }
93
+ initRuntime(config, isReducedMotion, getService, false)
76
94
  } else {
77
95
  initInteract(config, isReducedMotion)
78
96
  }
@@ -1,5 +1,5 @@
1
1
  export const wixInteractElementCss = `
2
- wix-interact-element {
2
+ interact-element {
3
3
  display: contents;
4
4
  }
5
5
  `
@@ -0,0 +1,42 @@
1
+ import React from 'react'
2
+ import type { FunctionComponent } from 'react'
3
+ import type { InteractConfig } from '@wix/interact'
4
+ import { reviveScriptElement } from '../reviveScriptElement'
5
+ import { getV2InteractionsScriptContent } from './interactionsScriptContent'
6
+
7
+ const DANGEROUSLY_SET_INNER_HTML = ['dangerously', 'Set', 'Inner', 'HTML']
8
+
9
+ /**
10
+ * The config is written as raw markup, so a `</script` inside any string value would close the
11
+ * element early. `\u003c` is valid JSON that `JSON.parse` reads back as `<`.
12
+ */
13
+ const serializeConfigForScriptElement = (config: InteractConfig): string =>
14
+ JSON.stringify(config).replace(/</g, '\\u003c')
15
+
16
+ export const createV2InteractionsScriptElement =
17
+ (config: InteractConfig, isReducedMotion: boolean, pageId: string): FunctionComponent =>
18
+ () => {
19
+ // This ID is also interpolated into raw module-script text. Percent-encoding removes
20
+ // script delimiters and template-literal syntax while keeping the ID deterministic.
21
+ const safePageId = encodeURIComponent(pageId)
22
+ const configId = `interactions-config-${safePageId}`
23
+ const interactionsScriptContent = getV2InteractionsScriptContent(configId, isReducedMotion)
24
+ const configProps = {
25
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: serializeConfigForScriptElement(config) },
26
+ }
27
+ const loaderProps = {
28
+ [DANGEROUSLY_SET_INNER_HTML.join('')]: { __html: interactionsScriptContent },
29
+ }
30
+
31
+ return (
32
+ <>
33
+ <script type="application/json" id={configId} {...configProps} />
34
+ <script
35
+ type="module"
36
+ id={`interactions-loader-${safePageId}`}
37
+ ref={reviveScriptElement}
38
+ {...loaderProps}
39
+ />
40
+ </>
41
+ )
42
+ }
@@ -0,0 +1,3 @@
1
+ export const INTERACT_V2_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/interact@2.5.14/dist/es/web.min.js'
2
+
3
+ export const WIX_MOTION_PRESETS_IMPORT_URL = 'https://cdn.jsdelivr.net/npm/@wix/wix-motion-presets@1.0.0/+esm'
@@ -0,0 +1,44 @@
1
+ import type { InteractConfig, Interaction } from '@wix/interact'
2
+
3
+ const escapeCssAttr = (value: string): string => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
4
+
5
+ /**
6
+ * Mirrors `@wix/interact` `getSelector(interaction, { asCombinator: true, useFirstChild: true })`
7
+ * plus the `[data-interact-key="…"]` prefix from `CSSRuleToString`.
8
+ */
9
+ const getInteractionSourceSelector = (
10
+ interaction: Pick<Interaction, 'key' | 'selector' | 'listContainer' | 'listItemSelector'>
11
+ ): string => {
12
+ const { key, selector, listContainer, listItemSelector } = interaction
13
+ const attrSelector = `[data-interact-key="${escapeCssAttr(key)}"]`
14
+
15
+ if (listContainer) {
16
+ const itemFilter = listItemSelector ? ` > ${listItemSelector}` : ''
17
+ const inner = selector ? `${listContainer}${itemFilter} ${selector}` : `${listContainer}${itemFilter || ' > *'}`
18
+
19
+ return `${attrSelector} ${inner}`
20
+ }
21
+
22
+ if (selector) {
23
+ return `${attrSelector} ${selector}`
24
+ }
25
+
26
+ return `${attrSelector} > :first-child`
27
+ }
28
+
29
+ /** Emits `cursor: pointer` for click interaction triggers (`'activate' || 'click'`), one rule per unique source selector. */
30
+ export const getClickTriggerCss = (config: InteractConfig): string => {
31
+ const selectors = [
32
+ ...new Set(
33
+ config.interactions
34
+ .filter(({ trigger }) => trigger === 'activate' || trigger === 'click')
35
+ .map(getInteractionSourceSelector)
36
+ ),
37
+ ]
38
+
39
+ if (!selectors.length) {
40
+ return ''
41
+ }
42
+
43
+ return selectors.map(selector => `${selector} {\ncursor: pointer;\n}`).join('\n')
44
+ }
@@ -0,0 +1,19 @@
1
+ import { generate, Interact } from '@wix/interact-v2'
2
+ import type { InteractConfig } from '@wix/interact'
3
+ import type { InteractConfig as InteractV2Config } from '@wix/interact-v2'
4
+ import * as motionPresets from '@wix/wix-motion-presets'
5
+ import { getClickTriggerCss } from './clickTriggerCss'
6
+
7
+ type PresetRegistry = Parameters<typeof Interact.registerEffects>[0]
8
+
9
+ // Interact's registry is process-global. This module is only pulled into the server bundle
10
+ // (`process.env.browser` DCE), so the namespace is registered once per Node process.
11
+ Interact.registerEffects(motionPresets as unknown as PresetRegistry)
12
+
13
+ /** Emit animation FOUC CSS and click-trigger cursor rules. */
14
+ export const getV2ConfigCss = (config: InteractConfig): string => {
15
+ const animationCss = generate(config as InteractV2Config, true).trim()
16
+ const clickCss = getClickTriggerCss(config).trim()
17
+
18
+ return [animationCss, clickCss].filter(Boolean).join('\n')
19
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Head content is a raw HTML string, so anything tag-like in the generated CSS either closes the
3
+ * style element early or trips the head appender's script-tag guard, which throws. Nothing in CSS
4
+ * opens a tag: `<` appears only in media range queries, followed by a space or a digit. Cutting
5
+ * from the first `<` that could start a tag leaves valid CSS untouched.
6
+ */
7
+ const sanitizeCssForStyleElement = (css: string): string => {
8
+ const tagIndex = css.search(/<[a-zA-Z/]/)
9
+ return tagIndex === -1 ? css : css.slice(0, tagIndex)
10
+ }
11
+
12
+ export const getV2ConfigStyleHeadContent = (css: string): string => `<style>${sanitizeCssForStyleElement(css)}</style>`
@@ -0,0 +1,34 @@
1
+ import { INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL } from './cdnUrls'
2
+
3
+ /**
4
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
5
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
6
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
7
+ * would download each module twice.
8
+ */
9
+ export const getV2ModulePreloadHeadContent = (): string =>
10
+ `<link rel="modulepreload" href="${INTERACT_V2_IMPORT_URL}"><link rel="modulepreload" href="${WIX_MOTION_PRESETS_IMPORT_URL}">`
11
+
12
+ export const getV2InteractionsScriptContent = (configId: string, isReducedMotion: boolean): string =>
13
+ [
14
+ `const configElement = document.getElementById(\`${configId}\`)`,
15
+ 'if (configElement) {',
16
+ ' const config = JSON.parse(configElement.textContent)',
17
+ ' const [{ Interact }, presets] = await Promise.all([',
18
+ ` import(\`${INTERACT_V2_IMPORT_URL}\`),`,
19
+ ` import(\`${WIX_MOTION_PRESETS_IMPORT_URL}\`),`,
20
+ ' ])',
21
+ ' Interact.registerEffects(presets)',
22
+ ` Interact.forceReducedMotion = ${isReducedMotion}`,
23
+ ' Interact.setup({',
24
+ ' scrollOptionsGetter: function () {',
25
+ ' return document.getElementById(`site-root`)',
26
+ ' },',
27
+ ' allowA11yTriggers: true,',
28
+ ' viewEnter: {',
29
+ ' useSafeViewEnter: true,',
30
+ ' },',
31
+ ' })',
32
+ ' Interact.create(config)',
33
+ '}',
34
+ ].join('\n')