@wix/site-service-interactions 1.0.12 → 1.0.13

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 (76) hide show
  1. package/cjs/build/definition/index.d.ts +19 -3
  2. package/cjs/build/definition/index.js.map +1 -1
  3. package/cjs/build/implementations/InteractionsScriptElement.d.ts +1 -1
  4. package/cjs/build/implementations/configEntries.d.ts +13 -0
  5. package/cjs/build/implementations/configEntries.js +80 -0
  6. package/cjs/build/implementations/configEntries.js.map +1 -0
  7. package/cjs/build/implementations/coreInteractions.d.ts +2 -2
  8. package/cjs/build/implementations/coreInteractions.js +50 -23
  9. package/cjs/build/implementations/coreInteractions.js.map +1 -1
  10. package/cjs/build/implementations/interactionsService.d.ts +5 -4
  11. package/cjs/build/implementations/v2/InteractionsScriptElement.d.ts +2 -2
  12. package/cjs/build/implementations/v2/InteractionsScriptElement.js.map +1 -1
  13. package/cjs/build/implementations/v2/authoredStyles.d.ts +2 -0
  14. package/cjs/build/implementations/v2/authoredStyles.js +95 -0
  15. package/cjs/build/implementations/v2/authoredStyles.js.map +1 -0
  16. package/cjs/build/implementations/v2/cdnUrls.d.ts +2 -1
  17. package/cjs/build/implementations/v2/cdnUrls.js +3 -2
  18. package/cjs/build/implementations/v2/cdnUrls.js.map +1 -1
  19. package/cjs/build/implementations/v2/clickTriggerCss.d.ts +1 -1
  20. package/cjs/build/implementations/v2/configCss.d.ts +1 -1
  21. package/cjs/build/implementations/v2/configCss.js +3 -36
  22. package/cjs/build/implementations/v2/configCss.js.map +1 -1
  23. package/cjs/build/implementations/v2/configStyleHeadContent.js +8 -6
  24. package/cjs/build/implementations/v2/configStyleHeadContent.js.map +1 -1
  25. package/cjs/build/implementations/v2/interactionsScriptContent.js +18 -7
  26. package/cjs/build/implementations/v2/interactionsScriptContent.js.map +1 -1
  27. package/cjs/build/implementations/v2/motionPresets.d.ts +14 -0
  28. package/cjs/build/implementations/v2/motionPresets.js +76 -0
  29. package/cjs/build/implementations/v2/motionPresets.js.map +1 -0
  30. package/cjs/build/service.d.ts +1 -1
  31. package/cjs/build/types/index.d.ts +1 -1
  32. package/dist/definition/index.d.ts +19 -3
  33. package/dist/definition/index.js.map +1 -1
  34. package/dist/implementations/InteractionsScriptElement.d.ts +1 -1
  35. package/dist/implementations/configEntries.d.ts +13 -0
  36. package/dist/implementations/configEntries.js +73 -0
  37. package/dist/implementations/configEntries.js.map +1 -0
  38. package/dist/implementations/coreInteractions.d.ts +2 -2
  39. package/dist/implementations/coreInteractions.js +50 -23
  40. package/dist/implementations/coreInteractions.js.map +1 -1
  41. package/dist/implementations/interactionsService.d.ts +5 -4
  42. package/dist/implementations/v2/InteractionsScriptElement.d.ts +2 -2
  43. package/dist/implementations/v2/InteractionsScriptElement.js.map +1 -1
  44. package/dist/implementations/v2/authoredStyles.d.ts +2 -0
  45. package/dist/implementations/v2/authoredStyles.js +91 -0
  46. package/dist/implementations/v2/authoredStyles.js.map +1 -0
  47. package/dist/implementations/v2/cdnUrls.d.ts +2 -1
  48. package/dist/implementations/v2/cdnUrls.js +2 -1
  49. package/dist/implementations/v2/cdnUrls.js.map +1 -1
  50. package/dist/implementations/v2/clickTriggerCss.d.ts +1 -1
  51. package/dist/implementations/v2/configCss.d.ts +1 -1
  52. package/dist/implementations/v2/configCss.js +2 -2
  53. package/dist/implementations/v2/configCss.js.map +1 -1
  54. package/dist/implementations/v2/configStyleHeadContent.js +8 -6
  55. package/dist/implementations/v2/configStyleHeadContent.js.map +1 -1
  56. package/dist/implementations/v2/interactionsScriptContent.js +19 -8
  57. package/dist/implementations/v2/interactionsScriptContent.js.map +1 -1
  58. package/dist/implementations/v2/motionPresets.d.ts +14 -0
  59. package/dist/implementations/v2/motionPresets.js +39 -0
  60. package/dist/implementations/v2/motionPresets.js.map +1 -0
  61. package/dist/service.d.ts +1 -1
  62. package/dist/types/index.d.ts +1 -1
  63. package/package.json +4 -3
  64. package/src/definition/index.ts +19 -2
  65. package/src/implementations/InteractionsScriptElement.tsx +1 -1
  66. package/src/implementations/configEntries.ts +105 -0
  67. package/src/implementations/coreInteractions.ts +64 -30
  68. package/src/implementations/v2/InteractionsScriptElement.tsx +3 -3
  69. package/src/implementations/v2/authoredStyles.ts +108 -0
  70. package/src/implementations/v2/cdnUrls.ts +4 -1
  71. package/src/implementations/v2/clickTriggerCss.ts +1 -1
  72. package/src/implementations/v2/configCss.ts +4 -5
  73. package/src/implementations/v2/configStyleHeadContent.ts +9 -6
  74. package/src/implementations/v2/interactionsScriptContent.ts +20 -8
  75. package/src/implementations/v2/motionPresets.ts +60 -0
  76. package/src/types/index.ts +1 -1
