@wix/site-service-interactions 1.0.9 → 1.0.10

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 (74) hide show
  1. package/cjs/build/implementations/coreInteractions.js +34 -26
  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 +15 -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 +9 -0
  21. package/cjs/build/implementations/v2/interactionsScriptContent.js +52 -0
  22. package/cjs/build/implementations/v2/interactionsScriptContent.js.map +1 -0
  23. package/cjs/build/implementations/v2/motionPresets.d.ts +13 -0
  24. package/cjs/build/implementations/v2/motionPresets.js +54 -0
  25. package/cjs/build/implementations/v2/motionPresets.js.map +1 -0
  26. package/cjs/build/implementations/v2/namedEffectTypes.d.ts +2 -0
  27. package/cjs/build/implementations/v2/namedEffectTypes.js +42 -0
  28. package/cjs/build/implementations/v2/namedEffectTypes.js.map +1 -0
  29. package/cjs/build/implementations/v2/registerConfigEffects.d.ts +6 -0
  30. package/cjs/build/implementations/v2/registerConfigEffects.js +27 -0
  31. package/cjs/build/implementations/v2/registerConfigEffects.js.map +1 -0
  32. package/dist/implementations/coreInteractions.js +30 -22
  33. package/dist/implementations/coreInteractions.js.map +1 -1
  34. package/dist/implementations/stylesToAdd.d.ts +1 -1
  35. package/dist/implementations/stylesToAdd.js +1 -1
  36. package/dist/implementations/v2/InteractionsScriptElement.d.ts +3 -0
  37. package/dist/implementations/v2/InteractionsScriptElement.js +26 -0
  38. package/dist/implementations/v2/InteractionsScriptElement.js.map +1 -0
  39. package/dist/implementations/v2/cdnUrls.d.ts +2 -0
  40. package/dist/implementations/v2/cdnUrls.js +3 -0
  41. package/dist/implementations/v2/cdnUrls.js.map +1 -0
  42. package/dist/implementations/v2/clickTriggerCss.d.ts +3 -0
  43. package/dist/implementations/v2/clickTriggerCss.js +31 -0
  44. package/dist/implementations/v2/clickTriggerCss.js.map +1 -0
  45. package/dist/implementations/v2/configCss.d.ts +3 -0
  46. package/dist/implementations/v2/configCss.js +11 -0
  47. package/dist/implementations/v2/configCss.js.map +1 -0
  48. package/dist/implementations/v2/configStyleHeadContent.d.ts +1 -0
  49. package/dist/implementations/v2/configStyleHeadContent.js +12 -0
  50. package/dist/implementations/v2/configStyleHeadContent.js.map +1 -0
  51. package/dist/implementations/v2/interactionsScriptContent.d.ts +9 -0
  52. package/dist/implementations/v2/interactionsScriptContent.js +47 -0
  53. package/dist/implementations/v2/interactionsScriptContent.js.map +1 -0
  54. package/dist/implementations/v2/motionPresets.d.ts +13 -0
  55. package/dist/implementations/v2/motionPresets.js +16 -0
  56. package/dist/implementations/v2/motionPresets.js.map +1 -0
  57. package/dist/implementations/v2/namedEffectTypes.d.ts +2 -0
  58. package/dist/implementations/v2/namedEffectTypes.js +38 -0
  59. package/dist/implementations/v2/namedEffectTypes.js.map +1 -0
  60. package/dist/implementations/v2/registerConfigEffects.d.ts +6 -0
  61. package/dist/implementations/v2/registerConfigEffects.js +23 -0
  62. package/dist/implementations/v2/registerConfigEffects.js.map +1 -0
  63. package/package.json +8 -5
  64. package/src/implementations/coreInteractions.ts +36 -25
  65. package/src/implementations/stylesToAdd.ts +1 -1
  66. package/src/implementations/v2/InteractionsScriptElement.tsx +42 -0
  67. package/src/implementations/v2/cdnUrls.ts +4 -0
  68. package/src/implementations/v2/clickTriggerCss.ts +44 -0
  69. package/src/implementations/v2/configCss.ts +13 -0
  70. package/src/implementations/v2/configStyleHeadContent.ts +12 -0
  71. package/src/implementations/v2/interactionsScriptContent.ts +61 -0
  72. package/src/implementations/v2/motionPresets.ts +26 -0
  73. package/src/implementations/v2/namedEffectTypes.ts +52 -0
  74. package/src/implementations/v2/registerConfigEffects.ts +31 -0
