@react-native-motion-kit/text-motion 0.0.0-stage → 0.1.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/CHANGELOG.md +14 -0
- package/LICENSE +20 -0
- package/README.ko.md +104 -0
- package/README.md +103 -2
- package/lib/module/accessibility/index.js +4 -0
- package/lib/module/accessibility/index.js.map +1 -0
- package/lib/module/accessibility/policies.js +39 -0
- package/lib/module/accessibility/policies.js.map +1 -0
- package/lib/module/controls/brand.js +4 -0
- package/lib/module/controls/brand.js.map +1 -0
- package/lib/module/controls/controls.js +28 -0
- package/lib/module/controls/controls.js.map +1 -0
- package/lib/module/controls/descriptors.js +55 -0
- package/lib/module/controls/descriptors.js.map +1 -0
- package/lib/module/controls/index.js +4 -0
- package/lib/module/controls/index.js.map +1 -0
- package/lib/module/effects/compose.js +48 -0
- package/lib/module/effects/compose.js.map +1 -0
- package/lib/module/effects/fade.js +15 -0
- package/lib/module/effects/fade.js.map +1 -0
- package/lib/module/effects/index.js +12 -0
- package/lib/module/effects/index.js.map +1 -0
- package/lib/module/effects/lineReveal.js +17 -0
- package/lib/module/effects/lineReveal.js.map +1 -0
- package/lib/module/effects/pulse.js +14 -0
- package/lib/module/effects/pulse.js.map +1 -0
- package/lib/module/effects/rise.js +14 -0
- package/lib/module/effects/rise.js.map +1 -0
- package/lib/module/effects/scale.js +15 -0
- package/lib/module/effects/scale.js.map +1 -0
- package/lib/module/effects/shake.js +14 -0
- package/lib/module/effects/shake.js.map +1 -0
- package/lib/module/effects/slide.js +15 -0
- package/lib/module/effects/slide.js.map +1 -0
- package/lib/module/effects/typewriter.js +19 -0
- package/lib/module/effects/typewriter.js.map +1 -0
- package/lib/module/effects/validation.js +10 -0
- package/lib/module/effects/validation.js.map +1 -0
- package/lib/module/index.js +10 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/presets/index.js +35 -0
- package/lib/module/presets/index.js.map +1 -0
- package/lib/module/recipe/component.js +60 -0
- package/lib/module/recipe/component.js.map +1 -0
- package/lib/module/recipe/defineTextMotion.js +9 -0
- package/lib/module/recipe/defineTextMotion.js.map +1 -0
- package/lib/module/recipe/descriptors.js +60 -0
- package/lib/module/recipe/descriptors.js.map +1 -0
- package/lib/module/recipe/index.js +5 -0
- package/lib/module/recipe/index.js.map +1 -0
- package/lib/module/recipe/recipe.js +163 -0
- package/lib/module/recipe/recipe.js.map +1 -0
- package/lib/module/renderers/index.js +5 -0
- package/lib/module/renderers/index.js.map +1 -0
- package/lib/module/renderers/nativeText.js +494 -0
- package/lib/module/renderers/nativeText.js.map +1 -0
- package/lib/module/renderers/nativeTextControls.js +96 -0
- package/lib/module/renderers/nativeTextControls.js.map +1 -0
- package/lib/module/renderers/nativeTextLineLayout.js +290 -0
- package/lib/module/renderers/nativeTextLineLayout.js.map +1 -0
- package/lib/module/renderers/nativeTextPlayback.js +91 -0
- package/lib/module/renderers/nativeTextPlayback.js.map +1 -0
- package/lib/module/renderers/overlayText.js +543 -0
- package/lib/module/renderers/overlayText.js.map +1 -0
- package/lib/module/renderers/overlayTextLayout.js +182 -0
- package/lib/module/renderers/overlayTextLayout.js.map +1 -0
- package/lib/module/renderers/rendererMotion.js +264 -0
- package/lib/module/renderers/rendererMotion.js.map +1 -0
- package/lib/module/split/createToken.js +19 -0
- package/lib/module/split/createToken.js.map +1 -0
- package/lib/module/split/custom.js +57 -0
- package/lib/module/split/custom.js.map +1 -0
- package/lib/module/split/graphemes.js +25 -0
- package/lib/module/split/graphemes.js.map +1 -0
- package/lib/module/split/index.js +7 -0
- package/lib/module/split/index.js.map +1 -0
- package/lib/module/split/lines.js +43 -0
- package/lib/module/split/lines.js.map +1 -0
- package/lib/module/split/segmenter.js +74 -0
- package/lib/module/split/segmenter.js.map +1 -0
- package/lib/module/split/words.js +28 -0
- package/lib/module/split/words.js.map +1 -0
- package/lib/module/timeline/index.js +7 -0
- package/lib/module/timeline/index.js.map +1 -0
- package/lib/module/timeline/parallel.js +21 -0
- package/lib/module/timeline/parallel.js.map +1 -0
- package/lib/module/timeline/sequence.js +18 -0
- package/lib/module/timeline/sequence.js.map +1 -0
- package/lib/module/timeline/stagger.js +43 -0
- package/lib/module/timeline/stagger.js.map +1 -0
- package/lib/module/timeline/validation.js +24 -0
- package/lib/module/timeline/validation.js.map +1 -0
- package/lib/module/timeline/wave.js +25 -0
- package/lib/module/timeline/wave.js.map +1 -0
- package/lib/module/types/index.js +4 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/recipe.js +4 -0
- package/lib/module/types/recipe.js.map +1 -0
- package/lib/module/types/renderer.js +27 -0
- package/lib/module/types/renderer.js.map +1 -0
- package/lib/module/types/token.js +2 -0
- package/lib/module/types/token.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/accessibility/index.d.ts +2 -0
- package/lib/typescript/src/accessibility/index.d.ts.map +1 -0
- package/lib/typescript/src/accessibility/policies.d.ts +13 -0
- package/lib/typescript/src/accessibility/policies.d.ts.map +1 -0
- package/lib/typescript/src/controls/brand.d.ts +2 -0
- package/lib/typescript/src/controls/brand.d.ts.map +1 -0
- package/lib/typescript/src/controls/controls.d.ts +28 -0
- package/lib/typescript/src/controls/controls.d.ts.map +1 -0
- package/lib/typescript/src/controls/descriptors.d.ts +14 -0
- package/lib/typescript/src/controls/descriptors.d.ts.map +1 -0
- package/lib/typescript/src/controls/index.d.ts +3 -0
- package/lib/typescript/src/controls/index.d.ts.map +1 -0
- package/lib/typescript/src/effects/compose.d.ts +11 -0
- package/lib/typescript/src/effects/compose.d.ts.map +1 -0
- package/lib/typescript/src/effects/fade.d.ts +10 -0
- package/lib/typescript/src/effects/fade.d.ts.map +1 -0
- package/lib/typescript/src/effects/index.d.ts +10 -0
- package/lib/typescript/src/effects/index.d.ts.map +1 -0
- package/lib/typescript/src/effects/lineReveal.d.ts +11 -0
- package/lib/typescript/src/effects/lineReveal.d.ts.map +1 -0
- package/lib/typescript/src/effects/pulse.d.ts +8 -0
- package/lib/typescript/src/effects/pulse.d.ts.map +1 -0
- package/lib/typescript/src/effects/rise.d.ts +8 -0
- package/lib/typescript/src/effects/rise.d.ts.map +1 -0
- package/lib/typescript/src/effects/scale.d.ts +10 -0
- package/lib/typescript/src/effects/scale.d.ts.map +1 -0
- package/lib/typescript/src/effects/shake.d.ts +8 -0
- package/lib/typescript/src/effects/shake.d.ts.map +1 -0
- package/lib/typescript/src/effects/slide.d.ts +10 -0
- package/lib/typescript/src/effects/slide.d.ts.map +1 -0
- package/lib/typescript/src/effects/typewriter.d.ts +13 -0
- package/lib/typescript/src/effects/typewriter.d.ts.map +1 -0
- package/lib/typescript/src/effects/validation.d.ts +2 -0
- package/lib/typescript/src/effects/validation.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/presets/index.d.ts +10 -0
- package/lib/typescript/src/presets/index.d.ts.map +1 -0
- package/lib/typescript/src/recipe/component.d.ts +3 -0
- package/lib/typescript/src/recipe/component.d.ts.map +1 -0
- package/lib/typescript/src/recipe/defineTextMotion.d.ts +4 -0
- package/lib/typescript/src/recipe/defineTextMotion.d.ts.map +1 -0
- package/lib/typescript/src/recipe/descriptors.d.ts +15 -0
- package/lib/typescript/src/recipe/descriptors.d.ts.map +1 -0
- package/lib/typescript/src/recipe/index.d.ts +4 -0
- package/lib/typescript/src/recipe/index.d.ts.map +1 -0
- package/lib/typescript/src/recipe/recipe.d.ts +67 -0
- package/lib/typescript/src/recipe/recipe.d.ts.map +1 -0
- package/lib/typescript/src/renderers/index.d.ts +3 -0
- package/lib/typescript/src/renderers/index.d.ts.map +1 -0
- package/lib/typescript/src/renderers/nativeText.d.ts +13 -0
- package/lib/typescript/src/renderers/nativeText.d.ts.map +1 -0
- package/lib/typescript/src/renderers/nativeTextControls.d.ts +16 -0
- package/lib/typescript/src/renderers/nativeTextControls.d.ts.map +1 -0
- package/lib/typescript/src/renderers/nativeTextLineLayout.d.ts +84 -0
- package/lib/typescript/src/renderers/nativeTextLineLayout.d.ts.map +1 -0
- package/lib/typescript/src/renderers/nativeTextPlayback.d.ts +21 -0
- package/lib/typescript/src/renderers/nativeTextPlayback.d.ts.map +1 -0
- package/lib/typescript/src/renderers/overlayText.d.ts +13 -0
- package/lib/typescript/src/renderers/overlayText.d.ts.map +1 -0
- package/lib/typescript/src/renderers/overlayTextLayout.d.ts +36 -0
- package/lib/typescript/src/renderers/overlayTextLayout.d.ts.map +1 -0
- package/lib/typescript/src/renderers/rendererMotion.d.ts +53 -0
- package/lib/typescript/src/renderers/rendererMotion.d.ts.map +1 -0
- package/lib/typescript/src/split/createToken.d.ts +11 -0
- package/lib/typescript/src/split/createToken.d.ts.map +1 -0
- package/lib/typescript/src/split/custom.d.ts +17 -0
- package/lib/typescript/src/split/custom.d.ts.map +1 -0
- package/lib/typescript/src/split/graphemes.d.ts +4 -0
- package/lib/typescript/src/split/graphemes.d.ts.map +1 -0
- package/lib/typescript/src/split/index.d.ts +5 -0
- package/lib/typescript/src/split/index.d.ts.map +1 -0
- package/lib/typescript/src/split/lines.d.ts +4 -0
- package/lib/typescript/src/split/lines.d.ts.map +1 -0
- package/lib/typescript/src/split/segmenter.d.ts +18 -0
- package/lib/typescript/src/split/segmenter.d.ts.map +1 -0
- package/lib/typescript/src/split/words.d.ts +4 -0
- package/lib/typescript/src/split/words.d.ts.map +1 -0
- package/lib/typescript/src/timeline/index.d.ts +5 -0
- package/lib/typescript/src/timeline/index.d.ts.map +1 -0
- package/lib/typescript/src/timeline/parallel.d.ts +4 -0
- package/lib/typescript/src/timeline/parallel.d.ts.map +1 -0
- package/lib/typescript/src/timeline/sequence.d.ts +4 -0
- package/lib/typescript/src/timeline/sequence.d.ts.map +1 -0
- package/lib/typescript/src/timeline/stagger.d.ts +11 -0
- package/lib/typescript/src/timeline/stagger.d.ts.map +1 -0
- package/lib/typescript/src/timeline/validation.d.ts +4 -0
- package/lib/typescript/src/timeline/validation.d.ts.map +1 -0
- package/lib/typescript/src/timeline/wave.d.ts +11 -0
- package/lib/typescript/src/timeline/wave.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +6 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/types/recipe.d.ts +123 -0
- package/lib/typescript/src/types/recipe.d.ts.map +1 -0
- package/lib/typescript/src/types/renderer.d.ts +51 -0
- package/lib/typescript/src/types/renderer.d.ts.map +1 -0
- package/lib/typescript/src/types/token.d.ts +35 -0
- package/lib/typescript/src/types/token.d.ts.map +1 -0
- package/package.json +117 -3
- package/src/accessibility/index.ts +7 -0
- package/src/accessibility/policies.ts +60 -0
- package/src/controls/brand.ts +3 -0
- package/src/controls/controls.ts +41 -0
- package/src/controls/descriptors.ts +83 -0
- package/src/controls/index.ts +2 -0
- package/src/effects/compose.ts +98 -0
- package/src/effects/fade.ts +22 -0
- package/src/effects/index.ts +9 -0
- package/src/effects/lineReveal.ts +28 -0
- package/src/effects/pulse.ts +19 -0
- package/src/effects/rise.ts +19 -0
- package/src/effects/scale.ts +22 -0
- package/src/effects/shake.ts +19 -0
- package/src/effects/slide.ts +22 -0
- package/src/effects/typewriter.ts +16 -0
- package/src/effects/validation.ts +9 -0
- package/src/index.tsx +46 -0
- package/src/presets/index.ts +42 -0
- package/src/recipe/component.tsx +88 -0
- package/src/recipe/defineTextMotion.ts +6 -0
- package/src/recipe/descriptors.ts +158 -0
- package/src/recipe/index.ts +3 -0
- package/src/recipe/recipe.ts +359 -0
- package/src/renderers/index.ts +2 -0
- package/src/renderers/nativeText.tsx +813 -0
- package/src/renderers/nativeTextControls.ts +131 -0
- package/src/renderers/nativeTextLineLayout.ts +495 -0
- package/src/renderers/nativeTextPlayback.ts +204 -0
- package/src/renderers/overlayText.tsx +945 -0
- package/src/renderers/overlayTextLayout.ts +312 -0
- package/src/renderers/rendererMotion.ts +483 -0
- package/src/split/createToken.ts +26 -0
- package/src/split/custom.ts +92 -0
- package/src/split/graphemes.ts +27 -0
- package/src/split/index.ts +9 -0
- package/src/split/lines.ts +35 -0
- package/src/split/segmenter.ts +111 -0
- package/src/split/words.ts +28 -0
- package/src/timeline/index.ts +4 -0
- package/src/timeline/parallel.ts +30 -0
- package/src/timeline/sequence.ts +29 -0
- package/src/timeline/stagger.ts +60 -0
- package/src/timeline/validation.ts +29 -0
- package/src/timeline/wave.ts +34 -0
- package/src/types/index.ts +34 -0
- package/src/types/recipe.ts +195 -0
- package/src/types/renderer.ts +91 -0
- package/src/types/token.ts +39 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TextMotionAccessibilityPolicy,
|
|
3
|
+
TextMotionAnyEffect,
|
|
4
|
+
TextMotionAnyTimeline,
|
|
5
|
+
TextMotionComponent,
|
|
6
|
+
TextMotionEffect,
|
|
7
|
+
TextMotionMotionConfig,
|
|
8
|
+
TextMotionRecipeConfig,
|
|
9
|
+
TextMotionRenderer,
|
|
10
|
+
TextMotionRendererCapability,
|
|
11
|
+
TextMotionSplitter,
|
|
12
|
+
} from '../types';
|
|
13
|
+
import type {
|
|
14
|
+
TextMotionCompatibleEffect,
|
|
15
|
+
TextMotionRenderedLineRenderer,
|
|
16
|
+
TextMotionSourceTokenRenderer,
|
|
17
|
+
} from '../types/renderer';
|
|
18
|
+
|
|
19
|
+
import { createTextMotionComponent } from './component';
|
|
20
|
+
|
|
21
|
+
type RecipeDraft<RendererCapabilities extends TextMotionRendererCapability> = {
|
|
22
|
+
splitter?: TextMotionSplitter;
|
|
23
|
+
renderer?: TextMotionRenderer<RendererCapabilities>;
|
|
24
|
+
timeline?: TextMotionAnyTimeline;
|
|
25
|
+
effects: readonly TextMotionAnyEffect[];
|
|
26
|
+
motion?: TextMotionMotionConfig;
|
|
27
|
+
accessibility?: TextMotionAccessibilityPolicy;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type RequiredCapabilitiesOfEffect<Effect extends TextMotionAnyEffect> =
|
|
31
|
+
Effect extends TextMotionEffect<infer RequiredCapabilities> ? RequiredCapabilities : never;
|
|
32
|
+
|
|
33
|
+
type CapabilitiesOfRenderer<Renderer> =
|
|
34
|
+
Renderer extends TextMotionRenderer<infer Capabilities, unknown> ? Capabilities : never;
|
|
35
|
+
|
|
36
|
+
type AnyTextMotionSourceTokenRenderer = TextMotionSourceTokenRenderer<
|
|
37
|
+
TextMotionRendererCapability,
|
|
38
|
+
unknown
|
|
39
|
+
>;
|
|
40
|
+
type AnyTextMotionRenderedLineRenderer = TextMotionRenderedLineRenderer<
|
|
41
|
+
TextMotionRendererCapability,
|
|
42
|
+
unknown
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
type TextMotionRecipeBuilderMethods<
|
|
46
|
+
RendererCapabilities extends TextMotionRendererCapability,
|
|
47
|
+
CurrentBuilder,
|
|
48
|
+
> = {
|
|
49
|
+
/** Choose the timing strategy for token delays. */
|
|
50
|
+
timeline(timeline: TextMotionAnyTimeline): CurrentBuilder;
|
|
51
|
+
|
|
52
|
+
/** Add an effect that is compatible with the selected renderer. */
|
|
53
|
+
effect<Effect extends TextMotionAnyEffect>(
|
|
54
|
+
effect: TextMotionCompatibleEffect<
|
|
55
|
+
RendererCapabilities,
|
|
56
|
+
RequiredCapabilitiesOfEffect<Effect>,
|
|
57
|
+
Effect
|
|
58
|
+
>,
|
|
59
|
+
): CurrentBuilder;
|
|
60
|
+
|
|
61
|
+
/** Configure the Reanimated motion primitive used by the renderer. */
|
|
62
|
+
motion(motion: TextMotionMotionConfig): CurrentBuilder;
|
|
63
|
+
|
|
64
|
+
/** Configure accessibility behavior such as reduced motion and token hiding. */
|
|
65
|
+
accessibility(accessibility: TextMotionAccessibilityPolicy): CurrentBuilder;
|
|
66
|
+
|
|
67
|
+
/** Return the immutable recipe config. */
|
|
68
|
+
recipe(): TextMotionRecipeConfig<RendererCapabilities>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** Builder state before a renderer has been selected. */
|
|
72
|
+
export interface TextMotionRecipeBuilder<
|
|
73
|
+
RendererCapabilities extends TextMotionRendererCapability = never,
|
|
74
|
+
> extends TextMotionRecipeBuilderMethods<
|
|
75
|
+
RendererCapabilities,
|
|
76
|
+
TextMotionRecipeBuilder<RendererCapabilities>
|
|
77
|
+
> {
|
|
78
|
+
/** Choose how the input string is split into tokens. */
|
|
79
|
+
split(splitter: TextMotionSplitter): TextMotionSplitRecipeBuilder<RendererCapabilities>;
|
|
80
|
+
|
|
81
|
+
/** Choose the renderer responsible for measuring and drawing split input. */
|
|
82
|
+
layout<Renderer extends AnyTextMotionSourceTokenRenderer>(
|
|
83
|
+
renderer: Renderer,
|
|
84
|
+
): TextMotionRenderableRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
85
|
+
|
|
86
|
+
/** Choose the renderer responsible for its own layout unit. */
|
|
87
|
+
layout<Renderer extends AnyTextMotionRenderedLineRenderer>(
|
|
88
|
+
renderer: Renderer,
|
|
89
|
+
): TextMotionRenderedLineRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Builder state after a splitter has been selected before renderer layout. */
|
|
93
|
+
interface TextMotionSplitRecipeBuilder<
|
|
94
|
+
RendererCapabilities extends TextMotionRendererCapability = never,
|
|
95
|
+
> extends TextMotionRecipeBuilderMethods<
|
|
96
|
+
RendererCapabilities,
|
|
97
|
+
TextMotionSplitRecipeBuilder<RendererCapabilities>
|
|
98
|
+
> {
|
|
99
|
+
/** Choose how the input string is split into tokens. */
|
|
100
|
+
split(splitter: TextMotionSplitter): TextMotionSplitRecipeBuilder<RendererCapabilities>;
|
|
101
|
+
|
|
102
|
+
/** Choose the renderer responsible for measuring and drawing split input. */
|
|
103
|
+
layout<Renderer extends AnyTextMotionSourceTokenRenderer>(
|
|
104
|
+
renderer: Renderer,
|
|
105
|
+
): TextMotionSplitRenderableRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Builder state after a renderer has been selected. */
|
|
109
|
+
export interface TextMotionRenderableRecipeBuilder<
|
|
110
|
+
RendererCapabilities extends TextMotionRendererCapability,
|
|
111
|
+
> extends TextMotionRecipeBuilderMethods<
|
|
112
|
+
RendererCapabilities,
|
|
113
|
+
TextMotionRenderableRecipeBuilder<RendererCapabilities>
|
|
114
|
+
> {
|
|
115
|
+
/** Choose how the input string is split into tokens. */
|
|
116
|
+
split(splitter: TextMotionSplitter): TextMotionSplitRenderableRecipeBuilder<RendererCapabilities>;
|
|
117
|
+
|
|
118
|
+
/** Choose the renderer responsible for measuring and drawing split input. */
|
|
119
|
+
layout<Renderer extends AnyTextMotionSourceTokenRenderer>(
|
|
120
|
+
renderer: Renderer,
|
|
121
|
+
): TextMotionRenderableRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
122
|
+
|
|
123
|
+
/** Choose the renderer responsible for its own layout unit. */
|
|
124
|
+
layout<Renderer extends AnyTextMotionRenderedLineRenderer>(
|
|
125
|
+
renderer: Renderer,
|
|
126
|
+
): TextMotionRenderedLineRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
127
|
+
|
|
128
|
+
/** Create a React component from the current recipe. */
|
|
129
|
+
component(): TextMotionComponent;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Builder state after a splittable renderer and splitter have been selected. */
|
|
133
|
+
export interface TextMotionSplitRenderableRecipeBuilder<
|
|
134
|
+
RendererCapabilities extends TextMotionRendererCapability,
|
|
135
|
+
> extends TextMotionRecipeBuilderMethods<
|
|
136
|
+
RendererCapabilities,
|
|
137
|
+
TextMotionSplitRenderableRecipeBuilder<RendererCapabilities>
|
|
138
|
+
> {
|
|
139
|
+
/** Choose how the input string is split into tokens. */
|
|
140
|
+
split(splitter: TextMotionSplitter): TextMotionSplitRenderableRecipeBuilder<RendererCapabilities>;
|
|
141
|
+
|
|
142
|
+
/** Choose the renderer responsible for measuring and drawing split input. */
|
|
143
|
+
layout<Renderer extends AnyTextMotionSourceTokenRenderer>(
|
|
144
|
+
renderer: Renderer,
|
|
145
|
+
): TextMotionSplitRenderableRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
146
|
+
|
|
147
|
+
/** Create a React component from the current recipe. */
|
|
148
|
+
component(): TextMotionComponent;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Builder state after a rendered-line renderer has been selected. */
|
|
152
|
+
interface TextMotionRenderedLineRecipeBuilder<
|
|
153
|
+
RendererCapabilities extends TextMotionRendererCapability,
|
|
154
|
+
> extends TextMotionRecipeBuilderMethods<
|
|
155
|
+
RendererCapabilities,
|
|
156
|
+
TextMotionRenderedLineRecipeBuilder<RendererCapabilities>
|
|
157
|
+
> {
|
|
158
|
+
/** Choose the renderer responsible for measuring and drawing split input. */
|
|
159
|
+
layout<Renderer extends AnyTextMotionSourceTokenRenderer>(
|
|
160
|
+
renderer: Renderer,
|
|
161
|
+
): TextMotionRenderableRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
162
|
+
|
|
163
|
+
/** Choose the renderer responsible for its own layout unit. */
|
|
164
|
+
layout<Renderer extends AnyTextMotionRenderedLineRenderer>(
|
|
165
|
+
renderer: Renderer,
|
|
166
|
+
): TextMotionRenderedLineRecipeBuilder<CapabilitiesOfRenderer<Renderer>>;
|
|
167
|
+
|
|
168
|
+
/** Create a React component from the current recipe. */
|
|
169
|
+
component(): TextMotionComponent;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function cloneTimingOptions(
|
|
173
|
+
options: Extract<TextMotionMotionConfig, { kind: 'timing' }>['options'],
|
|
174
|
+
) {
|
|
175
|
+
return options ? { ...options } : undefined;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function cloneSpringOptions(
|
|
179
|
+
options: Extract<TextMotionMotionConfig, { kind: 'spring' }>['options'],
|
|
180
|
+
) {
|
|
181
|
+
if (!options) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (options.clamp) {
|
|
186
|
+
return {
|
|
187
|
+
...options,
|
|
188
|
+
clamp: { ...options.clamp },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { ...options };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function cloneAccessibilityPolicy(
|
|
196
|
+
accessibility: TextMotionAccessibilityPolicy | undefined,
|
|
197
|
+
): TextMotionAccessibilityPolicy | undefined {
|
|
198
|
+
return accessibility ? { ...accessibility } : undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function validateMotionOptionValue(
|
|
202
|
+
kind: TextMotionMotionConfig['kind'],
|
|
203
|
+
path: string,
|
|
204
|
+
value: unknown,
|
|
205
|
+
): void {
|
|
206
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (typeof value === 'number') {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`@react-native-motion-kit/text-motion ${kind} motion option "${path}" must be a finite number.`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (Array.isArray(value)) {
|
|
217
|
+
value.forEach((item, index) => validateMotionOptionValue(kind, `${path}[${index}]`, item));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (value && typeof value === 'object') {
|
|
222
|
+
Object.entries(value).forEach(([key, nestedValue]) =>
|
|
223
|
+
validateMotionOptionValue(kind, `${path}.${key}`, nestedValue),
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function validateMotionConfig(motion: TextMotionMotionConfig): TextMotionMotionConfig {
|
|
229
|
+
if (motion.kind === 'spring') {
|
|
230
|
+
if (motion.options) {
|
|
231
|
+
validateMotionOptionValue(motion.kind, 'options', motion.options);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
kind: 'spring',
|
|
236
|
+
options: cloneSpringOptions(motion.options),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (motion.kind === 'timing') {
|
|
241
|
+
if (motion.options) {
|
|
242
|
+
validateMotionOptionValue(motion.kind, 'options', motion.options);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
kind: 'timing',
|
|
247
|
+
options: cloneTimingOptions(motion.options),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
throw new Error('@react-native-motion-kit/text-motion motion kind must be "timing" or "spring".');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function cloneMotionConfig(
|
|
255
|
+
motion: TextMotionMotionConfig | undefined,
|
|
256
|
+
): TextMotionMotionConfig | undefined {
|
|
257
|
+
return motion ? validateMotionConfig(motion) : undefined;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function cloneDraft<RendererCapabilities extends TextMotionRendererCapability>(
|
|
261
|
+
draft: RecipeDraft<RendererCapabilities>,
|
|
262
|
+
): RecipeDraft<RendererCapabilities> {
|
|
263
|
+
return {
|
|
264
|
+
...draft,
|
|
265
|
+
accessibility: cloneAccessibilityPolicy(draft.accessibility),
|
|
266
|
+
effects: [...draft.effects],
|
|
267
|
+
motion: cloneMotionConfig(draft.motion),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
class TextMotionRecipeBuilderImpl<
|
|
272
|
+
RendererCapabilities extends TextMotionRendererCapability = never,
|
|
273
|
+
> {
|
|
274
|
+
private readonly draft: RecipeDraft<RendererCapabilities>;
|
|
275
|
+
|
|
276
|
+
constructor(draft: Partial<RecipeDraft<RendererCapabilities>> = {}) {
|
|
277
|
+
this.draft = {
|
|
278
|
+
effects: draft.effects ? [...draft.effects] : [],
|
|
279
|
+
splitter: draft.splitter,
|
|
280
|
+
renderer: draft.renderer,
|
|
281
|
+
timeline: draft.timeline,
|
|
282
|
+
motion: draft.motion,
|
|
283
|
+
accessibility: draft.accessibility,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** Choose how the input string is split into tokens. */
|
|
288
|
+
split(splitter: TextMotionSplitter): TextMotionRecipeBuilderImpl<RendererCapabilities> {
|
|
289
|
+
return new TextMotionRecipeBuilderImpl<RendererCapabilities>({
|
|
290
|
+
...cloneDraft(this.draft),
|
|
291
|
+
splitter,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Choose the renderer responsible for measuring and drawing tokens. */
|
|
296
|
+
layout<NextCapabilities extends TextMotionRendererCapability>(
|
|
297
|
+
renderer: TextMotionRenderer<NextCapabilities, unknown>,
|
|
298
|
+
): TextMotionRecipeBuilderImpl<NextCapabilities> {
|
|
299
|
+
return new TextMotionRecipeBuilderImpl<NextCapabilities>({
|
|
300
|
+
...cloneDraft(this.draft),
|
|
301
|
+
renderer,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** Choose the timing strategy for token delays. */
|
|
306
|
+
timeline(timeline: TextMotionAnyTimeline): TextMotionRecipeBuilderImpl<RendererCapabilities> {
|
|
307
|
+
return new TextMotionRecipeBuilderImpl<RendererCapabilities>({
|
|
308
|
+
...cloneDraft(this.draft),
|
|
309
|
+
timeline,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Add an effect that is compatible with the selected renderer. */
|
|
314
|
+
effect<Effect extends TextMotionAnyEffect>(
|
|
315
|
+
effect: TextMotionCompatibleEffect<
|
|
316
|
+
RendererCapabilities,
|
|
317
|
+
RequiredCapabilitiesOfEffect<Effect>,
|
|
318
|
+
Effect
|
|
319
|
+
>,
|
|
320
|
+
): TextMotionRecipeBuilderImpl<RendererCapabilities> {
|
|
321
|
+
return new TextMotionRecipeBuilderImpl<RendererCapabilities>({
|
|
322
|
+
...cloneDraft(this.draft),
|
|
323
|
+
effects: [...this.draft.effects, effect],
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** Configure the Reanimated motion primitive used by the renderer. */
|
|
328
|
+
motion(motion: TextMotionMotionConfig): TextMotionRecipeBuilderImpl<RendererCapabilities> {
|
|
329
|
+
return new TextMotionRecipeBuilderImpl<RendererCapabilities>({
|
|
330
|
+
...cloneDraft(this.draft),
|
|
331
|
+
motion: validateMotionConfig(motion),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** Configure accessibility behavior such as reduced motion and token hiding. */
|
|
336
|
+
accessibility(
|
|
337
|
+
accessibility: TextMotionAccessibilityPolicy,
|
|
338
|
+
): TextMotionRecipeBuilderImpl<RendererCapabilities> {
|
|
339
|
+
return new TextMotionRecipeBuilderImpl<RendererCapabilities>({
|
|
340
|
+
...cloneDraft(this.draft),
|
|
341
|
+
accessibility,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Return the immutable recipe config. */
|
|
346
|
+
recipe(): TextMotionRecipeConfig<RendererCapabilities> {
|
|
347
|
+
return cloneDraft(this.draft);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Create a React component from the current recipe. */
|
|
351
|
+
component(): TextMotionComponent {
|
|
352
|
+
return createTextMotionComponent(cloneDraft(this.draft));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** @internal */
|
|
357
|
+
export function createTextMotionRecipeBuilder(): TextMotionRecipeBuilder {
|
|
358
|
+
return new TextMotionRecipeBuilderImpl() as TextMotionRecipeBuilder;
|
|
359
|
+
}
|