@motion.page/sdk 1.1.4 → 1.2.1
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 +49 -0
- package/dist/core/Motion.d.ts +2 -0
- package/dist/index.cjs +12 -12
- package/dist/index.d.ts +1 -0
- package/dist/index.js +12 -12
- package/dist/registries/SDKRegistry.d.ts +10 -0
- package/dist/responsive/ResponsiveManager.d.ts +86 -0
- package/dist/utils/PropertyParser/constants.d.ts +15 -0
- package/dist/utils/PropertyParser/index.d.ts +23 -0
- package/dist/utils/PropertyParser/parsers.d.ts +13 -0
- package/dist/utils/PropertyParser/predicates.d.ts +37 -0
- package/dist/utils/PropertyParser/relative.d.ts +17 -0
- package/dist/utils/PropertyParser/types.d.ts +83 -0
- package/dist/utils/PropertyParser/units.d.ts +53 -0
- package/dist/utils/{TextFlapper.d.ts → TextFlapper/TextFlapper.d.ts} +2 -37
- package/dist/utils/TextFlapper/charRender.d.ts +21 -0
- package/dist/utils/TextFlapper/constants.d.ts +20 -0
- package/dist/utils/TextFlapper/helpers.d.ts +50 -0
- package/dist/utils/TextFlapper/index.d.ts +16 -0
- package/dist/utils/TextFlapper/types.d.ts +89 -0
- package/dist/utils/TextSplitter/TextSplitter.d.ts +55 -0
- package/dist/utils/TextSplitter/helpers.d.ts +56 -0
- package/dist/utils/TextSplitter/index.d.ts +17 -0
- package/dist/utils/TextSplitter/splitDom.d.ts +51 -0
- package/dist/utils/TextSplitter/state.d.ts +8 -0
- package/dist/utils/TextSplitter/types.d.ts +39 -0
- package/package.json +1 -1
- package/dist/utils/PropertyParser.d.ts +0 -191
- package/dist/utils/TextSplitter.d.ts +0 -164
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextSplitter helpers — non-destructive split upgrades plus the mask-wrapper
|
|
3
|
+
* and gradient-text post-processing passes.
|
|
4
|
+
*
|
|
5
|
+
* These operate on an existing SplitResult / ElementSplitState and never touch
|
|
6
|
+
* the module-level splitStateMap directly (state is passed in by the class).
|
|
7
|
+
*/
|
|
8
|
+
import type { SplitType, SplitOptions, SplitResult, ElementSplitState } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Attempt to upgrade an existing split to satisfy a new type request without
|
|
11
|
+
* destroying existing DOM references.
|
|
12
|
+
*
|
|
13
|
+
* Returns the appropriate span array on success, or null if the upgrade is
|
|
14
|
+
* not possible (caller must fall back to a full revert + re-split).
|
|
15
|
+
*/
|
|
16
|
+
export declare function tryUpgrade(element: HTMLElement, state: ElementSplitState, type: SplitType, options?: SplitOptions): HTMLElement[] | null;
|
|
17
|
+
/**
|
|
18
|
+
* Return the appropriate span array from a SplitResult for the requested type.
|
|
19
|
+
* Chars have highest priority, then words, then lines.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getSpansForType(result: SplitResult, type: string): HTMLElement[];
|
|
22
|
+
/**
|
|
23
|
+
* Build a combined data-split attribute value from existing and requested types,
|
|
24
|
+
* ordered as: lines, words, chars (broadest → most granular).
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildTypeString(existingTypes: string[], requestedTypes: string[]): string;
|
|
27
|
+
/**
|
|
28
|
+
* Walk a word span's text nodes and replace them with individual char spans,
|
|
29
|
+
* appending each new span to the provided `chars` array.
|
|
30
|
+
*
|
|
31
|
+
* Used when upgrading an existing 'words' split to include 'chars'.
|
|
32
|
+
* The word span itself is NOT moved or recreated — only its text node
|
|
33
|
+
* children are swapped out, so existing references to the word span remain valid.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nestCharsInElement(parent: HTMLElement, chars: HTMLElement[]): void;
|
|
36
|
+
/**
|
|
37
|
+
* Wrap each split element in a parent with overflow:hidden for clip-reveal.
|
|
38
|
+
* The wrapper clips content so animating y:'100%' creates a reveal effect.
|
|
39
|
+
*/
|
|
40
|
+
export declare function applyMaskWrappers(result: SplitResult): void;
|
|
41
|
+
/**
|
|
42
|
+
* Detect if the split element uses `background-clip: text` (gradient text)
|
|
43
|
+
* and propagate the gradient through all generated spans so text stays visible.
|
|
44
|
+
*
|
|
45
|
+
* Without this, inline-block split spans inherit `-webkit-text-fill-color: transparent`
|
|
46
|
+
* but NOT the parent's gradient background, making the text invisible.
|
|
47
|
+
*
|
|
48
|
+
* IMPORTANT: We copy the computed background-image directly instead of using
|
|
49
|
+
* `background: inherit` because `background` is NOT an inherited CSS property.
|
|
50
|
+
* When the split element contains intermediate wrapper elements (e.g.
|
|
51
|
+
* `<h1><span class="line"><span class="accent">word</span></span></h1>`),
|
|
52
|
+
* `inherit` resolves to `none` at each intermediate element, breaking the chain.
|
|
53
|
+
* Copying the resolved value ensures the gradient reaches every split span
|
|
54
|
+
* regardless of DOM depth.
|
|
55
|
+
*/
|
|
56
|
+
export declare function propagateGradientText(element: HTMLElement, result: SplitResult): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextSplitter barrel — preserves the public import path `../utils/TextSplitter`.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the exact public surface the original single-file module had:
|
|
5
|
+
* - class `TextSplitter`
|
|
6
|
+
* - type `SplitType` (re-exported from the shared SDK types)
|
|
7
|
+
* - interface `SplitOptions`
|
|
8
|
+
*
|
|
9
|
+
* The SDKRegistry self-registration side effect lives in `./TextSplitter`
|
|
10
|
+
* (co-located with the class), so importing this barrel still registers the
|
|
11
|
+
* implementation on SDKRegistry at module load — the behaviour the SDK entry
|
|
12
|
+
* relies on. It is intentionally NOT a separate bare `import './register'`:
|
|
13
|
+
* the chunked SDK bundler does not inline bare side-effect imports and would
|
|
14
|
+
* leak a raw `import` statement into the standalone bundle.
|
|
15
|
+
*/
|
|
16
|
+
export { TextSplitter } from './TextSplitter';
|
|
17
|
+
export type { SplitType, SplitOptions } from './types';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextSplitter DOM-walking split functions.
|
|
3
|
+
*
|
|
4
|
+
* The actual text-node → span splitting passes (words, chars, words+chars, and
|
|
5
|
+
* the layout-measuring lines pass) plus the small HTML-serialization helpers the
|
|
6
|
+
* lines pass relies on. Each function preserves existing element wrappers like
|
|
7
|
+
* `<span class="accent">word</span>` and recurses into child elements.
|
|
8
|
+
*/
|
|
9
|
+
import type { SplitResult } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Split text nodes into word spans, preserving existing element wrappers.
|
|
12
|
+
* Recurses into child elements so `<span class="accent">word</span>` keeps
|
|
13
|
+
* its wrapper and the text inside is split within it.
|
|
14
|
+
*/
|
|
15
|
+
export declare function splitWordsDom(parent: HTMLElement, result: SplitResult): void;
|
|
16
|
+
/**
|
|
17
|
+
* Split text nodes into character spans, preserving existing element wrappers.
|
|
18
|
+
*
|
|
19
|
+
* Characters are grouped by word inside implicit wrapper spans with
|
|
20
|
+
* `white-space: nowrap` so the browser never breaks a word across lines
|
|
21
|
+
* (matching GSAP SplitText behaviour). Only the char spans are exposed
|
|
22
|
+
* as animatable elements — the word wrappers are transparent to consumers.
|
|
23
|
+
*/
|
|
24
|
+
export declare function splitCharsDom(parent: HTMLElement, result: SplitResult): void;
|
|
25
|
+
/**
|
|
26
|
+
* Split text nodes into word spans containing character spans.
|
|
27
|
+
* Preserves existing element wrappers.
|
|
28
|
+
*/
|
|
29
|
+
export declare function splitWordsWithCharsDom(parent: HTMLElement, result: SplitResult): void;
|
|
30
|
+
/**
|
|
31
|
+
* Split with line detection (requires layout measurement).
|
|
32
|
+
*
|
|
33
|
+
* Strategy:
|
|
34
|
+
* 1. DOM-walk to split into word spans (preserving element wrappers)
|
|
35
|
+
* 2. Measure each word span's vertical position to group into lines
|
|
36
|
+
* 3. Wrap each line group in a line span
|
|
37
|
+
*/
|
|
38
|
+
export declare function splitWithLinesDom(element: HTMLElement, needsWords: boolean, needsChars: boolean, result: SplitResult): void;
|
|
39
|
+
/**
|
|
40
|
+
* Get the chain of wrapper elements between a word span and the root element.
|
|
41
|
+
* Returns outermost-first order (root's direct child → … → word's parent).
|
|
42
|
+
*/
|
|
43
|
+
export declare function getWrapperChain(word: HTMLElement, root: HTMLElement): HTMLElement[];
|
|
44
|
+
/**
|
|
45
|
+
* Serialize an element's opening tag, preserving all attributes (class, style, data-*, etc).
|
|
46
|
+
*/
|
|
47
|
+
export declare function openTag(el: HTMLElement): string;
|
|
48
|
+
/**
|
|
49
|
+
* Escape HTML special characters
|
|
50
|
+
*/
|
|
51
|
+
export declare function escapeHtml(str: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextSplitter module state.
|
|
3
|
+
*
|
|
4
|
+
* A single WeakMap holds per-element split state, keyed by the split element.
|
|
5
|
+
* It replaces the old originalContentMap + splitResultMap pair.
|
|
6
|
+
*/
|
|
7
|
+
import type { ElementSplitState } from './types';
|
|
8
|
+
export declare const splitStateMap: WeakMap<Element, ElementSplitState>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextSplitter types — public options plus internal structural types shared
|
|
3
|
+
* across the TextSplitter parts.
|
|
4
|
+
*/
|
|
5
|
+
import type { SplitType } from '../../types';
|
|
6
|
+
export type { SplitType };
|
|
7
|
+
export interface SplitOptions {
|
|
8
|
+
/** Wrap each split element in a parent with overflow:hidden for clip-reveal effects */
|
|
9
|
+
mask?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Opaque token identifying the caller (e.g. an AnimationBuilder instance).
|
|
12
|
+
* When provided, splits are reference-counted: the DOM is only reverted once
|
|
13
|
+
* all registered consumers release their claim via revert(element, consumer).
|
|
14
|
+
* A second consumer on the same element triggers a smart DOM upgrade (nesting)
|
|
15
|
+
* rather than destroying the first consumer's spans.
|
|
16
|
+
*/
|
|
17
|
+
consumer?: object;
|
|
18
|
+
}
|
|
19
|
+
export interface SplitResult {
|
|
20
|
+
chars: HTMLElement[];
|
|
21
|
+
words: HTMLElement[];
|
|
22
|
+
lines: HTMLElement[];
|
|
23
|
+
elements: HTMLElement[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Per-element split state, held in a module-level WeakMap.
|
|
27
|
+
* Replaces the old originalContentMap + splitResultMap pair.
|
|
28
|
+
*/
|
|
29
|
+
export interface ElementSplitState {
|
|
30
|
+
/** The element's innerHTML captured before any split — always the true original. */
|
|
31
|
+
originalHTML: string;
|
|
32
|
+
/** The live split result arrays (mutated in-place on upgrades). */
|
|
33
|
+
result: SplitResult;
|
|
34
|
+
/**
|
|
35
|
+
* Set of consumer tokens currently holding a reference to this split.
|
|
36
|
+
* Empty set means no consumer tracking (single-timeline / legacy callers).
|
|
37
|
+
*/
|
|
38
|
+
consumers: Set<object>;
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PropertyParser - Parse and normalize animation properties
|
|
3
|
-
*
|
|
4
|
-
* Handles:
|
|
5
|
-
* - Transform shortcuts (x, y, rotate, scale, etc.)
|
|
6
|
-
* - Relative values (+=, -=, *=, /=)
|
|
7
|
-
* - Unit parsing and defaulting
|
|
8
|
-
* - Color parsing (hex, rgb, hsl, named, CSS variables) - OPTIONAL
|
|
9
|
-
* - Filter parsing (blur, brightness, contrast, etc.) - OPTIONAL
|
|
10
|
-
* - DrawSVG parsing (SVG stroke animations) - OPTIONAL
|
|
11
|
-
*
|
|
12
|
-
* Optional parsers are loaded conditionally via SDKRegistry.
|
|
13
|
-
* If a parser is not loaded, those property types will be skipped.
|
|
14
|
-
*/
|
|
15
|
-
import type { AnimationTarget } from '../types';
|
|
16
|
-
import type { ParsedFilterFunction } from './FilterParser';
|
|
17
|
-
import type { ParsedDrawSVG } from './DrawSVGParser';
|
|
18
|
-
import type { ParsedClipPath } from './ClipPathParser';
|
|
19
|
-
/**
|
|
20
|
-
* Valid property value types for animation
|
|
21
|
-
*/
|
|
22
|
-
export type PropertyValue = number | string;
|
|
23
|
-
/**
|
|
24
|
-
* Base fields shared by all parsed property types
|
|
25
|
-
*/
|
|
26
|
-
interface ParsedPropertyBase {
|
|
27
|
-
property: string;
|
|
28
|
-
isTransform: boolean;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Scalar property (numbers with units)
|
|
32
|
-
*/
|
|
33
|
-
interface ParsedScalarProperty extends ParsedPropertyBase {
|
|
34
|
-
type: 'scalar';
|
|
35
|
-
startValue: number;
|
|
36
|
-
endValue: number;
|
|
37
|
-
unit: string;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Color property (RGBA values)
|
|
41
|
-
*/
|
|
42
|
-
interface ParsedColorProperty extends ParsedPropertyBase {
|
|
43
|
-
type: 'color';
|
|
44
|
-
startColor: Float32Array;
|
|
45
|
-
endColor: Float32Array;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Filter property (CSS filters)
|
|
49
|
-
*/
|
|
50
|
-
interface ParsedFilterProperty extends ParsedPropertyBase {
|
|
51
|
-
type: 'filter';
|
|
52
|
-
startFilters: ParsedFilterFunction[];
|
|
53
|
-
endFilters: ParsedFilterFunction[];
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* DrawSVG property (SVG stroke animation)
|
|
57
|
-
*/
|
|
58
|
-
interface ParsedDrawSVGProperty extends ParsedPropertyBase {
|
|
59
|
-
type: 'drawSVG';
|
|
60
|
-
startDraw: ParsedDrawSVG;
|
|
61
|
-
endDraw: ParsedDrawSVG;
|
|
62
|
-
length: number;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Clip-path property (CSS clip-path shape function interpolation)
|
|
66
|
-
*/
|
|
67
|
-
interface ParsedClipPathProperty extends ParsedPropertyBase {
|
|
68
|
-
type: 'clipPath';
|
|
69
|
-
startClipPath: ParsedClipPath;
|
|
70
|
-
endClipPath: ParsedClipPath;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Path property (motion along SVG path)
|
|
74
|
-
*/
|
|
75
|
-
interface ParsedPathProperty extends ParsedPropertyBase {
|
|
76
|
-
type: 'path';
|
|
77
|
-
pathData: string;
|
|
78
|
-
pathLength: number;
|
|
79
|
-
startProgress: number;
|
|
80
|
-
endProgress: number;
|
|
81
|
-
rotate: boolean;
|
|
82
|
-
alignOffset: {
|
|
83
|
-
x: number;
|
|
84
|
-
y: number;
|
|
85
|
-
};
|
|
86
|
-
pathOffset: {
|
|
87
|
-
x: number;
|
|
88
|
-
y: number;
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Discriminated union of all parsed property types
|
|
93
|
-
*/
|
|
94
|
-
export type ParsedProperty = ParsedScalarProperty | ParsedColorProperty | ParsedFilterProperty | ParsedDrawSVGProperty | ParsedPathProperty | ParsedClipPathProperty;
|
|
95
|
-
/**
|
|
96
|
-
* Check if a property is a transform property
|
|
97
|
-
*/
|
|
98
|
-
export declare function isTransformProp(prop: string): boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Check if a property is a color property
|
|
101
|
-
*/
|
|
102
|
-
export declare function isColorProp(prop: string): boolean;
|
|
103
|
-
/**
|
|
104
|
-
* Check if a property is the filter property
|
|
105
|
-
*/
|
|
106
|
-
export declare function isFilterProp(prop: string): boolean;
|
|
107
|
-
/**
|
|
108
|
-
* Check if a property is the drawSVG property
|
|
109
|
-
*/
|
|
110
|
-
export declare function isDrawSVGProp(prop: string): boolean;
|
|
111
|
-
/**
|
|
112
|
-
* Check if a property is the path property (motion path)
|
|
113
|
-
*/
|
|
114
|
-
export declare function isPathProp(prop: string): boolean;
|
|
115
|
-
/**
|
|
116
|
-
* Check if a property is the clip-path property (accepts both kebab and camel case)
|
|
117
|
-
*/
|
|
118
|
-
export declare function isClipPathProp(prop: string): boolean;
|
|
119
|
-
/**
|
|
120
|
-
* Check if a property is a CSS variable (custom property)
|
|
121
|
-
*/
|
|
122
|
-
export declare function isCSSVariable(prop: string): boolean;
|
|
123
|
-
/**
|
|
124
|
-
* Check if a value looks like a color (for CSS variable type detection)
|
|
125
|
-
*/
|
|
126
|
-
export declare function looksLikeColor(value: PropertyValue): boolean;
|
|
127
|
-
/**
|
|
128
|
-
* Parse a property value and extract numeric value and unit
|
|
129
|
-
*/
|
|
130
|
-
export declare function parseValue(value: PropertyValue): {
|
|
131
|
-
value: number;
|
|
132
|
-
unit: string;
|
|
133
|
-
};
|
|
134
|
-
/**
|
|
135
|
-
* Get the default unit for a property
|
|
136
|
-
*/
|
|
137
|
-
export declare function getDefaultUnit(prop: string): string;
|
|
138
|
-
/**
|
|
139
|
-
* Get the current computed value of a property from a target
|
|
140
|
-
* Handles both DOM Elements and plain objects
|
|
141
|
-
*/
|
|
142
|
-
export declare function getCurrentValue(target: AnimationTarget, prop: string): number;
|
|
143
|
-
/**
|
|
144
|
-
* Convert a pixel value to a target CSS unit by measuring the element in the DOM.
|
|
145
|
-
*
|
|
146
|
-
* Uses the browser's layout engine: temporarily sets `100{targetUnit}` on the
|
|
147
|
-
* element, reads the computed pixel equivalent, then derives the conversion ratio.
|
|
148
|
-
* This handles %, em, rem, vw, vh, vmin, vmax, ch, ex — any unit the browser supports.
|
|
149
|
-
*
|
|
150
|
-
* When the target unit is 'px' or empty, returns the value unchanged (no conversion).
|
|
151
|
-
* Falls back to the raw pixel value if measurement fails (e.g. detached element).
|
|
152
|
-
*/
|
|
153
|
-
export declare function convertPxToUnit(element: Element, prop: string, pxValue: number, targetUnit: string): number;
|
|
154
|
-
/**
|
|
155
|
-
* Get the current computed value of a property, converted to the specified unit.
|
|
156
|
-
*
|
|
157
|
-
* Combines getCurrentValue (which always returns px for layout properties)
|
|
158
|
-
* with convertPxToUnit to return the value in the desired CSS unit.
|
|
159
|
-
* Only performs conversion for DOM Element targets with non-px units.
|
|
160
|
-
*/
|
|
161
|
-
export declare function getCurrentValueInUnit(target: AnimationTarget, prop: string, targetUnit: string): number;
|
|
162
|
-
/**
|
|
163
|
-
* Get the original CSS value AND unit of a property (excluding inline styles)
|
|
164
|
-
* Returns both value and unit to preserve the original CSS unit (%, rem, em, vh, etc.)
|
|
165
|
-
*/
|
|
166
|
-
export declare function getOriginalCSSValueWithUnit(target: Element, prop: string): {
|
|
167
|
-
value: number;
|
|
168
|
-
unit: string;
|
|
169
|
-
};
|
|
170
|
-
/**
|
|
171
|
-
* Convert camelCase to kebab-case
|
|
172
|
-
*/
|
|
173
|
-
export declare function camelToKebab(str: string): string;
|
|
174
|
-
/**
|
|
175
|
-
* Check if a value is relative (+=, -=, *=, /=)
|
|
176
|
-
*/
|
|
177
|
-
export declare function isRelativeValue(value: PropertyValue): boolean;
|
|
178
|
-
/**
|
|
179
|
-
* Get relative operator from value string
|
|
180
|
-
*/
|
|
181
|
-
export declare function getRelativeOperator(value: string): '+=' | '-=' | '*=' | '/=' | null;
|
|
182
|
-
/**
|
|
183
|
-
* Calculate relative end value
|
|
184
|
-
*/
|
|
185
|
-
export declare function calculateRelativeValue(startValue: number, relativeValue: number, operator: '+=' | '-=' | '*=' | '/='): number;
|
|
186
|
-
/**
|
|
187
|
-
* Parse a property for animation
|
|
188
|
-
* Handles both DOM Elements and plain objects
|
|
189
|
-
*/
|
|
190
|
-
export declare function parseProperty(target: AnimationTarget, prop: string, targetValue: PropertyValue, fromValue?: PropertyValue): ParsedProperty;
|
|
191
|
-
export {};
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TextSplitter - Split text into animatable elements
|
|
3
|
-
*
|
|
4
|
-
* Splits text content into chars, words, or lines wrapped in spans.
|
|
5
|
-
* Supports nested splitting (e.g., 'chars,words' = words containing char spans).
|
|
6
|
-
*
|
|
7
|
-
* Preserves existing element structure — inline elements like
|
|
8
|
-
* `<span class="accent">word</span>` keep their wrapper and styling.
|
|
9
|
-
* Only text nodes are replaced with split spans.
|
|
10
|
-
*
|
|
11
|
-
* Usage:
|
|
12
|
-
* const elements = TextSplitter.split(element, 'chars');
|
|
13
|
-
* const elements = TextSplitter.split(element, 'words');
|
|
14
|
-
* const elements = TextSplitter.split(element, 'chars,words');
|
|
15
|
-
*
|
|
16
|
-
* Revert:
|
|
17
|
-
* TextSplitter.revert(element);
|
|
18
|
-
* TextSplitter.revert(element, consumer); // reference-counted
|
|
19
|
-
*/
|
|
20
|
-
import type { SplitType } from '../types';
|
|
21
|
-
export type { SplitType };
|
|
22
|
-
export interface SplitOptions {
|
|
23
|
-
/** Wrap each split element in a parent with overflow:hidden for clip-reveal effects */
|
|
24
|
-
mask?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Opaque token identifying the caller (e.g. an AnimationBuilder instance).
|
|
27
|
-
* When provided, splits are reference-counted: the DOM is only reverted once
|
|
28
|
-
* all registered consumers release their claim via revert(element, consumer).
|
|
29
|
-
* A second consumer on the same element triggers a smart DOM upgrade (nesting)
|
|
30
|
-
* rather than destroying the first consumer's spans.
|
|
31
|
-
*/
|
|
32
|
-
consumer?: object;
|
|
33
|
-
}
|
|
34
|
-
interface SplitResult {
|
|
35
|
-
chars: HTMLElement[];
|
|
36
|
-
words: HTMLElement[];
|
|
37
|
-
lines: HTMLElement[];
|
|
38
|
-
elements: HTMLElement[];
|
|
39
|
-
}
|
|
40
|
-
export declare class TextSplitter {
|
|
41
|
-
/**
|
|
42
|
-
* Split text content into animatable elements.
|
|
43
|
-
*
|
|
44
|
-
* When `options.consumer` is provided the split is reference-counted.
|
|
45
|
-
* A second consumer on the same element will have the DOM upgraded
|
|
46
|
-
* (chars nested inside existing word spans, or word-wraps promoted to
|
|
47
|
-
* word spans) rather than reverted and rebuilt, so the first consumer's
|
|
48
|
-
* DOM references remain valid.
|
|
49
|
-
*
|
|
50
|
-
* Without a consumer token the function behaves exactly like before:
|
|
51
|
-
* any existing split is reverted and a fresh split is performed.
|
|
52
|
-
*/
|
|
53
|
-
static split(element: Element, type: SplitType, options?: SplitOptions): HTMLElement[];
|
|
54
|
-
/**
|
|
55
|
-
* Attempt to upgrade an existing split to satisfy a new type request without
|
|
56
|
-
* destroying existing DOM references.
|
|
57
|
-
*
|
|
58
|
-
* Returns the appropriate span array on success, or null if the upgrade is
|
|
59
|
-
* not possible (caller must fall back to a full revert + re-split).
|
|
60
|
-
*/
|
|
61
|
-
private static _tryUpgrade;
|
|
62
|
-
/**
|
|
63
|
-
* Return the appropriate span array from a SplitResult for the requested type.
|
|
64
|
-
* Chars have highest priority, then words, then lines.
|
|
65
|
-
*/
|
|
66
|
-
private static _getSpansForType;
|
|
67
|
-
/**
|
|
68
|
-
* Build a combined data-split attribute value from existing and requested types,
|
|
69
|
-
* ordered as: lines, words, chars (broadest → most granular).
|
|
70
|
-
*/
|
|
71
|
-
private static _buildTypeString;
|
|
72
|
-
/**
|
|
73
|
-
* Walk a word span's text nodes and replace them with individual char spans,
|
|
74
|
-
* appending each new span to the provided `chars` array.
|
|
75
|
-
*
|
|
76
|
-
* Used when upgrading an existing 'words' split to include 'chars'.
|
|
77
|
-
* The word span itself is NOT moved or recreated — only its text node
|
|
78
|
-
* children are swapped out, so existing references to the word span remain valid.
|
|
79
|
-
*/
|
|
80
|
-
private static _nestCharsInElement;
|
|
81
|
-
/**
|
|
82
|
-
* Split text nodes into word spans, preserving existing element wrappers.
|
|
83
|
-
* Recurses into child elements so `<span class="accent">word</span>` keeps
|
|
84
|
-
* its wrapper and the text inside is split within it.
|
|
85
|
-
*/
|
|
86
|
-
private static _splitWordsDom;
|
|
87
|
-
/**
|
|
88
|
-
* Split text nodes into character spans, preserving existing element wrappers.
|
|
89
|
-
*
|
|
90
|
-
* Characters are grouped by word inside implicit wrapper spans with
|
|
91
|
-
* `white-space: nowrap` so the browser never breaks a word across lines
|
|
92
|
-
* (matching GSAP SplitText behaviour). Only the char spans are exposed
|
|
93
|
-
* as animatable elements — the word wrappers are transparent to consumers.
|
|
94
|
-
*/
|
|
95
|
-
private static _splitCharsDom;
|
|
96
|
-
/**
|
|
97
|
-
* Split text nodes into word spans containing character spans.
|
|
98
|
-
* Preserves existing element wrappers.
|
|
99
|
-
*/
|
|
100
|
-
private static _splitWordsWithCharsDom;
|
|
101
|
-
/**
|
|
102
|
-
* Split with line detection (requires layout measurement).
|
|
103
|
-
*
|
|
104
|
-
* Strategy:
|
|
105
|
-
* 1. DOM-walk to split into word spans (preserving element wrappers)
|
|
106
|
-
* 2. Measure each word span's vertical position to group into lines
|
|
107
|
-
* 3. Wrap each line group in a line span
|
|
108
|
-
*/
|
|
109
|
-
private static _splitWithLinesDom;
|
|
110
|
-
/**
|
|
111
|
-
* Wrap each split element in a parent with overflow:hidden for clip-reveal.
|
|
112
|
-
* The wrapper clips content so animating y:'100%' creates a reveal effect.
|
|
113
|
-
*/
|
|
114
|
-
private static _applyMaskWrappers;
|
|
115
|
-
/**
|
|
116
|
-
* Detect if the split element uses `background-clip: text` (gradient text)
|
|
117
|
-
* and propagate the gradient through all generated spans so text stays visible.
|
|
118
|
-
*
|
|
119
|
-
* Without this, inline-block split spans inherit `-webkit-text-fill-color: transparent`
|
|
120
|
-
* but NOT the parent's gradient background, making the text invisible.
|
|
121
|
-
*
|
|
122
|
-
* IMPORTANT: We copy the computed background-image directly instead of using
|
|
123
|
-
* `background: inherit` because `background` is NOT an inherited CSS property.
|
|
124
|
-
* When the split element contains intermediate wrapper elements (e.g.
|
|
125
|
-
* `<h1><span class="line"><span class="accent">word</span></span></h1>`),
|
|
126
|
-
* `inherit` resolves to `none` at each intermediate element, breaking the chain.
|
|
127
|
-
* Copying the resolved value ensures the gradient reaches every split span
|
|
128
|
-
* regardless of DOM depth.
|
|
129
|
-
*/
|
|
130
|
-
private static _propagateGradientText;
|
|
131
|
-
/**
|
|
132
|
-
* Revert element to original content.
|
|
133
|
-
*
|
|
134
|
-
* When `consumer` is provided the revert is reference-counted: the DOM is
|
|
135
|
-
* only restored once all registered consumers have released via this method.
|
|
136
|
-
* If the consumer is the last one (or no consumer tracking is active), the
|
|
137
|
-
* element's innerHTML is restored to the pre-split original immediately.
|
|
138
|
-
*
|
|
139
|
-
* Without `consumer` (legacy / forced revert), the DOM is restored regardless
|
|
140
|
-
* of how many consumers are still registered. All consumer refs are cleared.
|
|
141
|
-
*/
|
|
142
|
-
static revert(element: Element, consumer?: object): boolean;
|
|
143
|
-
/**
|
|
144
|
-
* Check if element has been split
|
|
145
|
-
*/
|
|
146
|
-
static isSplit(element: Element): boolean;
|
|
147
|
-
/**
|
|
148
|
-
* Get split result for an element
|
|
149
|
-
*/
|
|
150
|
-
static getResult(element: Element): SplitResult | undefined;
|
|
151
|
-
/**
|
|
152
|
-
* Get the chain of wrapper elements between a word span and the root element.
|
|
153
|
-
* Returns outermost-first order (root's direct child → … → word's parent).
|
|
154
|
-
*/
|
|
155
|
-
private static _getWrapperChain;
|
|
156
|
-
/**
|
|
157
|
-
* Serialize an element's opening tag, preserving all attributes (class, style, data-*, etc).
|
|
158
|
-
*/
|
|
159
|
-
private static _openTag;
|
|
160
|
-
/**
|
|
161
|
-
* Escape HTML special characters
|
|
162
|
-
*/
|
|
163
|
-
private static _escapeHtml;
|
|
164
|
-
}
|