@@ -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,61 @@
1
+ import type { InteractConfig } from '@wix/interact'
2
+ import { INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL } from './cdnUrls'
3
+ import { collectNamedEffectTypes } from './namedEffectTypes'
4
+ import { filterKnownPresetTypes } from './motionPresets'
5
+
6
+ const getPresetTypes = (config: InteractConfig): string[] => filterKnownPresetTypes(collectNamedEffectTypes(config))
7
+
8
+ const getModuleUrls = (presetTypes: string[]): string[] =>
9
+ presetTypes.length > 0 ? [INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL] : [INTERACT_V2_IMPORT_URL]
10
+
11
+ /**
12
+ * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
13
+ * see, so without the links the fetches only start once the loader runs. No `crossorigin`: a bare
14
+ * `modulepreload` fetches with the same credentials mode as a bare `import()`, and a mismatch
15
+ * would download each module twice.
16
+ */
17
+ export const getV2ModulePreloadHeadContent = (config: InteractConfig): string =>
18
+ getModuleUrls(getPresetTypes(config))
19
+ .map(url => `<link rel="modulepreload" href="${url}">`)
20
+ .join('')
21
+
22
+ export const getV2InteractionsScriptContent = (
23
+ config: InteractConfig,
24
+ configId: string,
25
+ isReducedMotion: boolean
26
+ ): string => {
27
+ const presetTypes = getPresetTypes(config)
28
+ const bindings = ['{ Interact }']
29
+ const imports = getModuleUrls(presetTypes).map(url => `import(\`${url}\`)`)
30
+
31
+ if (presetTypes.length > 0) {
32
+ bindings.push(`{ ${presetTypes.join(', ')} }`)
33
+ }
34
+
35
+ const registerEffects =
36
+ presetTypes.length > 0 ? ` Interact.registerEffects({ ${presetTypes.join(', ')} })` : undefined
37
+
38
+ return [
39
+ `const configElement = document.getElementById(\`${configId}\`)`,
40
+ 'if (configElement) {',
41
+ ' const config = JSON.parse(configElement.textContent)',
42
+ ` const [${bindings.join(', ')}] = await Promise.all([`,
43
+ ...imports.map(importCall => ` ${importCall},`),
44
+ ' ])',
45
+ registerEffects,
46
+ ` Interact.forceReducedMotion = ${isReducedMotion}`,
47
+ ' Interact.setup({',
48
+ ' scrollOptionsGetter: function () {',
49
+ ' return document.getElementById(`site-root`)',
50
+ ' },',
51
+ ' allowA11yTriggers: true,',
52
+ ' viewEnter: {',
53
+ ' useSafeViewEnter: true,',
54
+ ' },',
55
+ ' })',
56
+ ' Interact.create(config)',
57
+ '}',
58
+ ]
59
+ .filter((line): line is string => line !== undefined)
60
+ .join('\n')
61
+ }
@@ -0,0 +1,26 @@
1
+ import * as allPresets from '@wix/wix-motion-presets'
2
+
3
+ type EffectModule = {
4
+ web: unknown
5
+ style?: unknown
6
+ getNames: unknown
7
+ }
8
+
9
+ export const motionPresets: Record<string, EffectModule> = allPresets as unknown as Record<string, EffectModule>
10
+
11
+ const knownPresetTypes = new Set(Object.keys(motionPresets))
12
+
13
+ export const isKnownPresetType = (type: string): boolean => knownPresetTypes.has(type)
14
+
15
+ /**
16
+ * Preset names become bare JavaScript identifiers in the client loader. Filtering against the
17
+ * installed package prevents unknown names from creating invalid source or a failed import.
18
+ */
19
+ export const filterKnownPresetTypes = (types: string[]): string[] => {
20
+ const unknown = types.filter(type => !isKnownPresetType(type))
21
+ if (unknown.length > 0) {
22
+ console.warn(`Interactions: skipping unknown Wix motion preset type(s): ${unknown.join(', ')}`)
23
+ }
24
+
25
+ return types.filter(isKnownPresetType)
26
+ }
@@ -0,0 +1,52 @@
1
+ import type { Effect, EffectRef, InteractConfig } from '@wix/interact'
2
+
3
+ type InteractionEffect = NonNullable<InteractConfig['interactions'][number]['effects']>[number]
4
+ type SequenceEffect = NonNullable<InteractConfig['sequences']>[string]['effects'][number]
5
+ type ConfigEffect = InteractionEffect | SequenceEffect
6
+
7
+ /** Prefer the effects map; fall back to an inline named effect when an effect id misses. */
8
+ const resolveEffect = (config: InteractConfig, effect: ConfigEffect): Effect | EffectRef => {
9
+ if (!effect.effectId) {
10
+ return effect
11
+ }
12
+
13
+ return config.effects?.[effect.effectId] ?? effect
14
+ }
15
+
16
+ const readNamedEffectType = (effect: Effect | EffectRef): string | undefined => {
17
+ if (!('namedEffect' in effect) || !effect.namedEffect) {
18
+ return undefined
19
+ }
20
+
21
+ const { type } = effect.namedEffect
22
+ return typeof type === 'string' ? type : undefined
23
+ }
24
+
25
+ export const collectNamedEffectTypes = (config: InteractConfig): string[] => {
26
+ const types = new Set<string>()
27
+
28
+ const collectFromEffects = (effects: ConfigEffect[]) => {
29
+ for (const effect of effects) {
30
+ const type = readNamedEffectType(resolveEffect(config, effect))
31
+ if (type) {
32
+ types.add(type)
33
+ }
34
+ }
35
+ }
36
+
37
+ for (const interaction of config.interactions) {
38
+ collectFromEffects(interaction.effects ?? [])
39
+
40
+ for (const sequence of interaction.sequences ?? []) {
41
+ if ('effects' in sequence) {
42
+ collectFromEffects(sequence.effects)
43
+ continue
44
+ }
45
+
46
+ const referencedSequence = config.sequences?.[sequence.sequenceId]
47
+ collectFromEffects(referencedSequence?.effects ?? [])
48
+ }
49
+ }
50
+
51
+ return [...types].sort()
52
+ }
@@ -0,0 +1,31 @@
1
+ import { Interact } from '@wix/interact'
2
+ import type { InteractConfig } from '@wix/interact'
3
+ import { collectNamedEffectTypes } from './namedEffectTypes'
4
+ import { filterKnownPresetTypes, motionPresets } from './motionPresets'
5
+
6
+ type PresetRegistry = Parameters<typeof Interact.registerEffects>[0]
7
+ type EffectModule = PresetRegistry[string]
8
+
9
+ // Interact's effect registry is process-global, so mirror it across repeated SSR renders.
10
+ const registeredTypes = new Set<string>()
11
+
12
+ /**
13
+ * A named effect only runs once its preset is registered, so every path that reaches
14
+ * `Interact.create` or `generate` has to register the config's presets first.
15
+ */
16
+ export const registerConfigEffects = (config: InteractConfig) => {
17
+ const presetsToRegister: PresetRegistry = {}
18
+
19
+ for (const type of filterKnownPresetTypes(collectNamedEffectTypes(config))) {
20
+ if (registeredTypes.has(type)) {
21
+ continue
22
+ }
23
+
24
+ presetsToRegister[type] = motionPresets[type] as EffectModule
25
+ }
26
+
27
+ if (Object.keys(presetsToRegister).length > 0) {
28
+ Interact.registerEffects(presetsToRegister)
29
+ Object.keys(presetsToRegister).forEach(type => registeredTypes.add(type))
30
+ }
31
+ }