You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// types the `$splitText` field on interactions and effects
984
986
```
985
987
988
+
Prefer the config type exported by the plugin package over re-declaring its shape by hand.
989
+
986
990
### `PluginFields`
987
991
988
992
The `$`-prefixed plugin fields allowed on interactions and effects. Augmented plugins keep their value types (as `$<name>`); any other `$`-prefixed field is still allowed with an `unknown` value.
Copy file name to clipboardExpand all lines: packages/interact/docs/guides/plugins.md
+18-51Lines changed: 18 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
`@wix/interact` can route parts of your config to **plugins** — external code registered at runtime. Interact acts purely as a bridge: it knows a plugin's _name_, and when an interaction or effect carries a field named `$<name>` it hands that field's value to the plugin. Interact never knows what the plugin does.
4
4
5
-
This keeps Interact free of any plugin-specific code, and keeps plugins (like [`@wix/splittext`](https://www.npmjs.com/package/@wix/splittext)) free of any Interact-specific code. Neither package depends on the other — the glue lives in your app.
5
+
This keeps Interact free of any plugin-specific code, and keeps plugins (like [`@wix/splittext`](https://www.npmjs.com/package/@wix/splittext)) free of any dependency on Interact. A plugin package can still ship its own adapter — `@wix/splittext/plugin` does — by typing it _structurally_ against the contract below rather than importing `@wix/interact`. Your app then only supplies the type glue.
6
6
7
7
## How it works
8
8
@@ -35,7 +35,7 @@ This keeps Interact free of any plugin-specific code, and keeps plugins (like [`
35
35
36
36
When the `hero` element connects, Interact sees the `$myPlugin` field, looks up the `myPlugin` plugin, and calls it with `{ any: 'value' }`. Plugins run **before** target resolution, so any DOM a plugin creates is visible to the `selector` / `listContainer` queries that follow.
37
37
38
-
If a `$`-prefixed field names a plugin that was never registered, Interact throws a clear error at connect time.
38
+
If a `$`-prefixed field names a plugin that was never registered, Interact ignores it.
39
39
40
40
> **Why the `$` prefix?** It marks a field as plugin config unambiguously (no clash with real config fields), it's a valid unquoted key in JS/TS and valid JSON, and it lets `@wix/interact-validate` accept plugin fields (via `catchall`) while still flagging genuinely-unknown keys.
`@wix/splittext` splits an element's text into `<span>` wrappers (`.split-c` for chars, `.split-w` for words, `.split-l` for lines, `.split-s` for sentences). Wire it up as a plugin, then target the generated spans with a normal `selector`:
75
+
`@wix/splittext` splits an element's text into `<span>` wrappers (`.split-c` for chars, `.split-w` for words, `.split-l` for lines, `.split-s` for sentences). You don't need to write the adapter — it ships from the `@wix/splittext/plugin` entry point, written against the contract above _structurally_ so `@wix/splittext` keeps no dependency on `@wix/interact`. Register it, then target the generated spans with a normal `selector`:
76
76
77
77
```ts
78
-
// splitTextPlugin.ts — the ONLY module that imports both packages
@@ -171,52 +160,30 @@ type InteractPluginStyleGenerator = (
171
160
172
161
### SplitText example — hide until split
173
162
174
-
Pair a runtime marker with a build-time hide rule so the container is hidden on first paint and revealed once split:
163
+
`@wix/splittext/plugin` ships this pairing ready-made: `splitTextStyle` is the SSR counterpart to `splitTextPlugin`, and the two agree on a `data-splittext-ready` marker. Opt in per-field with `hideUntilReady`:
175
164
176
165
```ts
177
-
// splitTextPlugin.ts (extends the earlier example)
On first paint the container is hidden; once the runtime plugin splits it and sets `data-splittext-ready`, the hide rule stops matching and the (individually-hidden) spans take over their entrance animation — no flash of un-split text.
186
+
On first paint the container is hidden; once the runtime plugin splits it and sets `data-splittext-ready`, the hide rule stops matching and the (individually-hidden) spans take over their entrance animation — no flash of un-split text. Without `hideUntilReady`, `splitTextStyle` emits nothing.
220
187
221
188
> Plugin styles are emitted verbatim and unconditionally. If a rule should be scoped to a media query or condition, have the generator build that itself (it receives the interaction/effect `config`).
Copy file name to clipboardExpand all lines: packages/interact/rules/full-lean.md
+12-24Lines changed: 12 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -708,58 +708,46 @@ The target element is what the effect animates. Resolved in priority order:
708
708
709
709
## Plugins
710
710
711
-
Interact can route config to external plugins registered with `Interact.use(name, plugin)`. Interact is only a bridge — it matches a `$<name>` config field to a registered plugin name and passes the value in; it never inspects plugin behavior. Neither Interact nor the plugin package depend on each other — the adapter lives in your app.
711
+
Interact can route config to external plugins registered with `Interact.use(name, plugin)`. Interact is only a bridge — it matches a `$<name>` config field to a registered plugin name and passes the value in; it never inspects plugin behavior. Neither Interact nor the plugin package depend on each other. A plugin package MAY ship its own adapter typed structurally against the contract (e.g. `@wix/splittext/plugin`) — use it instead of hand-rolling one; your app supplies only the type glue.
712
712
713
713
- Register before `create()`: `Interact.use('splitText', splitTextPlugin)`.
714
714
- Reference with a `$<name>` field on an **interaction** or **effect**: `$splitText: { container: '.title', type: 'chars' }`.
715
715
- Plugins run at connect time, **before** target resolution — so DOM they create (e.g. `.split-c` spans) is visible to `selector` queries that follow.
716
716
- A plugin may return a cleanup function; Interact runs it on disconnect/teardown.
717
-
- A `$<name>` field with no registered plugin throws at connect time.
717
+
- A `$<name>` field with no registered plugin is ignored.
718
718
- Plugin fields MUST be `$`-prefixed — anon-prefixed unknown key on an interaction/effect is rejected by `@wix/interact-validate`.
719
-
- **SSR styling:** for FOUC prevention (e.g. hiding un-splittext before an entrance animation), pass a**separate**per-plugin callback as `generate()`'s third arg: `generate(config, true, { splitText: (value, context) => { declarations, selectorSuffix }[] })`. `generate()` does not inspect the value; the callback returns CSS rule(s) data and scopes them under the base selector (`[data-interact-key="<key>"]`). It is NOT the `use()` callback.
719
+
- **SSR styling:** for FOUC prevention (e.g. hiding un-splittext before an entrance animation), pass a**separate**per-plugin callback as `generate()`'s third arg: `generate(config, true, { myPlugin: (value, context) => { declarations, selectorSuffix }[] })`. `generate()` does not inspect the value; the callback returns CSS rule(s) data and scopes them under the base selector (`[data-interact-key="<key>"]`). It is NOT the `use()` callback. If the plugin package ships a generator (e.g. `splitTextStyle` from `@wix/splittext/plugin`), pass that instead of writing one.
720
720
721
-
**Example — split text, then stagger the generated char spans:**
721
+
**Example — split text, then stagger the generated char spans.**Use the adapter shipped from `@wix/splittext/plugin` (`splitTextPlugin` + its SSR counterpart `splitTextStyle`); do NOT hand-roll it:
722
722
723
723
```js
724
724
import { Interact, generate } from '@wix/interact';
725
-
import { splitText} from '@wix/splittext';
725
+
import { splitTextPlugin, splitTextStyle} from '@wix/splittext/plugin';
// Embed css in HTML — see CSS Generation & FOUC Prevention
750
742
751
-
// The only glue that imports both packages:
752
-
Interact.use('splitText', (value, { root }) => {
753
-
const { container, ...options } = value;
754
-
const el = root.querySelector(container);
755
-
if (!el) return;
756
-
const result = splitText(el, options);
757
-
return () => result.revert();
758
-
});
743
+
Interact.use('splitText', splitTextPlugin);
759
744
760
745
Interact.create(config);
761
746
```
762
747
748
+
- `$splitText` takes `{ container, hideUntilReady?, ...SplitTextOptions }`; `container` is resolved within the element and every match is split.
749
+
- Type the field in your app: `declare module '@wix/interact' { interfaceInteractPluginConfigMap { splitText: SplitTextPluginConfig } }` (type from `@wix/splittext/plugin`).
Copy file name to clipboardExpand all lines: packages/interact/rules/plugins.md
+29-27Lines changed: 29 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,8 +7,9 @@ Rules for extending `@wix/interact` with external plugins via `Interact.use()` a
7
7
Interact is a **generic bridge**. It knows a plugin only by the name it was registered under. When an interaction or effect carries a field named `$<name>`, Interact passes that field's value to the matching plugin and (optionally) stores a cleanup. Interact never inspects what the plugin does.
8
8
9
9
-`@wix/interact` has **no** plugin-specific code and does **not** depend on any plugin package.
10
-
- A plugin package (e.g. `@wix/splittext`) has **no** Interact-specific code and does **not** depend on `@wix/interact`.
11
-
- The adapter that maps an Interact plugin call to the plugin's own API lives in **your app** — the only place that imports both.
10
+
- A plugin package (e.g. `@wix/splittext`) does **not** depend on `@wix/interact`.
11
+
- A plugin package MAY still ship a ready-made adapter (e.g. `@wix/splittext/plugin`), typed _structurally_ against the contract below so it stays assignable to `InteractPlugin` without importing Interact. Prefer the shipped adapter over hand-rolling one.
12
+
- Only the **typing** glue lives in your app — the declaration merge on `InteractPluginConfigMap` (see [Config placement](#config-placement)).
-`Interact.getPlugin(name)` / `Interact.hasPlugins()` inspect the registry.
26
+
-`Interact.getPlugin(name) / Interact.getPluginsNames()` inspect the registry.
26
27
27
28
## Config placement
28
29
@@ -39,7 +40,7 @@ Add a `$<plugin-name>` field on an **interaction** or an **effect**:
39
40
40
41
## Rules
41
42
42
-
-**MUST** register the plugin (`Interact.use`) before `Interact.create()`. A `$<name>` field with no registered plugin throws at connect time.
43
+
-**MUST** register the plugin (`Interact.use`) before `Interact.create()`. A `$<name>` field with no registered plugin is ignored.
43
44
-**MUST** prefix plugin fields with `$` (e.g. `$splitText`). A non-prefixed unknown key on an interaction/effect is rejected by `@wix/interact-validate` (via `catchall` + key check). Only `$`-prefixed fields are treated as opaque, un-inspected plugin config.
44
45
- Use a bare, unquoted `$<name>` key — no quotes needed since `$` is a valid identifier start (e.g. `$splitText:`, not `'plugin:splitText':`).
45
46
- Plugins run at **connect time, before target resolution** — DOM a plugin creates is visible to the `selector` / `listContainer` queries that follow.
@@ -53,20 +54,21 @@ Runtime plugins mutate the DOM only after JS loads. To style the element _before
- If the plugin package ships its own generator, pass that instead of writing one — e.g. `splitTextStyle` from `@wix/splittext/plugin` (see the example below).
70
72
- This is **NOT** the callback registered via `Interact.use()` — it's a build-time styling generator.
71
73
- `generate()` does **not** inspect the `$<name>` value (same as `create()`); it just routes it to the generator, which returns partial CSS rule(s) data.
72
74
- `declarations` is an array of names and values of CSS properties to set; `selectorSuffix` is used to refine the target of the CSS rule - the resulting selector for the rule is `[data-interact-key=${key}]${selectorSuffix}`
Split text into `<span>`s, then target the generated spans with a normal `selector`. Default classes: `.split-c` (chars), `.split-w` (words), `.split-l` (lines), `.split-s` (sentences).
79
81
82
+
**Do NOT hand-roll this adapter.** `@wix/splittext/plugin` ships both callbacks — `splitTextPlugin` (runtime) and `splitTextStyle` (SSR) — already paired on the `data-splittext-ready` marker:
83
+
80
84
```js
81
-
import { Interact } from '@wix/interact';
82
-
import { splitText } from '@wix/splittext';
85
+
import { Interact, generate } from '@wix/interact';
86
+
import { splitTextPlugin, splitTextStyle } from '@wix/splittext/plugin';
0 commit comments