@@ -1,18 +1,17 @@
1
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'
2
+ import type { InteractConfig } from '@wix/interact-v2'
5
3
  import { getClickTriggerCss } from './clickTriggerCss'
4
+ import { motionPresets } from './motionPresets'
6
5
 
7
6
  type PresetRegistry = Parameters<typeof Interact.registerEffects>[0]
8
7
 
9
8
  // 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.
9
+ // (`process.env.browser` DCE), so both namespaces are registered once per Node process.
11
10
  Interact.registerEffects(motionPresets as unknown as PresetRegistry)
12
11
 
13
12
  /** Emit animation FOUC CSS and click-trigger cursor rules. */
14
13
  export const getV2ConfigCss = (config: InteractConfig): string => {
15
- const animationCss = generate(config as InteractV2Config, true).trim()
14
+ const animationCss = generate(config, true).trim()
16
15
  const clickCss = getClickTriggerCss(config).trim()
17
16
 
18
17
  return [animationCss, clickCss].filter(Boolean).join('\n')
@@ -1,12 +1,15 @@
1
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.
2
+ * Head content is a raw HTML string. CSS values may contain tag-like text, but an actual closing
3
+ * style tag still terminates the raw-text element, and HeadAppender rejects `<script` substrings.
4
+ * Keep other CSS intact: drop content after a closing style tag and break script-like sequences.
6
5
  */
6
+ const STYLE_END_TAG = /<\/style(?=[\t\n\f\r />])/i
7
+ const SCRIPT_LIKE = /<script/gi
8
+
7
9
  const sanitizeCssForStyleElement = (css: string): string => {
8
- const tagIndex = css.search(/<[a-zA-Z/]/)
9
- return tagIndex === -1 ? css : css.slice(0, tagIndex)
10
+ const styleEndTagIndex = css.search(STYLE_END_TAG)
11
+ const withoutStyleBreakout = styleEndTagIndex === -1 ? css : css.slice(0, styleEndTagIndex)
12
+ return withoutStyleBreakout.replace(SCRIPT_LIKE, '\\3c script')
10
13
  }
11
14
 
12
15
  export const getV2ConfigStyleHeadContent = (css: string): string => `<style>${sanitizeCssForStyleElement(css)}</style>`
@@ -1,4 +1,8 @@
1
- import { INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL } from './cdnUrls'
1
+ import { INTERACT_V2_IMPORT_URL, LEGACY_WIX_MOTION_PRESETS_IMPORT_URL, MOTION_PRESETS_IMPORT_URL } from './cdnUrls'
2
+ import { LEGACY_PREFIX } from './motionPresets'
3
+
4
+ /** The loader destructures `Promise.all` in this order. */
5
+ const MODULE_IMPORT_URLS = [INTERACT_V2_IMPORT_URL, LEGACY_WIX_MOTION_PRESETS_IMPORT_URL, MOTION_PRESETS_IMPORT_URL]
2
6
 
3
7
  /**
4
8
  * The loader reaches these modules through dynamic `import()`, which the preload scanner cannot
@@ -7,18 +11,24 @@ import { INTERACT_V2_IMPORT_URL, WIX_MOTION_PRESETS_IMPORT_URL } from './cdnUrls
7
11
  * would download each module twice.
8
12
  */
9
13
  export const getV2ModulePreloadHeadContent = (): string =>
10
- `<link rel="modulepreload" href="${INTERACT_V2_IMPORT_URL}"><link rel="modulepreload" href="${WIX_MOTION_PRESETS_IMPORT_URL}">`
14
+ MODULE_IMPORT_URLS.map(url => `<link rel="modulepreload" href="${url}">`).join('')
11
15
 
12
16
  export const getV2InteractionsScriptContent = (configId: string, isReducedMotion: boolean): string =>
13
17
  [
14
18
  `const configElement = document.getElementById(\`${configId}\`)`,
15
19
  '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
+ ' const parsedConfig = JSON.parse(configElement.textContent)',
21
+ ' const configs = Array.isArray(parsedConfig) ? parsedConfig : [parsedConfig]',
22
+ ' const [{ Interact }, legacyPresets, presets] = await Promise.all([',
23
+ ...MODULE_IMPORT_URLS.map(url => ` import(\`${url}\`),`),
20
24
  ' ])',
21
- ' Interact.registerEffects(presets)',
25
+ // Reactions configs carry the prefix on their named effect types, so the two packages can
26
+ // both export a preset under the same name without one shadowing the other.
27
+ ' const aliasedLegacyPresets = {}',
28
+ ' for (const name of Object.keys(legacyPresets)) {',
29
+ ` aliasedLegacyPresets[\`${LEGACY_PREFIX}\` + name] = legacyPresets[name]`,
30
+ ' }',
31
+ ' Interact.registerEffects({ ...presets, ...aliasedLegacyPresets })',
22
32
  ` Interact.forceReducedMotion = ${isReducedMotion}`,
23
33
  ' Interact.setup({',
24
34
  ' scrollOptionsGetter: function () {',
@@ -29,6 +39,8 @@ export const getV2InteractionsScriptContent = (configId: string, isReducedMotion
29
39
  ' useSafeViewEnter: true,',
30
40
  ' },',
31
41
  ' })',
32
- ' Interact.create(config)',
42
+ ' for (const config of configs) {',
43
+ ' Interact.create(config)',
44
+ ' }',
33
45
  '}',
34
46
  ].join('\n')
@@ -0,0 +1,60 @@
1
+ import * as allLegacyPresets from '@wix/wix-motion-presets'
2
+ import * as allPresets from '@wix/motion-presets'
3
+ import type { Effect, EffectRef, InteractConfig } from '@wix/interact-v2'
4
+
5
+ type EffectModule = {
6
+ web: unknown
7
+ style?: unknown
8
+ getNames: unknown
9
+ }
10
+
11
+ type NamedEffect = { type: string } & Record<string, unknown>
12
+
13
+ export const LEGACY_PREFIX = 'LEGACY_'
14
+
15
+ const isEffectModule = (value: unknown): value is EffectModule =>
16
+ typeof value === 'object' && value !== null && 'web' in value && 'getNames' in value
17
+
18
+ const getPresetModules = (namespace: object, prefix: string = ''): Record<string, EffectModule> =>
19
+ Object.fromEntries(
20
+ Object.entries(namespace)
21
+ .filter(([, value]) => isEffectModule(value))
22
+ .map(([name, value]) => [`${prefix}${name}`, value as EffectModule])
23
+ )
24
+
25
+ /**
26
+ * Both preset packages under one registry, mirroring what the client loader registers. The legacy
27
+ * names carry the prefix so a preset published by both packages doesn't shadow its counterpart.
28
+ */
29
+ export const motionPresets: Record<string, EffectModule> = {
30
+ ...getPresetModules(allPresets),
31
+ ...getPresetModules(allLegacyPresets, LEGACY_PREFIX),
32
+ }
33
+
34
+ const aliasEffect = <T extends object>(effect: T): T => {
35
+ const { namedEffect } = effect as { namedEffect?: NamedEffect }
36
+ if (!namedEffect?.type) {
37
+ return effect
38
+ }
39
+ return { ...effect, namedEffect: { ...namedEffect, type: `${LEGACY_PREFIX}${namedEffect.type}` } }
40
+ }
41
+
42
+ const aliasSequence = <T extends object>(sequence: T): T => {
43
+ const { effects } = sequence as { effects?: (Effect | EffectRef)[] }
44
+ return effects ? { ...sequence, effects: effects.map(aliasEffect) } : sequence
45
+ }
46
+
47
+ const mapRecord = <T>(record: Record<string, T>, map: (value: T) => T): Record<string, T> =>
48
+ Object.fromEntries(Object.entries(record).map(([key, value]) => [key, map(value)]))
49
+
50
+ // TODO(ameerf): make this implementation simpler without so many copies of the config object. The current implementation is a direct translation of the v1 code, which was written to avoid mutating the config object.
51
+ export const aliasLegacyNamedEffects = (interact: InteractConfig): InteractConfig => ({
52
+ ...interact,
53
+ ...(interact.effects && { effects: mapRecord(interact.effects, aliasEffect) }),
54
+ ...(interact.sequences && { sequences: mapRecord(interact.sequences, aliasSequence) }),
55
+ interactions: interact.interactions.map(interaction => ({
56
+ ...interaction,
57
+ ...(interaction.effects && { effects: interaction.effects.map(aliasEffect) }),
58
+ ...(interaction.sequences && { sequences: interaction.sequences.map(aliasSequence) }),
59
+ })),
60
+ })
@@ -1,2 +1,2 @@
1
1
  export type { IInteractionsService, IInteractionsServiceConfig, IInteractionsDefinition } from '../definition'
2
- export type { InteractConfig } from '@wix/interact'
2
+ export type { InteractConfig } from '@wix/interact-v2'