@wix/origami-transforms 0.1.17 → 0.1.19

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.
@@ -0,0 +1,6 @@
1
+ export namespace pageSlotsPlugin {
2
+ let name: string;
3
+ let order: number;
4
+ function appliesTo(context: any): boolean;
5
+ function transform(program: any): void;
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/origami-transforms",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Babel and PostCSS checks and transforms for Wix origami page files.",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -18,7 +18,7 @@
18
18
  "@babel/parser": "^7.25.0",
19
19
  "@babel/types": "^7.25.2",
20
20
  "@wix/origami-fonts": "1.0.1",
21
- "@wix/origami-system-components": "1.10.0",
21
+ "@wix/origami-system-components": "1.10.2",
22
22
  "postcss": "^8.5.3",
23
23
  "postcss-custom-media": "^12.0.1"
24
24
  },
@@ -64,5 +64,5 @@
64
64
  },
65
65
  "type": "module",
66
66
  "types": "./dist/index.d.ts",
67
- "falconPackageHash": "7fd53a47a2a80ee2e831d1b608e15378825592abfb78d94393377d13"
67
+ "falconPackageHash": "c11a6c324a5b97b42a4b7a2a48d91b173e6a90a02c324a92787797d9"
68
68
  }
@@ -5,6 +5,7 @@
5
5
  import { mediaValidationPlugin } from './mediaValidation/index.js'
6
6
  import { origamiCompatibilityPlugin } from './origamiCompatibility/index.js'
7
7
  import { layoutValidationPlugin } from './validation/index.js'
8
+ import { pageSlotsPlugin } from './pageSlots.js'
8
9
 
9
10
  /** @type {readonly import('../transform/types.js').JsxTransformPlugin[]} */
10
- export const jsxPlugins = Object.freeze([layoutValidationPlugin, mediaValidationPlugin, origamiCompatibilityPlugin])
11
+ export const jsxPlugins = Object.freeze([layoutValidationPlugin, mediaValidationPlugin, origamiCompatibilityPlugin, pageSlotsPlugin])
@@ -0,0 +1,85 @@
1
+ import { basename } from 'node:path'
2
+ import { types as t } from '@babel/core'
3
+ import { findAttribute } from './origamiCompatibility/ast.js'
4
+
5
+ // Resolve imports rather than function names: shared definitions and wrapper names
6
+ // are otherwise opaque to Page at runtime, especially after minification.
7
+ const componentOf = path => {
8
+ const name = path.node.openingElement.name
9
+ if (!t.isJSXIdentifier(name)) return undefined
10
+ const binding = path.scope.getBinding(name.name)?.path
11
+ if (!binding || !binding.parentPath.isImportDeclaration()) return undefined
12
+ const source = binding.parentPath.node.source.value
13
+ const imported = binding.isImportSpecifier()
14
+ ? binding.node.imported.name ?? binding.node.imported.value
15
+ : 'default'
16
+ if (source === 'document' || source === 'document/components' || source === 'wixSystemElements') {
17
+ return imported
18
+ }
19
+ const system = /^@wix\/origami-system-components\/layout\/(Page|Header|Footer)$/u.exec(source)?.[1]
20
+ if (system && (imported === system || imported === 'default')) return system
21
+ const shared = /(?:^|\/)global\/components\/(Header|Footer)_[^/]+(?:\/index\.jsx)?$/u.exec(source)?.[1]
22
+ if (shared && imported === 'default') return shared
23
+ const background = /^@origami-wrappers\/wixSystemElements\/(background|backgroundshapedivider)$/u.exec(source)?.[1]
24
+ if (background && (imported.toLowerCase() === background || imported === 'default')) return 'Background'
25
+ return undefined
26
+ }
27
+
28
+ const slotFor = component => {
29
+ if (component === 'Header' || component?.startsWith('Header_')) return 'header'
30
+ if (component === 'Footer' || component?.startsWith('Footer_')) return 'footer'
31
+ if (component === 'Background' || component === 'BackgroundShapeDivider') return 'backgroundLayer'
32
+ return undefined
33
+ }
34
+
35
+ /** Transitional support for DM's literal Page children alongside authored slot props. */
36
+ export const pageSlotsPlugin = {
37
+ name: 'wix-import-page-slots',
38
+ order: 0,
39
+ appliesTo: context => basename(context.filePath) === 'structure.jsx',
40
+ transform: program => {
41
+ program.traverse({
42
+ JSXElement(path) {
43
+ if (componentOf(path) !== 'Page') return
44
+ const slots = new Map()
45
+ const collect = parent => {
46
+ for (const child of parent.get('children')) {
47
+ if (child.isJSXFragment()) {
48
+ collect(child)
49
+ continue
50
+ }
51
+ if (!child.isJSXElement()) continue
52
+ const slot = slotFor(componentOf(child))
53
+ if (!slot) continue
54
+ if (!slots.has(slot)) slots.set(slot, [])
55
+ slots.get(slot).push(child.node)
56
+ child.remove()
57
+ }
58
+ }
59
+ collect(path)
60
+ const attributes = path.node.openingElement.attributes
61
+ for (const [slot, children] of slots) {
62
+ // Explicit slots (including null) win. Insert defaults before spreads
63
+ // so an authored spread can override them as normal JSX props do.
64
+ if (findAttribute(attributes, slot)) continue
65
+ let value
66
+ if (slot === 'backgroundLayer') {
67
+ // The slot shares InternalContainer's array contract. These
68
+ // literal children need keys now that they form an array.
69
+ children.forEach((child, index) => {
70
+ const props = child.openingElement.attributes
71
+ if (!findAttribute(props, 'key')) {
72
+ props.push(t.jsxAttribute(t.jsxIdentifier('key'), t.stringLiteral(`origami-background-${index}`)))
73
+ }
74
+ })
75
+ value = t.arrayExpression(children)
76
+ } else {
77
+ value = children.length === 1 ? children[0] :
78
+ t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), children)
79
+ }
80
+ attributes.unshift(t.jsxAttribute(t.jsxIdentifier(slot), t.jsxExpressionContainer(value)))
81
+ }
82
+ },
83
+ })
84
+ },
85
+ }