@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.
Files changed (252) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +20 -0
  3. package/README.ko.md +104 -0
  4. package/README.md +103 -2
  5. package/lib/module/accessibility/index.js +4 -0
  6. package/lib/module/accessibility/index.js.map +1 -0
  7. package/lib/module/accessibility/policies.js +39 -0
  8. package/lib/module/accessibility/policies.js.map +1 -0
  9. package/lib/module/controls/brand.js +4 -0
  10. package/lib/module/controls/brand.js.map +1 -0
  11. package/lib/module/controls/controls.js +28 -0
  12. package/lib/module/controls/controls.js.map +1 -0
  13. package/lib/module/controls/descriptors.js +55 -0
  14. package/lib/module/controls/descriptors.js.map +1 -0
  15. package/lib/module/controls/index.js +4 -0
  16. package/lib/module/controls/index.js.map +1 -0
  17. package/lib/module/effects/compose.js +48 -0
  18. package/lib/module/effects/compose.js.map +1 -0
  19. package/lib/module/effects/fade.js +15 -0
  20. package/lib/module/effects/fade.js.map +1 -0
  21. package/lib/module/effects/index.js +12 -0
  22. package/lib/module/effects/index.js.map +1 -0
  23. package/lib/module/effects/lineReveal.js +17 -0
  24. package/lib/module/effects/lineReveal.js.map +1 -0
  25. package/lib/module/effects/pulse.js +14 -0
  26. package/lib/module/effects/pulse.js.map +1 -0
  27. package/lib/module/effects/rise.js +14 -0
  28. package/lib/module/effects/rise.js.map +1 -0
  29. package/lib/module/effects/scale.js +15 -0
  30. package/lib/module/effects/scale.js.map +1 -0
  31. package/lib/module/effects/shake.js +14 -0
  32. package/lib/module/effects/shake.js.map +1 -0
  33. package/lib/module/effects/slide.js +15 -0
  34. package/lib/module/effects/slide.js.map +1 -0
  35. package/lib/module/effects/typewriter.js +19 -0
  36. package/lib/module/effects/typewriter.js.map +1 -0
  37. package/lib/module/effects/validation.js +10 -0
  38. package/lib/module/effects/validation.js.map +1 -0
  39. package/lib/module/index.js +10 -0
  40. package/lib/module/index.js.map +1 -0
  41. package/lib/module/package.json +1 -0
  42. package/lib/module/presets/index.js +35 -0
  43. package/lib/module/presets/index.js.map +1 -0
  44. package/lib/module/recipe/component.js +60 -0
  45. package/lib/module/recipe/component.js.map +1 -0
  46. package/lib/module/recipe/defineTextMotion.js +9 -0
  47. package/lib/module/recipe/defineTextMotion.js.map +1 -0
  48. package/lib/module/recipe/descriptors.js +60 -0
  49. package/lib/module/recipe/descriptors.js.map +1 -0
  50. package/lib/module/recipe/index.js +5 -0
  51. package/lib/module/recipe/index.js.map +1 -0
  52. package/lib/module/recipe/recipe.js +163 -0
  53. package/lib/module/recipe/recipe.js.map +1 -0
  54. package/lib/module/renderers/index.js +5 -0
  55. package/lib/module/renderers/index.js.map +1 -0
  56. package/lib/module/renderers/nativeText.js +494 -0
  57. package/lib/module/renderers/nativeText.js.map +1 -0
  58. package/lib/module/renderers/nativeTextControls.js +96 -0
  59. package/lib/module/renderers/nativeTextControls.js.map +1 -0
  60. package/lib/module/renderers/nativeTextLineLayout.js +290 -0
  61. package/lib/module/renderers/nativeTextLineLayout.js.map +1 -0
  62. package/lib/module/renderers/nativeTextPlayback.js +91 -0
  63. package/lib/module/renderers/nativeTextPlayback.js.map +1 -0
  64. package/lib/module/renderers/overlayText.js +543 -0
  65. package/lib/module/renderers/overlayText.js.map +1 -0
  66. package/lib/module/renderers/overlayTextLayout.js +182 -0
  67. package/lib/module/renderers/overlayTextLayout.js.map +1 -0
  68. package/lib/module/renderers/rendererMotion.js +264 -0
  69. package/lib/module/renderers/rendererMotion.js.map +1 -0
  70. package/lib/module/split/createToken.js +19 -0
  71. package/lib/module/split/createToken.js.map +1 -0
  72. package/lib/module/split/custom.js +57 -0
  73. package/lib/module/split/custom.js.map +1 -0
  74. package/lib/module/split/graphemes.js +25 -0
  75. package/lib/module/split/graphemes.js.map +1 -0
  76. package/lib/module/split/index.js +7 -0
  77. package/lib/module/split/index.js.map +1 -0
  78. package/lib/module/split/lines.js +43 -0
  79. package/lib/module/split/lines.js.map +1 -0
  80. package/lib/module/split/segmenter.js +74 -0
  81. package/lib/module/split/segmenter.js.map +1 -0
  82. package/lib/module/split/words.js +28 -0
  83. package/lib/module/split/words.js.map +1 -0
  84. package/lib/module/timeline/index.js +7 -0
  85. package/lib/module/timeline/index.js.map +1 -0
  86. package/lib/module/timeline/parallel.js +21 -0
  87. package/lib/module/timeline/parallel.js.map +1 -0
  88. package/lib/module/timeline/sequence.js +18 -0
  89. package/lib/module/timeline/sequence.js.map +1 -0
  90. package/lib/module/timeline/stagger.js +43 -0
  91. package/lib/module/timeline/stagger.js.map +1 -0
  92. package/lib/module/timeline/validation.js +24 -0
  93. package/lib/module/timeline/validation.js.map +1 -0
  94. package/lib/module/timeline/wave.js +25 -0
  95. package/lib/module/timeline/wave.js.map +1 -0
  96. package/lib/module/types/index.js +4 -0
  97. package/lib/module/types/index.js.map +1 -0
  98. package/lib/module/types/recipe.js +4 -0
  99. package/lib/module/types/recipe.js.map +1 -0
  100. package/lib/module/types/renderer.js +27 -0
  101. package/lib/module/types/renderer.js.map +1 -0
  102. package/lib/module/types/token.js +2 -0
  103. package/lib/module/types/token.js.map +1 -0
  104. package/lib/typescript/package.json +1 -0
  105. package/lib/typescript/src/accessibility/index.d.ts +2 -0
  106. package/lib/typescript/src/accessibility/index.d.ts.map +1 -0
  107. package/lib/typescript/src/accessibility/policies.d.ts +13 -0
  108. package/lib/typescript/src/accessibility/policies.d.ts.map +1 -0
  109. package/lib/typescript/src/controls/brand.d.ts +2 -0
  110. package/lib/typescript/src/controls/brand.d.ts.map +1 -0
  111. package/lib/typescript/src/controls/controls.d.ts +28 -0
  112. package/lib/typescript/src/controls/controls.d.ts.map +1 -0
  113. package/lib/typescript/src/controls/descriptors.d.ts +14 -0
  114. package/lib/typescript/src/controls/descriptors.d.ts.map +1 -0
  115. package/lib/typescript/src/controls/index.d.ts +3 -0
  116. package/lib/typescript/src/controls/index.d.ts.map +1 -0
  117. package/lib/typescript/src/effects/compose.d.ts +11 -0
  118. package/lib/typescript/src/effects/compose.d.ts.map +1 -0
  119. package/lib/typescript/src/effects/fade.d.ts +10 -0
  120. package/lib/typescript/src/effects/fade.d.ts.map +1 -0
  121. package/lib/typescript/src/effects/index.d.ts +10 -0
  122. package/lib/typescript/src/effects/index.d.ts.map +1 -0
  123. package/lib/typescript/src/effects/lineReveal.d.ts +11 -0
  124. package/lib/typescript/src/effects/lineReveal.d.ts.map +1 -0
  125. package/lib/typescript/src/effects/pulse.d.ts +8 -0
  126. package/lib/typescript/src/effects/pulse.d.ts.map +1 -0
  127. package/lib/typescript/src/effects/rise.d.ts +8 -0
  128. package/lib/typescript/src/effects/rise.d.ts.map +1 -0
  129. package/lib/typescript/src/effects/scale.d.ts +10 -0
  130. package/lib/typescript/src/effects/scale.d.ts.map +1 -0
  131. package/lib/typescript/src/effects/shake.d.ts +8 -0
  132. package/lib/typescript/src/effects/shake.d.ts.map +1 -0
  133. package/lib/typescript/src/effects/slide.d.ts +10 -0
  134. package/lib/typescript/src/effects/slide.d.ts.map +1 -0
  135. package/lib/typescript/src/effects/typewriter.d.ts +13 -0
  136. package/lib/typescript/src/effects/typewriter.d.ts.map +1 -0
  137. package/lib/typescript/src/effects/validation.d.ts +2 -0
  138. package/lib/typescript/src/effects/validation.d.ts.map +1 -0
  139. package/lib/typescript/src/index.d.ts +15 -0
  140. package/lib/typescript/src/index.d.ts.map +1 -0
  141. package/lib/typescript/src/presets/index.d.ts +10 -0
  142. package/lib/typescript/src/presets/index.d.ts.map +1 -0
  143. package/lib/typescript/src/recipe/component.d.ts +3 -0
  144. package/lib/typescript/src/recipe/component.d.ts.map +1 -0
  145. package/lib/typescript/src/recipe/defineTextMotion.d.ts +4 -0
  146. package/lib/typescript/src/recipe/defineTextMotion.d.ts.map +1 -0
  147. package/lib/typescript/src/recipe/descriptors.d.ts +15 -0
  148. package/lib/typescript/src/recipe/descriptors.d.ts.map +1 -0
  149. package/lib/typescript/src/recipe/index.d.ts +4 -0
  150. package/lib/typescript/src/recipe/index.d.ts.map +1 -0
  151. package/lib/typescript/src/recipe/recipe.d.ts +67 -0
  152. package/lib/typescript/src/recipe/recipe.d.ts.map +1 -0
  153. package/lib/typescript/src/renderers/index.d.ts +3 -0
  154. package/lib/typescript/src/renderers/index.d.ts.map +1 -0
  155. package/lib/typescript/src/renderers/nativeText.d.ts +13 -0
  156. package/lib/typescript/src/renderers/nativeText.d.ts.map +1 -0
  157. package/lib/typescript/src/renderers/nativeTextControls.d.ts +16 -0
  158. package/lib/typescript/src/renderers/nativeTextControls.d.ts.map +1 -0
  159. package/lib/typescript/src/renderers/nativeTextLineLayout.d.ts +84 -0
  160. package/lib/typescript/src/renderers/nativeTextLineLayout.d.ts.map +1 -0
  161. package/lib/typescript/src/renderers/nativeTextPlayback.d.ts +21 -0
  162. package/lib/typescript/src/renderers/nativeTextPlayback.d.ts.map +1 -0
  163. package/lib/typescript/src/renderers/overlayText.d.ts +13 -0
  164. package/lib/typescript/src/renderers/overlayText.d.ts.map +1 -0
  165. package/lib/typescript/src/renderers/overlayTextLayout.d.ts +36 -0
  166. package/lib/typescript/src/renderers/overlayTextLayout.d.ts.map +1 -0
  167. package/lib/typescript/src/renderers/rendererMotion.d.ts +53 -0
  168. package/lib/typescript/src/renderers/rendererMotion.d.ts.map +1 -0
  169. package/lib/typescript/src/split/createToken.d.ts +11 -0
  170. package/lib/typescript/src/split/createToken.d.ts.map +1 -0
  171. package/lib/typescript/src/split/custom.d.ts +17 -0
  172. package/lib/typescript/src/split/custom.d.ts.map +1 -0
  173. package/lib/typescript/src/split/graphemes.d.ts +4 -0
  174. package/lib/typescript/src/split/graphemes.d.ts.map +1 -0
  175. package/lib/typescript/src/split/index.d.ts +5 -0
  176. package/lib/typescript/src/split/index.d.ts.map +1 -0
  177. package/lib/typescript/src/split/lines.d.ts +4 -0
  178. package/lib/typescript/src/split/lines.d.ts.map +1 -0
  179. package/lib/typescript/src/split/segmenter.d.ts +18 -0
  180. package/lib/typescript/src/split/segmenter.d.ts.map +1 -0
  181. package/lib/typescript/src/split/words.d.ts +4 -0
  182. package/lib/typescript/src/split/words.d.ts.map +1 -0
  183. package/lib/typescript/src/timeline/index.d.ts +5 -0
  184. package/lib/typescript/src/timeline/index.d.ts.map +1 -0
  185. package/lib/typescript/src/timeline/parallel.d.ts +4 -0
  186. package/lib/typescript/src/timeline/parallel.d.ts.map +1 -0
  187. package/lib/typescript/src/timeline/sequence.d.ts +4 -0
  188. package/lib/typescript/src/timeline/sequence.d.ts.map +1 -0
  189. package/lib/typescript/src/timeline/stagger.d.ts +11 -0
  190. package/lib/typescript/src/timeline/stagger.d.ts.map +1 -0
  191. package/lib/typescript/src/timeline/validation.d.ts +4 -0
  192. package/lib/typescript/src/timeline/validation.d.ts.map +1 -0
  193. package/lib/typescript/src/timeline/wave.d.ts +11 -0
  194. package/lib/typescript/src/timeline/wave.d.ts.map +1 -0
  195. package/lib/typescript/src/types/index.d.ts +6 -0
  196. package/lib/typescript/src/types/index.d.ts.map +1 -0
  197. package/lib/typescript/src/types/recipe.d.ts +123 -0
  198. package/lib/typescript/src/types/recipe.d.ts.map +1 -0
  199. package/lib/typescript/src/types/renderer.d.ts +51 -0
  200. package/lib/typescript/src/types/renderer.d.ts.map +1 -0
  201. package/lib/typescript/src/types/token.d.ts +35 -0
  202. package/lib/typescript/src/types/token.d.ts.map +1 -0
  203. package/package.json +117 -3
  204. package/src/accessibility/index.ts +7 -0
  205. package/src/accessibility/policies.ts +60 -0
  206. package/src/controls/brand.ts +3 -0
  207. package/src/controls/controls.ts +41 -0
  208. package/src/controls/descriptors.ts +83 -0
  209. package/src/controls/index.ts +2 -0
  210. package/src/effects/compose.ts +98 -0
  211. package/src/effects/fade.ts +22 -0
  212. package/src/effects/index.ts +9 -0
  213. package/src/effects/lineReveal.ts +28 -0
  214. package/src/effects/pulse.ts +19 -0
  215. package/src/effects/rise.ts +19 -0
  216. package/src/effects/scale.ts +22 -0
  217. package/src/effects/shake.ts +19 -0
  218. package/src/effects/slide.ts +22 -0
  219. package/src/effects/typewriter.ts +16 -0
  220. package/src/effects/validation.ts +9 -0
  221. package/src/index.tsx +46 -0
  222. package/src/presets/index.ts +42 -0
  223. package/src/recipe/component.tsx +88 -0
  224. package/src/recipe/defineTextMotion.ts +6 -0
  225. package/src/recipe/descriptors.ts +158 -0
  226. package/src/recipe/index.ts +3 -0
  227. package/src/recipe/recipe.ts +359 -0
  228. package/src/renderers/index.ts +2 -0
  229. package/src/renderers/nativeText.tsx +813 -0
  230. package/src/renderers/nativeTextControls.ts +131 -0
  231. package/src/renderers/nativeTextLineLayout.ts +495 -0
  232. package/src/renderers/nativeTextPlayback.ts +204 -0
  233. package/src/renderers/overlayText.tsx +945 -0
  234. package/src/renderers/overlayTextLayout.ts +312 -0
  235. package/src/renderers/rendererMotion.ts +483 -0
  236. package/src/split/createToken.ts +26 -0
  237. package/src/split/custom.ts +92 -0
  238. package/src/split/graphemes.ts +27 -0
  239. package/src/split/index.ts +9 -0
  240. package/src/split/lines.ts +35 -0
  241. package/src/split/segmenter.ts +111 -0
  242. package/src/split/words.ts +28 -0
  243. package/src/timeline/index.ts +4 -0
  244. package/src/timeline/parallel.ts +30 -0
  245. package/src/timeline/sequence.ts +29 -0
  246. package/src/timeline/stagger.ts +60 -0
  247. package/src/timeline/validation.ts +29 -0
  248. package/src/timeline/wave.ts +34 -0
  249. package/src/types/index.ts +34 -0
  250. package/src/types/recipe.ts +195 -0
  251. package/src/types/renderer.ts +91 -0
  252. package/src/types/token.ts +39 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # @react-native-motion-kit/text-motion
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#9](https://github.com/react-native-motion-kit/react-native-text-motion/pull/9) [`c460a1c`](https://github.com/react-native-motion-kit/react-native-text-motion/commit/c460a1c42b4f7cf77b57b542009043c9f389d038) Thanks [@saseungmin](https://github.com/saseungmin)! - Link the published documentation site from the package homepage and refresh the English and Korean package READMEs with concise examples and AI documentation resources.
8
+
9
+ ## 0.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#6](https://github.com/react-native-motion-kit/react-native-text-motion/pull/6) [`99ce29a`](https://github.com/react-native-motion-kit/react-native-text-motion/commit/99ce29a602b8a81b5322642fe856b12be30763c4) Thanks [@saseungmin](https://github.com/saseungmin)! - Initial release with composable text-motion recipes, presets, token splitting, timelines, playback controls, app-owned progress, and reduced-motion support.
14
+ Includes fixed-layout Typewriter reveals and measured native-line animation with isolated reveal masks.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 harang
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,104 @@
1
+ # React Native Text Motion
2
+
3
+ > [English](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/packages/text-motion/README.md) | 한국어
4
+
5
+ <div align="center">
6
+ <img src="https://raw.githubusercontent.com/react-native-motion-kit/react-native-text-motion/main/docs/docs/public/logo.png" width="300" alt="React Native Motion Kit logo" />
7
+ </div>
8
+
9
+ ## 소개
10
+
11
+ `@react-native-motion-kit/text-motion`은 Reanimated 기반의 React Native 텍스트 애니메이션 라이브러리입니다. 짧은 제목, 레이블, 온보딩 문구에 맞춰 텍스트 분할 방식, 렌더러, 타임라인, 효과를 조합하고 재사용 가능한 컴포넌트를 만듭니다.
12
+
13
+ ### 주요 기능
14
+
15
+ - **조합 가능한 레시피** — 분할, 레이아웃, 타이밍, 효과를 TypeScript API로 구성합니다.
16
+ - **단어와 글자 애니메이션** — `nativeText()`로 단어나 그래핌을 움직이고 `typewriter()`로 한 글자씩 표시합니다.
17
+ - **실제 줄 기준 모션** — `overlayText()`와 `lineReveal()`로 React Native가 렌더링한 줄을 드러냅니다.
18
+ - **재생 제어** — 이벤트에서 play/replay/reset/stop을 실행하거나 외부 Reanimated shared value로 진행률을 제어합니다.
19
+ - **접근성** — 기본적으로 전체 문장을 하나의 레이블로 제공하고 장식용 토큰은 스크린 리더에서 숨깁니다. 모션 줄이기 설정도 반영합니다.
20
+ - **기본 프리셋** — 프리셋으로 시작하고 필요에 따라 레시피를 조정합니다.
21
+
22
+ ## 빠르게 시작하기
23
+
24
+ ### 문서
25
+
26
+ [한국어 문서](https://react-native-text-motion.pages.dev/ko/) · [설치](https://react-native-text-motion.pages.dev/ko/guide/getting-started/installation.html) · [빠른 시작](https://react-native-text-motion.pages.dev/ko/guide/getting-started/quick-start.html)
27
+
28
+ ### 예제
29
+
30
+ - [예제 모음](https://react-native-text-motion.pages.dev/ko/guide/usage/examples.html) — 동작을 확인하고 예제 코드를 살펴봅니다.
31
+ - [Expo 예제 앱](https://github.com/react-native-motion-kit/react-native-text-motion/tree/main/example) — 레시피, 재생 제어, 네이티브 줄 애니메이션을 실행합니다.
32
+
33
+ ### AI
34
+
35
+ [AI 도구와 함께 사용하기](https://react-native-text-motion.pages.dev/ko/guide/getting-started/ai.html)에서 문서 활용 방법을 확인하세요.
36
+
37
+ - [llms.txt](https://react-native-text-motion.pages.dev/ko/llms.txt) — 문서 제목과 링크를 담은 색인입니다.
38
+ - [llms-full.txt](https://react-native-text-motion.pages.dev/ko/llms-full.txt) — 전체 문서를 하나의 텍스트 파일로 제공합니다.
39
+ - [영문 색인](https://react-native-text-motion.pages.dev/llms.txt) · [영문 전체 문서](https://react-native-text-motion.pages.dev/llms-full.txt)
40
+
41
+ ### 설치
42
+
43
+ ```sh
44
+ pnpm add @react-native-motion-kit/text-motion react-native-reanimated react-native-worklets
45
+ ```
46
+
47
+ peer dependency 최소 버전은 Reanimated `4.0.0`, Worklets `0.5.0`입니다. 이 최소값만으로 네이티브 의존성의 호환성이 보장되지는 않습니다. [설치 가이드](https://react-native-text-motion.pages.dev/ko/guide/getting-started/installation.html)와 [Reanimated 공식 설정 안내](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/)에 따라 앱의 React Native 또는 Expo 버전에 맞게 설정하세요. Reanimated 4는 New Architecture가 필요합니다.
48
+
49
+ ### 기본 사용법
50
+
51
+ 프리셋에서 컴포넌트를 만들고 애니메이션을 적용할 텍스트를 전달하세요.
52
+
53
+ ```tsx
54
+ import { editorialRise } from '@react-native-motion-kit/text-motion/presets';
55
+
56
+ // 재사용할 컴포넌트는 렌더 함수 밖에서 만드세요.
57
+ const HeroReveal = editorialRise().component();
58
+
59
+ export function HeroTitle() {
60
+ return <HeroReveal>Design motion that feels native</HeroReveal>;
61
+ }
62
+ ```
63
+
64
+ 직접 레시피를 조합할 수도 있습니다. `stagger()`의 시간 단위는 초이며, `.component()`를 호출하기 전에 `.layout(...)`으로 렌더러를 선택해야 합니다.
65
+
66
+ ```tsx
67
+ import {
68
+ defineTextMotion,
69
+ fade,
70
+ nativeText,
71
+ rise,
72
+ stagger,
73
+ words,
74
+ } from '@react-native-motion-kit/text-motion';
75
+
76
+ const WordReveal = defineTextMotion()
77
+ .split(words())
78
+ .layout(nativeText())
79
+ .timeline(stagger(0.04))
80
+ .effect(fade().and(rise({ y: 12 })))
81
+ .component();
82
+ ```
83
+
84
+ 자세한 내용은 [레시피 API](https://react-native-text-motion.pages.dev/ko/api/recipe.html), [렌더러](https://react-native-text-motion.pages.dev/ko/api/renderers.html), [재생 제어](https://react-native-text-motion.pages.dev/ko/guide/usage/playback.html)를 참고하세요. `controls`와 외부 `progress`는 함께 사용할 수 없습니다.
85
+
86
+ ## 사용 범위
87
+
88
+ 짧은 UI 텍스트를 위한 라이브러리이며 네이티브 `Text`의 모든 기능을 대체하지 않습니다. `nativeText()`는 소스 토큰을, `overlayText()`는 실제 렌더링된 줄을 애니메이션 단위로 사용합니다. `overlayText()`에는 `.split(...)`을 추가하지 마세요. `lines()`는 명시적인 `\n`만 분리합니다.
89
+
90
+ 긴 문단이나 많은 애니메이션 행은 대상 기기에서 측정하세요. 브라우저 예제는 네이티브 성능 측정 자료가 아닙니다. [성능 안내](https://react-native-text-motion.pages.dev/ko/guide/usage/performance.html)와 [접근성 안내](https://react-native-text-motion.pages.dev/ko/guide/usage/accessibility.html)를 참고하세요.
91
+
92
+ ## 프로젝트 방향
93
+
94
+ 우선순위와 기능 아이디어는 [프로젝트 방향·로드맵 Discussion](https://github.com/react-native-motion-kit/react-native-text-motion/discussions/10)에서 논의합니다.
95
+
96
+ 라이브러리 확장 전 현재 우선순위와 설계 범위는 [프로젝트 맥락과 로드맵](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/ROADMAP.ko.md)을 참고하세요.
97
+
98
+ ## 개발 참여
99
+
100
+ [기여 가이드와 개발 환경](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/CONTRIBUTING.md)
101
+
102
+ ## License
103
+
104
+ [MIT](./LICENSE)
package/README.md CHANGED
@@ -1,3 +1,104 @@
1
- # Temporary Holding Version
1
+ # React Native Text Motion
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > English | [한국어](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/packages/text-motion/README.ko.md)
4
+
5
+ <div align="center">
6
+ <img src="https://raw.githubusercontent.com/react-native-motion-kit/react-native-text-motion/main/docs/docs/public/logo.png" width="300" alt="React Native Motion Kit logo" />
7
+ </div>
8
+
9
+ ## Overview
10
+
11
+ `@react-native-motion-kit/text-motion` brings composable text animations to React Native with Reanimated. Build reusable animated components for short titles, labels, onboarding copy, and product copy by choosing how text is split, rendered, timed, and animated.
12
+
13
+ ### Key Features
14
+
15
+ - **Composable recipes** — Combine splitting, layout, timelines, and effects with a typed API.
16
+ - **Word and character motion** — Animate words or graphemes with `nativeText()`, including character-by-character `typewriter()` reveals.
17
+ - **Rendered-line reveals** — Use `overlayText()` and `lineReveal()` to animate the lines React Native actually rendered.
18
+ - **Playback control** — Trigger play/replay/reset/stop from events or drive progress with an external Reanimated shared value.
19
+ - **Accessibility** — Read the whole phrase as one label, hide decorative tokens from screen readers, and respect reduced motion by default.
20
+ - **Ready-to-use presets** — Start with a preset, then customize its recipe when needed.
21
+
22
+ ## Quick Start
23
+
24
+ ### Documentation
25
+
26
+ [Full documentation](https://react-native-text-motion.pages.dev/) · [Installation](https://react-native-text-motion.pages.dev/guide/getting-started/installation.html) · [Quick start](https://react-native-text-motion.pages.dev/guide/getting-started/quick-start.html)
27
+
28
+ ### Examples
29
+
30
+ - [Examples gallery](https://react-native-text-motion.pages.dev/guide/usage/examples.html) — Explore demos and their source code.
31
+ - [Expo example app](https://github.com/react-native-motion-kit/react-native-text-motion/tree/main/example) — Run recipes, playback controls, and native rendered-line examples.
32
+
33
+ ### AI
34
+
35
+ See [Use with AI tools](https://react-native-text-motion.pages.dev/guide/getting-started/ai.html) for documentation workflows.
36
+
37
+ - [llms.txt](https://react-native-text-motion.pages.dev/llms.txt) — A structured index of documentation pages.
38
+ - [llms-full.txt](https://react-native-text-motion.pages.dev/llms-full.txt) — The complete documentation in one text file.
39
+ - [Korean index](https://react-native-text-motion.pages.dev/ko/llms.txt) · [Korean full documentation](https://react-native-text-motion.pages.dev/ko/llms-full.txt)
40
+
41
+ ### Installation
42
+
43
+ ```sh
44
+ pnpm add @react-native-motion-kit/text-motion react-native-reanimated react-native-worklets
45
+ ```
46
+
47
+ The peer minimums are Reanimated `4.0.0` and Worklets `0.5.0`. These minimums are not a complete native compatibility matrix. Follow the [installation guide](https://react-native-text-motion.pages.dev/guide/getting-started/installation.html) and [official Reanimated setup](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/) for your React Native or Expo version. Reanimated 4 requires the New Architecture.
48
+
49
+ ### Basic Usage
50
+
51
+ Create a component from a preset and pass the text you want to animate:
52
+
53
+ ```tsx
54
+ import { editorialRise } from '@react-native-motion-kit/text-motion/presets';
55
+
56
+ // Create the reusable component outside render.
57
+ const HeroReveal = editorialRise().component();
58
+
59
+ export function HeroTitle() {
60
+ return <HeroReveal>Design motion that feels native</HeroReveal>;
61
+ }
62
+ ```
63
+
64
+ For custom motion, compose a recipe. `stagger()` uses seconds, and `.component()` requires a renderer selected with `.layout(...)`.
65
+
66
+ ```tsx
67
+ import {
68
+ defineTextMotion,
69
+ fade,
70
+ nativeText,
71
+ rise,
72
+ stagger,
73
+ words,
74
+ } from '@react-native-motion-kit/text-motion';
75
+
76
+ const WordReveal = defineTextMotion()
77
+ .split(words())
78
+ .layout(nativeText())
79
+ .timeline(stagger(0.04))
80
+ .effect(fade().and(rise({ y: 12 })))
81
+ .component();
82
+ ```
83
+
84
+ Continue with the [recipe API](https://react-native-text-motion.pages.dev/api/recipe.html), [renderers](https://react-native-text-motion.pages.dev/api/renderers.html), and [playback guide](https://react-native-text-motion.pages.dev/guide/usage/playback.html). Use either `controls` or external `progress` on an instance; they cannot be combined.
85
+
86
+ ## Scope
87
+
88
+ Designed for short UI text, this library does not replace every native `Text` feature. `nativeText()` animates source tokens; `overlayText()` animates actual rendered lines and must not use `.split(...)`. The `lines()` splitter handles explicit `\n` characters only.
89
+
90
+ Measure long paragraphs and many animated rows on target devices. Browser demos are not native performance evidence. See [performance guidance](https://react-native-text-motion.pages.dev/guide/usage/performance.html) and [accessibility](https://react-native-text-motion.pages.dev/guide/usage/accessibility.html).
91
+
92
+ ## Project direction
93
+
94
+ Discuss priorities and feature ideas in [Project direction & roadmap](https://github.com/react-native-motion-kit/react-native-text-motion/discussions/10).
95
+
96
+ Read the [project context and roadmap](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/ROADMAP.md) for priorities and design boundaries before extending the library.
97
+
98
+ ## Contributing
99
+
100
+ [Contributing guide and development setup](https://github.com/react-native-motion-kit/react-native-text-motion/blob/main/CONTRIBUTING.md)
101
+
102
+ ## License
103
+
104
+ [MIT](./LICENSE)
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { createHiddenTokenAccessibilityProps, createParentAccessibilityProps, parentLabelPolicy, resolveAccessibleText } from "./policies.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createHiddenTokenAccessibilityProps","createParentAccessibilityProps","parentLabelPolicy","resolveAccessibleText"],"sourceRoot":"../../../src","sources":["accessibility/index.ts"],"mappings":";;AAAA,SACEA,mCAAmC,EACnCC,8BAA8B,EAC9BC,iBAAiB,EACjBC,qBAAqB,QAEhB,eAAY","ignoreList":[]}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ /** Options for {@link parentLabelPolicy}. */
4
+
5
+ /** Make the parent text node accessible and hide decorative animated token nodes. */
6
+ export function parentLabelPolicy(options = {}) {
7
+ return {
8
+ kind: 'parent-label',
9
+ parentLabel: true,
10
+ hideTokensFromAccessibility: true,
11
+ reducedMotion: options.reducedMotion ?? 'system'
12
+ };
13
+ }
14
+ export function resolveAccessibleText(children, tokens) {
15
+ if (children.length > 0) {
16
+ return children;
17
+ }
18
+ return tokens.map(token => token.text).join('');
19
+ }
20
+ export function createParentAccessibilityProps(policy, label) {
21
+ if (!policy.parentLabel) {
22
+ return {};
23
+ }
24
+ return {
25
+ accessibilityLabel: label,
26
+ accessible: true
27
+ };
28
+ }
29
+ export function createHiddenTokenAccessibilityProps(policy) {
30
+ if (!policy.hideTokensFromAccessibility) {
31
+ return {};
32
+ }
33
+ return {
34
+ accessibilityElementsHidden: true,
35
+ accessible: false,
36
+ importantForAccessibility: 'no-hide-descendants'
37
+ };
38
+ }
39
+ //# sourceMappingURL=policies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["parentLabelPolicy","options","kind","parentLabel","hideTokensFromAccessibility","reducedMotion","resolveAccessibleText","children","tokens","length","map","token","text","join","createParentAccessibilityProps","policy","label","accessibilityLabel","accessible","createHiddenTokenAccessibilityProps","accessibilityElementsHidden","importantForAccessibility"],"sourceRoot":"../../../src","sources":["accessibility/policies.ts"],"mappings":";;AAIA;;AAMA;AACA,OAAO,SAASA,iBAAiBA,CAC/BC,OAAiC,GAAG,CAAC,CAAC,EACP;EAC/B,OAAO;IACLC,IAAI,EAAE,cAAc;IACpBC,WAAW,EAAE,IAAI;IACjBC,2BAA2B,EAAE,IAAI;IACjCC,aAAa,EAAEJ,OAAO,CAACI,aAAa,IAAI;EAC1C,CAAC;AACH;AAEA,OAAO,SAASC,qBAAqBA,CACnCC,QAAgB,EAChBC,MAAkC,EAC1B;EACR,IAAID,QAAQ,CAACE,MAAM,GAAG,CAAC,EAAE;IACvB,OAAOF,QAAQ;EACjB;EAEA,OAAOC,MAAM,CAACE,GAAG,CAAEC,KAAK,IAAKA,KAAK,CAACC,IAAI,CAAC,CAACC,IAAI,CAAC,EAAE,CAAC;AACnD;AAEA,OAAO,SAASC,8BAA8BA,CAC5CC,MAAqC,EACrCC,KAAa,EACyC;EACtD,IAAI,CAACD,MAAM,CAACZ,WAAW,EAAE;IACvB,OAAO,CAAC,CAAC;EACX;EAEA,OAAO;IACLc,kBAAkB,EAAED,KAAK;IACzBE,UAAU,EAAE;EACd,CAAC;AACH;AAEA,OAAO,SAASC,mCAAmCA,CACjDJ,MAAqC,EACwD;EAC7F,IAAI,CAACA,MAAM,CAACX,2BAA2B,EAAE;IACvC,OAAO,CAAC,CAAC;EACX;EAEA,OAAO;IACLgB,2BAA2B,EAAE,IAAI;IACjCF,UAAU,EAAE,KAAK;IACjBG,yBAAyB,EAAE;EAC7B,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export const textMotionControlsBrand = Symbol('@react-native-motion-kit/text-motion.controls');
4
+ //# sourceMappingURL=brand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["textMotionControlsBrand","Symbol"],"sourceRoot":"../../../src","sources":["controls/brand.ts"],"mappings":";;AAAA,OAAO,MAAMA,uBAAsC,GAAGC,MAAM,CAC1D,+CACF,CAAC","ignoreList":[]}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ import { useRef } from 'react';
4
+ import { createTextMotionControlsHandle } from "./descriptors.js";
5
+
6
+ /**
7
+ * Command channel for event-driven text playback.
8
+ *
9
+ * Pass the returned controls object to a text motion component with
10
+ * `controls={controls}`. The controls object emits playback commands; the component still owns
11
+ * its recipe, timeline, effects, and `.motion()` transition.
12
+ */
13
+
14
+ /**
15
+ * Create a stable text motion command channel for event-driven playback.
16
+ *
17
+ * Use controls for button presses, screen focus, onboarding steps, and other discrete events.
18
+ * Use the `progress` prop instead when text should follow a raw scroll, gesture, or synchronized
19
+ * Reanimated shared value.
20
+ */
21
+ export function useTextMotionControls() {
22
+ const controls = useRef(undefined);
23
+ if (!controls.current) {
24
+ controls.current = createTextMotionControlsHandle();
25
+ }
26
+ return controls.current;
27
+ }
28
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useRef","createTextMotionControlsHandle","useTextMotionControls","controls","undefined","current"],"sourceRoot":"../../../src","sources":["controls/controls.ts"],"mappings":";;AAAA,SAASA,MAAM,QAAQ,OAAO;AAI9B,SAASC,8BAA8B,QAAQ,kBAAe;;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAA,EAAuB;EAC1D,MAAMC,QAAQ,GAAGH,MAAM,CAAiCI,SAAS,CAAC;EAElE,IAAI,CAACD,QAAQ,CAACE,OAAO,EAAE;IACrBF,QAAQ,CAACE,OAAO,GAAGJ,8BAA8B,CAAC,CAAC;EACrD;EAEA,OAAOE,QAAQ,CAACE,OAAO;AACzB","ignoreList":[]}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ import { textMotionControlsBrand } from "./brand.js";
4
+ const controlsDescriptors = new WeakMap();
5
+ export function createTextMotionControlsHandle() {
6
+ const listeners = new Set();
7
+ const descriptor = {
8
+ getListenerCount() {
9
+ return listeners.size;
10
+ },
11
+ subscribe(listener) {
12
+ listeners.add(listener);
13
+ return () => {
14
+ listeners.delete(listener);
15
+ };
16
+ }
17
+ };
18
+ const emit = createTextMotionControlEmitter(listeners);
19
+ const controls = {
20
+ [textMotionControlsBrand]: true,
21
+ play() {
22
+ emit('play');
23
+ },
24
+ replay() {
25
+ emit('replay');
26
+ },
27
+ reset() {
28
+ emit('reset');
29
+ },
30
+ stop() {
31
+ emit('stop');
32
+ }
33
+ };
34
+ controlsDescriptors.set(controls, descriptor);
35
+ return controls;
36
+ }
37
+ export function readTextMotionControlsDescriptor(controls) {
38
+ const descriptor = controlsDescriptors.get(controls);
39
+ if (descriptor) {
40
+ return descriptor;
41
+ }
42
+ throw new Error('@react-native-motion-kit/text-motion received an unknown controls handle.');
43
+ }
44
+ function createTextMotionControlEmitter(listeners) {
45
+ let nextCommandId = 0;
46
+ return kind => {
47
+ const command = {
48
+ id: nextCommandId + 1,
49
+ kind
50
+ };
51
+ nextCommandId = command.id;
52
+ listeners.forEach(listener => listener(command));
53
+ };
54
+ }
55
+ //# sourceMappingURL=descriptors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["textMotionControlsBrand","controlsDescriptors","WeakMap","createTextMotionControlsHandle","listeners","Set","descriptor","getListenerCount","size","subscribe","listener","add","delete","emit","createTextMotionControlEmitter","controls","play","replay","reset","stop","set","readTextMotionControlsDescriptor","get","Error","nextCommandId","kind","command","id","forEach"],"sourceRoot":"../../../src","sources":["controls/descriptors.ts"],"mappings":";;AAEA,SAASA,uBAAuB,QAAQ,YAAS;AAgBjD,MAAMC,mBAAmB,GAAG,IAAIC,OAAO,CAAmD,CAAC;AAE3F,OAAO,SAASC,8BAA8BA,CAAA,EAAuB;EACnE,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAAmC,CAAC;EAC7D,MAAMC,UAAwC,GAAG;IAC/CC,gBAAgBA,CAAA,EAAG;MACjB,OAAOH,SAAS,CAACI,IAAI;IACvB,CAAC;IACDC,SAASA,CAACC,QAAQ,EAAE;MAClBN,SAAS,CAACO,GAAG,CAACD,QAAQ,CAAC;MAEvB,OAAO,MAAM;QACXN,SAAS,CAACQ,MAAM,CAACF,QAAQ,CAAC;MAC5B,CAAC;IACH;EACF,CAAC;EACD,MAAMG,IAAI,GAAGC,8BAA8B,CAACV,SAAS,CAAC;EACtD,MAAMW,QAA4B,GAAG;IACnC,CAACf,uBAAuB,GAAG,IAAI;IAC/BgB,IAAIA,CAAA,EAAG;MACLH,IAAI,CAAC,MAAM,CAAC;IACd,CAAC;IACDI,MAAMA,CAAA,EAAG;MACPJ,IAAI,CAAC,QAAQ,CAAC;IAChB,CAAC;IACDK,KAAKA,CAAA,EAAG;MACNL,IAAI,CAAC,OAAO,CAAC;IACf,CAAC;IACDM,IAAIA,CAAA,EAAG;MACLN,IAAI,CAAC,MAAM,CAAC;IACd;EACF,CAAC;EAEDZ,mBAAmB,CAACmB,GAAG,CAACL,QAAQ,EAAET,UAAU,CAAC;EAE7C,OAAOS,QAAQ;AACjB;AAEA,OAAO,SAASM,gCAAgCA,CAC9CN,QAA4B,EACE;EAC9B,MAAMT,UAAU,GAAGL,mBAAmB,CAACqB,GAAG,CAACP,QAAQ,CAAC;EAEpD,IAAIT,UAAU,EAAE;IACd,OAAOA,UAAU;EACnB;EAEA,MAAM,IAAIiB,KAAK,CAAC,2EAA2E,CAAC;AAC9F;AAEA,SAAST,8BAA8BA,CACrCV,SAAgD,EACF;EAC9C,IAAIoB,aAAa,GAAG,CAAC;EAErB,OAAQC,IAAI,IAAK;IACf,MAAMC,OAAO,GAAG;MACdC,EAAE,EAAEH,aAAa,GAAG,CAAC;MACrBC;IACF,CAAC;IAEDD,aAAa,GAAGE,OAAO,CAACC,EAAE;IAC1BvB,SAAS,CAACwB,OAAO,CAAElB,QAAQ,IAAKA,QAAQ,CAACgB,OAAO,CAAC,CAAC;EACpD,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { useTextMotionControls } from "./controls.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useTextMotionControls"],"sourceRoot":"../../../src","sources":["controls/index.ts"],"mappings":";;AAAA,SAASA,qBAAqB,QAAQ,eAAY","ignoreList":[]}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ import { attachTextMotionEffectDescriptor, readTextMotionEffectDescriptor } from "../recipe/descriptors.js";
4
+ const DEFAULT_EFFECT_OPTIONS = {};
5
+ const NATIVE_TEXT_CAPABILITIES = ['native-text'];
6
+ function uniqueCapabilities(capabilities) {
7
+ return Array.from(new Set(capabilities));
8
+ }
9
+
10
+ /** Compose multiple effects into one ordered effect. */
11
+ export function composeTextMotionEffects(effects) {
12
+ const descriptors = effects.map(readTextMotionEffectDescriptor);
13
+ const requiredCapabilities = uniqueCapabilities(descriptors.flatMap(descriptor => descriptor.requiredCapabilities));
14
+ const composed = {
15
+ and(effect) {
16
+ return composeTextMotionEffects([...effects, effect]);
17
+ }
18
+ };
19
+ return attachTextMotionEffectDescriptor(composed, {
20
+ kind: 'effect',
21
+ name: descriptors.map(descriptor => descriptor.name).join('+'),
22
+ requiredCapabilities,
23
+ effects
24
+ });
25
+ }
26
+
27
+ /** Create a custom native-text effect without descriptor options. */
28
+
29
+ /** Create a custom native-text effect with typed descriptor options. */
30
+
31
+ /** Create a custom effect with typed descriptor options and renderer capabilities. */
32
+
33
+ /** Create a custom text-motion effect for built-in or custom renderers. */
34
+ export function createTextMotionEffect(name, options = DEFAULT_EFFECT_OPTIONS, requiredCapabilities = NATIVE_TEXT_CAPABILITIES) {
35
+ const effect = {
36
+ and(nextEffect) {
37
+ return composeTextMotionEffects([effect, nextEffect]);
38
+ }
39
+ };
40
+ const descriptor = {
41
+ kind: 'effect',
42
+ name,
43
+ options,
44
+ requiredCapabilities
45
+ };
46
+ return attachTextMotionEffectDescriptor(effect, descriptor);
47
+ }
48
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["attachTextMotionEffectDescriptor","readTextMotionEffectDescriptor","DEFAULT_EFFECT_OPTIONS","NATIVE_TEXT_CAPABILITIES","uniqueCapabilities","capabilities","Array","from","Set","composeTextMotionEffects","effects","descriptors","map","requiredCapabilities","flatMap","descriptor","composed","and","effect","kind","name","join","createTextMotionEffect","options","nextEffect"],"sourceRoot":"../../../src","sources":["effects/compose.ts"],"mappings":";;AAQA,SACEA,gCAAgC,EAChCC,8BAA8B,QACzB,0BAAuB;AAE9B,MAAMC,sBAAyD,GAAG,CAAC,CAAC;AACpE,MAAMC,wBAAkD,GAAG,CAAC,aAAa,CAAC;AAE1E,SAASC,kBAAkBA,CACzBC,YAAqC,EACZ;EACzB,OAAOC,KAAK,CAACC,IAAI,CAAC,IAAIC,GAAG,CAACH,YAAY,CAAC,CAAC;AAC1C;;AAEA;AACA,OAAO,SAASI,wBAAwBA,CACtCC,OAAkD,EAClB;EAChC,MAAMC,WAAW,GAAGD,OAAO,CAACE,GAAG,CAACX,8BAA8B,CAAC;EAC/D,MAAMY,oBAAoB,GAAGT,kBAAkB,CAC7CO,WAAW,CAACG,OAAO,CAAEC,UAAU,IAAKA,UAAU,CAACF,oBAAoB,CACrE,CAAC;EAED,MAAMG,QAAQ,GAAG;IACfC,GAAGA,CACDC,MAAoD,EACpD;MACA,OAAOT,wBAAwB,CAAkC,CAAC,GAAGC,OAAO,EAAEQ,MAAM,CAAC,CAAC;IACxF;EACF,CAAmC;EAEnC,OAAOlB,gCAAgC,CACrCgB,QAAQ,EACR;IACEG,IAAI,EAAE,QAAQ;IACdC,IAAI,EAAET,WAAW,CAACC,GAAG,CAAEG,UAAU,IAAKA,UAAU,CAACK,IAAI,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC;IAChER,oBAAoB;IACpBH;EACF,CACF,CAAC;AACH;;AAEA;;AAKA;;AAMA;;AAWA;AACA,OAAO,SAASY,sBAAsBA,CACpCF,IAAY,EACZG,OAA0C,GAAGrB,sBAAsB,EACnEW,oBAA6D,GAAGV,wBAAwB,EACnE;EACrB,MAAMe,MAAM,GAAG;IACbD,GAAGA,CACDO,UAAwD,EACxD;MACA,OAAOf,wBAAwB,CAAkD,CAC/ES,MAAM,EACNM,UAAU,CACX,CAAC;IACJ;EACF,CAAwB;EAExB,MAAMT,UAAyC,GAAG;IAChDI,IAAI,EAAE,QAAQ;IACdC,IAAI;IACJG,OAAO;IACPV;EACF,CAAC;EAED,OAAOb,gCAAgC,CAACkB,MAAM,EAAEH,UAAU,CAAC;AAC7D","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link fade}. */
7
+
8
+ /** Fade each token between opacity values. */
9
+ export function fade(options = {}) {
10
+ return createTextMotionEffect('fade', {
11
+ from: validateFiniteEffectNumber(options.from ?? 0, 'fade from'),
12
+ to: validateFiniteEffectNumber(options.to ?? 1, 'fade to')
13
+ }, ['style-transform']);
14
+ }
15
+ //# sourceMappingURL=fade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","fade","options","from","to"],"sourceRoot":"../../../src","sources":["effects/fade.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAQA;AACA,OAAO,SAASC,IAAIA,CAACC,OAAoB,GAAG,CAAC,CAAC,EAAE;EAC9C,OAAOH,sBAAsB,CAC3B,MAAM,EACN;IACEI,IAAI,EAAEH,0BAA0B,CAACE,OAAO,CAACC,IAAI,IAAI,CAAC,EAAE,WAAW,CAAC;IAChEC,EAAE,EAAEJ,0BAA0B,CAACE,OAAO,CAACE,EAAE,IAAI,CAAC,EAAE,SAAS;EAC3D,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ export { composeTextMotionEffects, createTextMotionEffect } from "./compose.js";
4
+ export { fade } from "./fade.js";
5
+ export { lineReveal } from "./lineReveal.js";
6
+ export { pulse } from "./pulse.js";
7
+ export { rise } from "./rise.js";
8
+ export { scale } from "./scale.js";
9
+ export { shake } from "./shake.js";
10
+ export { slide } from "./slide.js";
11
+ export { typewriter } from "./typewriter.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["composeTextMotionEffects","createTextMotionEffect","fade","lineReveal","pulse","rise","scale","shake","slide","typewriter"],"sourceRoot":"../../../src","sources":["effects/index.ts"],"mappings":";;AAAA,SAASA,wBAAwB,EAAEC,sBAAsB,QAAQ,cAAW;AAC5E,SAASC,IAAI,QAA0B,WAAQ;AAC/C,SAASC,UAAU,QAAgC,iBAAc;AACjE,SAASC,KAAK,QAA2B,YAAS;AAClD,SAASC,IAAI,QAA0B,WAAQ;AAC/C,SAASC,KAAK,QAA2B,YAAS;AAClD,SAASC,KAAK,QAA2B,YAAS;AAClD,SAASC,KAAK,QAA2B,YAAS;AAClD,SAASC,UAAU,QAAQ,iBAAc","ignoreList":[]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionRendererCapability } from "../types/renderer.js";
4
+ import { createTextMotionEffect } from "./compose.js";
5
+ import { validateFiniteEffectNumber } from "./validation.js";
6
+ const LINE_MASK_CAPABILITY = createTextMotionRendererCapability('line-mask');
7
+
8
+ /** Options for {@link lineReveal}. */
9
+
10
+ /** Reveal each React Native rendered line through an `overlayText()` line mask. */
11
+ export function lineReveal(options = {}) {
12
+ return createTextMotionEffect('lineReveal', {
13
+ fromOpacity: validateFiniteEffectNumber(options.fromOpacity ?? 0, 'lineReveal fromOpacity'),
14
+ y: validateFiniteEffectNumber(options.y ?? 16, 'lineReveal y')
15
+ }, [LINE_MASK_CAPABILITY, 'style-transform']);
16
+ }
17
+ //# sourceMappingURL=lineReveal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionRendererCapability","createTextMotionEffect","validateFiniteEffectNumber","LINE_MASK_CAPABILITY","lineReveal","options","fromOpacity","y"],"sourceRoot":"../../../src","sources":["effects/lineReveal.ts"],"mappings":";;AAEA,SAASA,kCAAkC,QAAQ,sBAAmB;AACtE,SAASC,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;AAEzD,MAAMC,oBAAkD,GACtDH,kCAAkC,CAAC,WAAW,CAAC;;AAEjD;;AAQA;AACA,OAAO,SAASI,UAAUA,CAACC,OAA0B,GAAG,CAAC,CAAC,EAAE;EAC1D,OAAOJ,sBAAsB,CAC3B,YAAY,EACZ;IACEK,WAAW,EAAEJ,0BAA0B,CAACG,OAAO,CAACC,WAAW,IAAI,CAAC,EAAE,wBAAwB,CAAC;IAC3FC,CAAC,EAAEL,0BAA0B,CAACG,OAAO,CAACE,CAAC,IAAI,EAAE,EAAE,cAAc;EAC/D,CAAC,EACD,CAACJ,oBAAoB,EAAE,iBAAiB,CAC1C,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link pulse}. */
7
+
8
+ /** Briefly emphasize each token by scaling it up and returning to its final scale. */
9
+ export function pulse(options = {}) {
10
+ return createTextMotionEffect('pulse', {
11
+ scale: validateFiniteEffectNumber(options.scale ?? 1.04, 'pulse scale')
12
+ }, ['style-transform']);
13
+ }
14
+ //# sourceMappingURL=pulse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","pulse","options","scale"],"sourceRoot":"../../../src","sources":["effects/pulse.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAMA;AACA,OAAO,SAASC,KAAKA,CAACC,OAAqB,GAAG,CAAC,CAAC,EAAE;EAChD,OAAOH,sBAAsB,CAC3B,OAAO,EACP;IACEI,KAAK,EAAEH,0BAA0B,CAACE,OAAO,CAACC,KAAK,IAAI,IAAI,EAAE,aAAa;EACxE,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link rise}. */
7
+
8
+ /** Move each token upward from a vertical offset. */
9
+ export function rise(options = {}) {
10
+ return createTextMotionEffect('rise', {
11
+ y: validateFiniteEffectNumber(options.y ?? 12, 'rise y')
12
+ }, ['style-transform']);
13
+ }
14
+ //# sourceMappingURL=rise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","rise","options","y"],"sourceRoot":"../../../src","sources":["effects/rise.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAMA;AACA,OAAO,SAASC,IAAIA,CAACC,OAAoB,GAAG,CAAC,CAAC,EAAE;EAC9C,OAAOH,sBAAsB,CAC3B,MAAM,EACN;IACEI,CAAC,EAAEH,0BAA0B,CAACE,OAAO,CAACC,CAAC,IAAI,EAAE,EAAE,QAAQ;EACzD,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link scale}. */
7
+
8
+ /** Scale each token between two scale values. */
9
+ export function scale(options = {}) {
10
+ return createTextMotionEffect('scale', {
11
+ from: validateFiniteEffectNumber(options.from ?? 0.96, 'scale from'),
12
+ to: validateFiniteEffectNumber(options.to ?? 1, 'scale to')
13
+ }, ['style-transform']);
14
+ }
15
+ //# sourceMappingURL=scale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","scale","options","from","to"],"sourceRoot":"../../../src","sources":["effects/scale.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAQA;AACA,OAAO,SAASC,KAAKA,CAACC,OAAqB,GAAG,CAAC,CAAC,EAAE;EAChD,OAAOH,sBAAsB,CAC3B,OAAO,EACP;IACEI,IAAI,EAAEH,0BAA0B,CAACE,OAAO,CAACC,IAAI,IAAI,IAAI,EAAE,YAAY,CAAC;IACpEC,EAAE,EAAEJ,0BAA0B,CAACE,OAAO,CAACE,EAAE,IAAI,CAAC,EAAE,UAAU;EAC5D,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link shake}. */
7
+
8
+ /** Offset each token horizontally for a shake-like entrance. */
9
+ export function shake(options = {}) {
10
+ return createTextMotionEffect('shake', {
11
+ x: validateFiniteEffectNumber(options.x ?? 4, 'shake x')
12
+ }, ['style-transform']);
13
+ }
14
+ //# sourceMappingURL=shake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","shake","options","x"],"sourceRoot":"../../../src","sources":["effects/shake.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAMA;AACA,OAAO,SAASC,KAAKA,CAACC,OAAqB,GAAG,CAAC,CAAC,EAAE;EAChD,OAAOH,sBAAsB,CAC3B,OAAO,EACP;IACEI,CAAC,EAAEH,0BAA0B,CAACE,OAAO,CAACC,CAAC,IAAI,CAAC,EAAE,SAAS;EACzD,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ import { createTextMotionEffect } from "./compose.js";
4
+ import { validateFiniteEffectNumber } from "./validation.js";
5
+
6
+ /** Options for {@link slide}. */
7
+
8
+ /** Move each token from an x/y offset into place. */
9
+ export function slide(options = {}) {
10
+ return createTextMotionEffect('slide', {
11
+ x: validateFiniteEffectNumber(options.x ?? 0, 'slide x'),
12
+ y: validateFiniteEffectNumber(options.y ?? 12, 'slide y')
13
+ }, ['style-transform']);
14
+ }
15
+ //# sourceMappingURL=slide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTextMotionEffect","validateFiniteEffectNumber","slide","options","x","y"],"sourceRoot":"../../../src","sources":["effects/slide.ts"],"mappings":";;AAAA,SAASA,sBAAsB,QAAQ,cAAW;AAClD,SAASC,0BAA0B,QAAQ,iBAAc;;AAEzD;;AAQA;AACA,OAAO,SAASC,KAAKA,CAACC,OAAqB,GAAG,CAAC,CAAC,EAAE;EAChD,OAAOH,sBAAsB,CAC3B,OAAO,EACP;IACEI,CAAC,EAAEH,0BAA0B,CAACE,OAAO,CAACC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IACxDC,CAAC,EAAEJ,0BAA0B,CAACE,OAAO,CAACE,CAAC,IAAI,EAAE,EAAE,SAAS;EAC1D,CAAC,EACD,CAAC,iBAAiB,CACpB,CAAC;AACH","ignoreList":[]}