@wix/origami-site-runtime 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.
package/README.md CHANGED
@@ -28,12 +28,12 @@ cannot hide an illegally placed target. Diagnostics retain the original node sou
28
28
  `@origami-target internal-container-content-wrapper` routes to
29
29
  `#id > .id-overflow-wrapper > .id-container`; `internal-container-overflow-wrapper`
30
30
  routes to `#id > .id-overflow-wrapper`. Names come from the pure
31
- `@wix/origami-runtime/layout-contract` entry point. Root sizing, item placement, visibility
31
+ `@wix/origami-system-components/layout-contract` entry point. Root sizing, item placement, visibility
32
32
  and ordinary positioning remain on the ID selector. Background, border and pinned-layer
33
33
  CSS comes from `@wix/origami-system-components/InternalContainer.css`, imported by the maintained
34
- `@wix/origami-runtime/components/InternalContainer` component. The component preserves focus and
34
+ `@wix/origami-system-components/InternalContainer` component. The component preserves focus and
35
35
  wrapper flags. Ref support is deferred
36
- (see the [runtime decision](../origami-runtime/README.md#decision-defer-ref-support-2026-09-24)).
36
+ (see the [system-components decision](../origami-system-components/README.md#decision-defer-ref-support-2026-09-24)).
37
37
 
38
38
  Only explicit targets in site-owned layout.css carriers opt in. Sources of inlined nodes
39
39
  are checked too, including dependency CSS. Targets in style/global-style CSS, mixins,
@@ -62,10 +62,10 @@ half-pixel floor; fixed values retain fractional pixels; zero is zero. See the
62
62
 
63
63
  ## Release and limitations
64
64
 
65
- Generated structures import Page, Section, HeaderSection and FooterSection from
66
- `@wix/origami-system-components` subpaths, InternalContainer from `@wix/origami-runtime`,
65
+ Generated structures import Page, Section, HeaderSection, FooterSection and InternalContainer from
66
+ `@wix/origami-system-components` subpaths,
67
67
  and other editor components from fetched wrappers. The package dependency order is
68
- `@wix/origami-system-components` → `@wix/origami-runtime` → `@wix/origami-site-runtime`;
68
+ `@wix/origami-system-components` → `@wix/origami-site-runtime`;
69
69
  publish the required entry points before generator/CLI releases that consume them. Existing dependency
70
70
  entries, including local/file runtime overrides, are preserved when component dependencies are added.
71
71
  Packed tests verify the compiler and pure layout contract outside the workspace with only
@@ -84,5 +84,5 @@ limitations, not claims of Thunderbolt parity; they need a separate producer/run
84
84
  responsive SPX and grid/flex, nested fractional fixed values, max widths/alignment, overflow,
85
85
  visibility, focus/pointer mechanics, HMR and production build. Install Playwright Chromium or
86
86
  set `CHROME_CHANNEL=chrome` to use installed Chrome.
87
- - Build, lint and test the origami runtime and site generator when changing their contract or
87
+ - Build, lint and test system-components and the site generator when changing their contract or
88
88
  minimum versions. Static producer fixture provenance lives in test/fixtures/css/README.md.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/origami-site-runtime",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Vite development and build helpers for wix-import static sites",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  "@wix/builder-error-pages": "^1.1.6",
21
21
  "@wix/builder-piler-components": "^1.6.7",
22
22
  "@wix/origami-fonts": "1.0.0",
23
- "@wix/origami-runtime": "0.11.0",
23
+ "@wix/origami-system-components": "1.5.0",
24
24
  "postcss": "^8.5.3",
25
25
  "postcss-custom-media": "^12.0.1",
26
26
  "react": "^18.3.1",
@@ -65,5 +65,5 @@
65
65
  "./default-error-404": "./src/default-error-404.jsx"
66
66
  },
67
67
  "type": "module",
68
- "falconPackageHash": "641cce00719388c9e1fbc0fd6cab982b52a23c4daf02f37771b70615"
68
+ "falconPackageHash": "e22a7402b3249122540518d623a21731e722614ef9110bb8cce0eef7"
69
69
  }
@@ -7,13 +7,15 @@
7
7
  // stage guarantees a plugin sees. The order matters once: mixin bodies are copied into their calling rules before
8
8
  // layout routes declarations to wrappers and SPX converts calls using the browser's active settings. stack-children
9
9
  // only checks, and runs between mixins and layout: it needs the mixins' declarations and the stack rules as authored,
10
- // before layout compiles them away. fonts only checks the theme's font tokens, as authored.
10
+ // before layout compiles them away. presets runs after mixins too, so a `--preset` a mixin body carries is moved
11
+ // like an authored one. fonts only checks the theme's font tokens, as authored.
11
12
  //
12
13
  // `@layer` needs no plugin: cascade layers have been in every browser since March 2022.
13
14
 
14
15
  import { customMediaPlugin } from './customMedia.js'
15
16
  import { fontsPlugin } from './fonts.js'
16
17
  import { mixinsPlugin } from './mixins.js'
18
+ import { presetsPlugin } from './presets.js'
17
19
  import { layoutPlugin } from './layout/index.js'
18
20
  import { spxPlugin } from './spx/index.js'
19
21
  import { stackChildrenPlugin } from './stackChildren.js'
@@ -24,6 +26,7 @@ export const cssPlugins = Object.freeze([
24
26
  fontsPlugin,
25
27
  mixinsPlugin,
26
28
  stackChildrenPlugin,
29
+ presetsPlugin,
27
30
  layoutPlugin,
28
31
  spxPlugin,
29
32
  ])
@@ -1,5 +1,5 @@
1
1
  import postcss from 'postcss'
2
- import { buildContainerClasses } from '@wix/origami-runtime/layout-contract'
2
+ import { buildContainerClasses } from '@wix/origami-system-components/layout-contract'
3
3
  import { CONTENT } from './contract.js'
4
4
  import { isLayoutSource, parseTargets } from './parser.js'
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { basename } from 'node:path'
2
- import { isValidContainerId } from '@wix/origami-runtime/layout-contract'
2
+ import { isValidContainerId } from '@wix/origami-system-components/layout-contract'
3
3
  import { relativeToSite } from '../../routing/siteLayout.js'
4
4
  import { CONTENT, OVERFLOW, targets, displays } from './contract.js'
5
5
 
@@ -0,0 +1,67 @@
1
+ // A preset is set on the component's own rule (`#id` or `.id`): `--preset` for the component, `--preset-{key}` for
2
+ // its ref element `key` (as listed in the wrapper's `REF_ELEMENTS`). An element nested deeper is reached the same way,
3
+ // from the rule of the element it sits in: `.id .{parent} { --preset-{key}: … }`. The wrapper reads
4
+ // `--preset` off the presets-wrapper classes it renders (see the origami-component-usage skill), so each declaration
5
+ // moves there, as `--preset` in a rule of its own: `.{id}-presets-wrapper`, or `{selector} .{key}-presets-wrapper` so
6
+ // an inner element's preset reaches that instance only. A rule that does not start at a component is left as authored.
7
+
8
+ import postcss from 'postcss'
9
+
10
+ const PRESET = /^--preset(?:-([\w-]+))?$/
11
+ const COMPONENT = /^[#.]([\w-]+)$/
12
+ const WRAPPER = '-presets-wrapper'
13
+
14
+ /** Where a preset on `selector` goes: undefined when `selector` does not start at a component, null when it can't go. */
15
+ const target = (selector, key) => {
16
+ const [first] = selector.split(/\s+/, 1)
17
+ const id = COMPONENT.exec(first)?.[1]
18
+ if (id === undefined || id.endsWith(WRAPPER)) return undefined
19
+ if (key !== undefined) return `${selector} .${key}${WRAPPER}`
20
+ return selector === first ? `.${id}${WRAPPER}` : null
21
+ }
22
+
23
+ /** @type {import('../transform/types.js').CssTransformPlugin} */
24
+ export const presetsPlugin = {
25
+ name: 'presets',
26
+ order: 13,
27
+ transform(root) {
28
+ /** @type {import('postcss').Declaration[]} */
29
+ const declarations = []
30
+ root.walkDecls(PRESET, declaration => {
31
+ if (declaration.parent?.type === 'rule') declarations.push(declaration)
32
+ })
33
+ // Last first: each moved declaration lands right after its outermost rule, so source order is kept.
34
+ for (const declaration of declarations.reverse()) {
35
+ const rule = /** @type {import('postcss').Rule} */ (declaration.parent)
36
+ // The outermost rule, and the full selectors resolved as CSS Nesting does.
37
+ let outer = rule
38
+ let selectors = rule.selectors
39
+ while (outer.parent?.type === 'rule') {
40
+ outer = /** @type {import('postcss').Rule} */ (outer.parent)
41
+ const inner = selectors
42
+ selectors = outer.selectors.flatMap(parent =>
43
+ inner.map(selector => (selector.includes('&') ? selector.replaceAll('&', parent) : `${parent} ${selector}`))
44
+ )
45
+ }
46
+ const targets = selectors.map(selector => target(selector, PRESET.exec(declaration.prop)?.[1]))
47
+ if (targets.every(selector => selector === undefined)) continue
48
+ if (!targets.every(Boolean)) {
49
+ throw new Error(
50
+ `${declaration.prop} on "${selectors.join(', ')}": set --preset on #id or .id alone, ` +
51
+ `and an inner element's as --preset-{key} on the rule of the element it sits in`
52
+ )
53
+ }
54
+ declaration.prop = '--preset'
55
+ const presetRule = postcss.rule({ selector: targets.join(', ') })
56
+ if (rule.source) presetRule.source = rule.source
57
+ outer.after(presetRule.append(declaration))
58
+ // Drop the rules the move left empty, from the declaration's own up to the outermost.
59
+ for (let node = rule; !node.nodes.length; ) {
60
+ const parent = node.parent
61
+ node.remove()
62
+ if (node === outer) break
63
+ node = /** @type {import('postcss').Rule} */ (parent)
64
+ }
65
+ }
66
+ },
67
+ }