react-text-typing 0.1.0 โ 0.6.0
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 +175 -34
- package/assets/logo.png +0 -0
- package/dist/index.d.ts +19 -13
- package/dist/index.js +43 -15
- package/dist/index.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +68 -51
- package/dist/TextTyping.js +0 -141
- package/dist/TextTyping.test.js +0 -89
package/README.md
CHANGED
|
@@ -1,54 +1,195 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="react-text-typing" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">react-text-typing</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
A lightweight React component that creates a realistic typewriter animation effect with cursor blinking.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/react-text-typing">
|
|
13
|
+
<img src="https://img.shields.io/npm/v/react-text-typing?style=flat&color=0075D7" alt="npm version" />
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://github.com/Oda2/react-text-typing/actions">
|
|
16
|
+
<img src="https://github.com/Oda2/react-text-typing/actions/workflows/ci.yml/badge.svg" alt="CI" />
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://coveralls.io/github/Oda2/react-text-typing">
|
|
19
|
+
<img src="https://coveralls.io/repos/github/Oda2/react-text-typing/badge.svg?branch=main" alt="Coverage" />
|
|
20
|
+
</a>
|
|
21
|
+
<a href="https://bundlephobia.com/package/react-text-typing">
|
|
22
|
+
<img src="https://img.shields.io/bundlephobia/minzip/react-text-typing?color=0075D7" alt="Bundle Size" />
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://opensource.org/licenses/MIT">
|
|
25
|
+
<img src="https://img.shields.io/badge/license-MIT-0075D7.svg" alt="License" />
|
|
26
|
+
</a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## โจ Features
|
|
32
|
+
|
|
33
|
+
- ๐ฏ **Lightweight** - Zero dependencies, tiny bundle (~11kb gzipped)
|
|
34
|
+
- โก **Performant** - Built with React hooks, optimized for speed
|
|
35
|
+
- ๐จ **Customizable** - Colors, speed, font size, cursor blink
|
|
36
|
+
- โฟ **Accessible** - Semantic HTML, works with screen readers
|
|
37
|
+
- ๐ฆ **Tree-shakeable** - Import only what you need
|
|
38
|
+
- ๐ง **TypeScript** - Full TypeScript support included
|
|
39
|
+
- ๐งช **Well tested** - 100% test coverage
|
|
40
|
+
|
|
41
|
+
## ๐ฆ Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install react-text-typing
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
or
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yarn add react-text-typing
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## ๐ Quick Start
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import TextTyping from 'react-text-typing';
|
|
57
|
+
import 'react-text-typing/css';
|
|
58
|
+
|
|
59
|
+
function App() {
|
|
60
|
+
return <TextTyping text="Hello, World!" />;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## ๐ป Usage
|
|
65
|
+
|
|
66
|
+
### Basic
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<TextTyping text="Welcome to my website" />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Custom Speed
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<TextTyping text="Fast typing" speed={50} />
|
|
76
|
+
```
|
|
2
77
|
|
|
78
|
+
### Custom Colors
|
|
3
79
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://github.com/Oda2/react-text-typing/blob/master/LICENSE)
|
|
8
|
-
[](https://github.com/Oda2/react-text-typing/issues)
|
|
9
|
-
[](https://github.com/Oda2/react-text-typing/stargazers)
|
|
10
|
-
[](https://app.fossa.com/projects/git%2Bgithub.com%2FOda2%2Freact-text-typing?ref=badge_shield)
|
|
11
|
-
[](https://codesandbox.io/s/admiring-sun-5qry6?fontsize=14&hidenavigation=1&theme=dark)
|
|
80
|
+
```tsx
|
|
81
|
+
<TextTyping text="Custom colors" colorText="#ff6b6b" colorTyping="#4ecdc4" />
|
|
82
|
+
```
|
|
12
83
|
|
|
13
|
-
|
|
84
|
+
### Disable Cursor Blink
|
|
14
85
|
|
|
15
|
-
```
|
|
16
|
-
|
|
86
|
+
```tsx
|
|
87
|
+
<TextTyping text="No blink" showBlink={false} />
|
|
88
|
+
```
|
|
17
89
|
|
|
18
|
-
|
|
90
|
+
### Custom Font Size
|
|
19
91
|
|
|
20
|
-
|
|
92
|
+
```tsx
|
|
93
|
+
<TextTyping text="Big text" fontSize="3em" />
|
|
21
94
|
```
|
|
22
95
|
|
|
23
|
-
|
|
24
|
-
|
|
96
|
+
### With Callback
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<TextTyping text="Callback example" onComplete={() => console.log('Done!')} />
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Custom Component
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
<TextTyping text="Heading" component="h1" className="my-heading" />
|
|
106
|
+
```
|
|
25
107
|
|
|
26
|
-
##
|
|
108
|
+
## ๐ API Reference
|
|
109
|
+
|
|
110
|
+
| Prop | Type | Default | Description |
|
|
111
|
+
| ------------- | --------------------- | --------- | -------------------------------------- |
|
|
112
|
+
| `text` | `string` | Required | Text to type out |
|
|
113
|
+
| `speed` | `number` | `500` | Milliseconds between each character |
|
|
114
|
+
| `colorText` | `string` | `#fff` | Color of the typed text |
|
|
115
|
+
| `colorTyping` | `string` | `#0075D7` | Color of the typing effect |
|
|
116
|
+
| `showBlink` | `boolean` | `true` | Show/hide cursor blink |
|
|
117
|
+
| `fontSize` | `string` | `5em` | Font size of the text |
|
|
118
|
+
| `timeTyping` | `number` | `10` | Duration of typing animation (seconds) |
|
|
119
|
+
| `component` | `string \| Component` | `"span"` | HTML element or custom component |
|
|
120
|
+
| `onComplete` | `() => void` | - | Callback when typing finishes |
|
|
121
|
+
| `className` | `string` | - | Additional CSS class |
|
|
122
|
+
|
|
123
|
+
## ๐จ Styling
|
|
124
|
+
|
|
125
|
+
The component includes default CSS. To customize, you can:
|
|
126
|
+
|
|
127
|
+
1. **Override CSS variables:**
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<TextTyping text="Custom" colorText="#ff0000" colorTyping="#00ff00" />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
2. **Add your own styles:**
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
.text-typing {
|
|
137
|
+
font-family: 'Fira Code', monospace;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
3. **Import only CSS and customize:**
|
|
27
142
|
|
|
28
143
|
```js
|
|
29
|
-
import
|
|
30
|
-
|
|
31
|
-
import Text from 'react-text-typing';
|
|
144
|
+
import 'react-text-typing/css';
|
|
145
|
+
```
|
|
32
146
|
|
|
33
|
-
|
|
34
|
-
<Text
|
|
35
|
-
text="Example Text"
|
|
36
|
-
showBlink={true}
|
|
37
|
-
component="h1"
|
|
38
|
-
/>
|
|
39
|
-
);
|
|
147
|
+
## ๐ ๏ธ Development
|
|
40
148
|
|
|
41
|
-
|
|
149
|
+
```bash
|
|
150
|
+
# Install dependencies
|
|
151
|
+
npm install
|
|
152
|
+
|
|
153
|
+
# Run tests
|
|
154
|
+
npm test
|
|
155
|
+
|
|
156
|
+
# Run tests with coverage
|
|
157
|
+
npm run coverage
|
|
158
|
+
|
|
159
|
+
# Run Storybook
|
|
160
|
+
npm run dev
|
|
161
|
+
|
|
162
|
+
# Build library
|
|
163
|
+
npm run build:lib
|
|
164
|
+
|
|
165
|
+
# Lint
|
|
166
|
+
npm run lint
|
|
42
167
|
```
|
|
43
168
|
|
|
44
|
-
##
|
|
169
|
+
## ๐ค Contributing
|
|
170
|
+
|
|
171
|
+
Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) first.
|
|
172
|
+
|
|
173
|
+
1. Fork the repository
|
|
174
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
175
|
+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
176
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
177
|
+
5. Open a Pull Request
|
|
178
|
+
|
|
179
|
+
## ๐ Storybook
|
|
180
|
+
|
|
181
|
+
We use Storybook for component development and documentation. Run `npm run dev` to explore the component in an interactive environment.
|
|
182
|
+
|
|
183
|
+
## ๐ Issues
|
|
45
184
|
|
|
46
|
-
|
|
185
|
+
Found a bug? Please [open an issue](https://github.com/Oda2/react-text-typing/issues) with a detailed description.
|
|
47
186
|
|
|
48
|
-
|
|
187
|
+
## ๐ License
|
|
49
188
|
|
|
189
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
50
190
|
|
|
51
|
-
|
|
52
|
-
Licensed under [MIT](https://github.com/Oda2/react-text-typing/blob/master/LICENSE)
|
|
191
|
+
---
|
|
53
192
|
|
|
54
|
-
|
|
193
|
+
<p align="center">
|
|
194
|
+
Made with โค๏ธ by <a href="https://github.com/Oda2">Renato Oda</a>
|
|
195
|
+
</p>
|
package/assets/logo.png
ADDED
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
|
|
3
|
+
declare interface ITextTypingProps {
|
|
4
|
+
text: string;
|
|
5
|
+
component?: default_2.ElementType<any>;
|
|
6
|
+
colorText?: string;
|
|
7
|
+
colorTyping?: string;
|
|
8
|
+
showBlink?: boolean;
|
|
9
|
+
speed?: number;
|
|
10
|
+
timeTyping?: number;
|
|
11
|
+
fontSize?: string;
|
|
12
|
+
onComplete?: () => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const TextTyping: default_2.FC<ITextTypingProps>;
|
|
17
|
+
export default TextTyping;
|
|
18
|
+
|
|
19
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { jsx as D } from "react/jsx-runtime";
|
|
2
|
+
import { useState as m, useRef as y, useCallback as I, useEffect as T } from "react";
|
|
3
|
+
const q = ({
|
|
4
|
+
text: t,
|
|
5
|
+
showBlink: g = !0,
|
|
6
|
+
speed: s = 500,
|
|
7
|
+
component: d = "span",
|
|
8
|
+
colorText: x = "#000000",
|
|
9
|
+
colorTyping: $ = "#0075D7",
|
|
10
|
+
timeTyping: R = 10,
|
|
11
|
+
fontSize: c,
|
|
12
|
+
onComplete: o,
|
|
13
|
+
className: u = "",
|
|
14
|
+
...b
|
|
15
|
+
}) => {
|
|
16
|
+
const [i, l] = m(""), [e, a] = m(0), n = y(!1), f = y(t), p = I(() => {
|
|
17
|
+
l(""), a(0), n.current = !1;
|
|
18
|
+
}, []);
|
|
19
|
+
T(() => {
|
|
20
|
+
f.current !== t && (f.current = t, p());
|
|
21
|
+
}, [t, p]), T(() => {
|
|
22
|
+
if (e >= t.length) {
|
|
23
|
+
n.current || (n.current = !0, o?.());
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const C = setTimeout(() => {
|
|
27
|
+
l((r) => r + t[e]), a((r) => r + 1);
|
|
28
|
+
}, s);
|
|
29
|
+
return () => clearTimeout(C);
|
|
30
|
+
}, [e, t, s, o]);
|
|
31
|
+
const h = `text-typing${g ? "" : " no-blink"}${u ? ` ${u}` : ""}`, k = {
|
|
32
|
+
"--color-text": x,
|
|
33
|
+
"--color-typing": $,
|
|
34
|
+
"--internal-text": i,
|
|
35
|
+
"--time-typing": `${R}s`,
|
|
36
|
+
...c && { fontSize: c }
|
|
37
|
+
};
|
|
38
|
+
return /* @__PURE__ */ D(d, { className: h, style: k, "data-text": t, ...b, children: i });
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
q as default
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../lib/TextTyping.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useRef } from 'react';\nimport './TextTyping.css';\n\nexport interface ITextTypingProps {\n text: string;\n component?: React.ElementType<any>;\n colorText?: string;\n colorTyping?: string;\n showBlink?: boolean;\n speed?: number;\n timeTyping?: number;\n fontSize?: string;\n onComplete?: () => void;\n className?: string;\n}\n\nexport const TextTyping: React.FC<ITextTypingProps> = ({\n text,\n showBlink = true,\n speed = 500,\n component: Component = 'span',\n colorText = '#000000',\n colorTyping = '#0075D7',\n timeTyping = 10,\n fontSize,\n onComplete,\n className = '',\n ...props\n}) => {\n const [displayText, setDisplayText] = useState('');\n const [currentIndex, setCurrentIndex] = useState(0);\n const isCompleteRef = useRef(false);\n const textRef = useRef(text);\n\n const reset = useCallback(() => {\n setDisplayText('');\n setCurrentIndex(0);\n isCompleteRef.current = false;\n }, []);\n\n useEffect(() => {\n if (textRef.current !== text) {\n textRef.current = text;\n reset();\n }\n }, [text, reset]);\n\n useEffect(() => {\n if (currentIndex >= text.length) {\n if (!isCompleteRef.current) {\n isCompleteRef.current = true;\n onComplete?.();\n }\n return;\n }\n\n const typingTimeout = setTimeout(() => {\n setDisplayText((prev) => prev + text[currentIndex]);\n setCurrentIndex((prev) => prev + 1);\n }, speed);\n\n return () => clearTimeout(typingTimeout);\n }, [currentIndex, text, speed, onComplete]);\n\n const classes = `text-typing${showBlink ? '' : ' no-blink'}${className ? ` ${className}` : ''}`;\n\n const style = {\n '--color-text': colorText,\n '--color-typing': colorTyping,\n '--internal-text': displayText,\n '--time-typing': `${timeTyping}s`,\n ...(fontSize && { fontSize }),\n } as React.CSSProperties;\n\n return (\n <Component className={classes} style={style} data-text={text} {...props}>\n {displayText}\n </Component>\n );\n};\n\nexport default TextTyping;\n"],"names":["TextTyping","text","showBlink","speed","Component","colorText","colorTyping","timeTyping","fontSize","onComplete","className","props","displayText","setDisplayText","useState","currentIndex","setCurrentIndex","isCompleteRef","useRef","textRef","reset","useCallback","useEffect","typingTimeout","prev","classes","style","jsx"],"mappings":";;AAgBO,MAAMA,IAAyC,CAAC;AAAA,EACrD,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ;AAAA,EACR,WAAWC,IAAY;AAAA,EACvB,WAAAC,IAAY;AAAA,EACZ,aAAAC,IAAc;AAAA,EACd,YAAAC,IAAa;AAAA,EACb,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,GAAGC;AACL,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAIC,EAAS,EAAE,GAC3C,CAACC,GAAcC,CAAe,IAAIF,EAAS,CAAC,GAC5CG,IAAgBC,EAAO,EAAK,GAC5BC,IAAUD,EAAOjB,CAAI,GAErBmB,IAAQC,EAAY,MAAM;AAC9B,IAAAR,EAAe,EAAE,GACjBG,EAAgB,CAAC,GACjBC,EAAc,UAAU;AAAA,EAC1B,GAAG,CAAA,CAAE;AAEL,EAAAK,EAAU,MAAM;AACd,IAAIH,EAAQ,YAAYlB,MACtBkB,EAAQ,UAAUlB,GAClBmB,EAAA;AAAA,EAEJ,GAAG,CAACnB,GAAMmB,CAAK,CAAC,GAEhBE,EAAU,MAAM;AACd,QAAIP,KAAgBd,EAAK,QAAQ;AAC/B,MAAKgB,EAAc,YACjBA,EAAc,UAAU,IACxBR,IAAA;AAEF;AAAA,IACF;AAEA,UAAMc,IAAgB,WAAW,MAAM;AACrC,MAAAV,EAAe,CAACW,MAASA,IAAOvB,EAAKc,CAAY,CAAC,GAClDC,EAAgB,CAACQ,MAASA,IAAO,CAAC;AAAA,IACpC,GAAGrB,CAAK;AAER,WAAO,MAAM,aAAaoB,CAAa;AAAA,EACzC,GAAG,CAACR,GAAcd,GAAME,GAAOM,CAAU,CAAC;AAE1C,QAAMgB,IAAU,cAAcvB,IAAY,KAAK,WAAW,GAAGQ,IAAY,IAAIA,CAAS,KAAK,EAAE,IAEvFgB,IAAQ;AAAA,IACZ,gBAAgBrB;AAAA,IAChB,kBAAkBC;AAAA,IAClB,mBAAmBM;AAAA,IACnB,iBAAiB,GAAGL,CAAU;AAAA,IAC9B,GAAIC,KAAY,EAAE,UAAAA,EAAA;AAAA,EAAS;AAG7B,SACE,gBAAAmB,EAACvB,KAAU,WAAWqB,GAAS,OAAAC,GAAc,aAAWzB,GAAO,GAAGU,GAC/D,UAAAC,EAAA,CACH;AAEJ;"}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.text-typing{position:relative;color:var(--color-text, #fff);font-size:var(--font-size, 5em);margin:0;padding:0;border-right:.1em solid;animation:blinking .8s linear infinite}.text-typing:before{content:var(--internal-text);position:absolute;overflow:hidden;white-space:nowrap;animation:loading var(--time-typing, 10s) steps(80);max-width:100%;color:var(--color-typing, #0075d7)}.text-typing.no-blink{animation:none}@keyframes blinking{0%{border-color:transparent}50%{border-color:#000}}@keyframes loading{0%{max-width:0%}}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
+
"type": "module",
|
|
2
3
|
"name": "react-text-typing",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"registry": "https://registry.npmjs.org/"
|
|
7
|
+
},
|
|
8
|
+
"version": "0.6.0",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"style": "./dist/style.css",
|
|
7
12
|
"homepage": "https://renato-oda2.gitbook.io/react-text-typing",
|
|
8
13
|
"license": "MIT",
|
|
9
14
|
"author": {
|
|
@@ -12,67 +17,79 @@
|
|
|
12
17
|
},
|
|
13
18
|
"repository": {
|
|
14
19
|
"type": "git",
|
|
15
|
-
"url": "
|
|
20
|
+
"url": "https://github.com/Oda2/react-text-typing"
|
|
16
21
|
},
|
|
17
22
|
"keywords": [
|
|
18
23
|
"react",
|
|
19
|
-
"library"
|
|
24
|
+
"library",
|
|
25
|
+
"typing",
|
|
26
|
+
"animation"
|
|
20
27
|
],
|
|
21
28
|
"bugs": {
|
|
22
29
|
"url": "https://github.com/oda2/react-text-typing/issues"
|
|
23
30
|
},
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"**/*.css"
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./css": "./dist/style.css",
|
|
40
|
+
"./assets/logo.png": "./assets/logo.png"
|
|
41
|
+
},
|
|
24
42
|
"files": [
|
|
25
|
-
"dist"
|
|
43
|
+
"dist",
|
|
44
|
+
"assets"
|
|
26
45
|
],
|
|
27
46
|
"scripts": {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
47
|
+
"dev": "storybook dev -p 6006",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"test:watch": "vitest",
|
|
50
|
+
"coverage": "vitest run --coverage",
|
|
51
|
+
"build": "storybook build",
|
|
52
|
+
"build:lib": "tsc && vite build",
|
|
30
53
|
"lint": "eslint .",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls",
|
|
34
|
-
"cypress": "$(yarn bin)/cypress"
|
|
54
|
+
"format": "prettier . --write --ignore-unknown",
|
|
55
|
+
"cypress": "cypress"
|
|
35
56
|
},
|
|
36
57
|
"devDependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
58
|
+
"@storybook/addon-actions": "^8.6.17",
|
|
59
|
+
"@storybook/addon-essentials": "^8.6.17",
|
|
60
|
+
"@storybook/addon-links": "^8.6.17",
|
|
61
|
+
"@storybook/react": "^8.6.17",
|
|
62
|
+
"@storybook/react-vite": "^8.6.17",
|
|
63
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
64
|
+
"@testing-library/react": "^16.1.0",
|
|
65
|
+
"@types/node": "^22.10.0",
|
|
66
|
+
"@types/prop-types": "^15.7.15",
|
|
67
|
+
"@types/react": "^19.0.0",
|
|
68
|
+
"@types/react-dom": "^19.0.0",
|
|
69
|
+
"@vitejs/plugin-react-swc": "^3.7.0",
|
|
70
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
71
|
+
"cypress": "^15.10.0",
|
|
72
|
+
"eslint": "^9.17.0",
|
|
73
|
+
"eslint-config-prettier": "^9.1.0",
|
|
74
|
+
"eslint-plugin-jest-dom": "^5.5.0",
|
|
75
|
+
"eslint-plugin-react": "^7.37.5",
|
|
76
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
77
|
+
"eslint-plugin-react-refresh": "^0.5.0",
|
|
78
|
+
"eslint-plugin-storybook": "^0.8.0",
|
|
79
|
+
"jsdom": "^26.0.0",
|
|
80
|
+
"prettier": "^3.4.2",
|
|
45
81
|
"prop-types": "^15.8.1",
|
|
46
|
-
"react": "^
|
|
47
|
-
"react-
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"not op_mini all"
|
|
55
|
-
],
|
|
56
|
-
"development": [
|
|
57
|
-
"last 1 chrome version",
|
|
58
|
-
"last 1 firefox version",
|
|
59
|
-
"last 1 safari version"
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
"dependencies": {
|
|
63
|
-
"react-jss": "^10.9.0"
|
|
82
|
+
"react": "^19.0.0",
|
|
83
|
+
"react-dom": "^19.0.0",
|
|
84
|
+
"storybook": "^8.6.17",
|
|
85
|
+
"typescript": "^5.9.3",
|
|
86
|
+
"typescript-eslint": "^8.56.0",
|
|
87
|
+
"vite": "^6.0.0",
|
|
88
|
+
"vite-plugin-dts": "^4.3.0",
|
|
89
|
+
"vitest": "^4.0.18"
|
|
64
90
|
},
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
],
|
|
69
|
-
"coverageThreshold": {
|
|
70
|
-
"global": {
|
|
71
|
-
"branches": 100,
|
|
72
|
-
"functions": 100,
|
|
73
|
-
"lines": 100,
|
|
74
|
-
"statements": 100
|
|
75
|
-
}
|
|
76
|
-
}
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"react": "^19.0.0",
|
|
93
|
+
"react-dom": "^19.0.0"
|
|
77
94
|
}
|
|
78
95
|
}
|
package/dist/TextTyping.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "__esModule", {
|
|
8
|
-
value: true
|
|
9
|
-
});
|
|
10
|
-
exports.default = void 0;
|
|
11
|
-
|
|
12
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
13
|
-
|
|
14
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
15
|
-
|
|
16
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
17
|
-
|
|
18
|
-
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
19
|
-
|
|
20
|
-
var _react = _interopRequireWildcard(require("react"));
|
|
21
|
-
|
|
22
|
-
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
23
|
-
|
|
24
|
-
var _reactJss = require("react-jss");
|
|
25
|
-
|
|
26
|
-
var _excluded = ["text", "showBlink", "speed", "component"];
|
|
27
|
-
|
|
28
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
29
|
-
|
|
30
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
31
|
-
|
|
32
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
33
|
-
|
|
34
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
35
|
-
|
|
36
|
-
var TextTyping = function TextTyping(_ref) {
|
|
37
|
-
var text = _ref.text,
|
|
38
|
-
showBlink = _ref.showBlink,
|
|
39
|
-
speed = _ref.speed,
|
|
40
|
-
Component = _ref.component,
|
|
41
|
-
props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
|
|
42
|
-
var classes = useStyles(_objectSpread({}, props));
|
|
43
|
-
|
|
44
|
-
var _useState = (0, _react.useState)(''),
|
|
45
|
-
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
46
|
-
internalText = _useState2[0],
|
|
47
|
-
setInternalText = _useState2[1];
|
|
48
|
-
|
|
49
|
-
var timer = (0, _react.useRef)(null);
|
|
50
|
-
(0, _react.useEffect)(function () {
|
|
51
|
-
var typing = text.split('');
|
|
52
|
-
timer.current = setInterval(function () {
|
|
53
|
-
if (typing.length > 0) {
|
|
54
|
-
var next = typing.shift();
|
|
55
|
-
setInternalText(function (value) {
|
|
56
|
-
return value + next;
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
clearInterval(timer.current);
|
|
60
|
-
}
|
|
61
|
-
}, speed);
|
|
62
|
-
return function () {};
|
|
63
|
-
}, [text]);
|
|
64
|
-
return /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({
|
|
65
|
-
className: "".concat(classes.text, " ").concat(showBlink ? classes.blink : ''),
|
|
66
|
-
"data-text": internalText
|
|
67
|
-
}, props), internalText);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
var useStyles = (0, _reactJss.createUseStyles)({
|
|
71
|
-
text: {
|
|
72
|
-
position: 'relative',
|
|
73
|
-
color: function color(props) {
|
|
74
|
-
return props.colorText;
|
|
75
|
-
},
|
|
76
|
-
fontSize: '5em',
|
|
77
|
-
'&:before': {
|
|
78
|
-
content: 'attr(data-text)',
|
|
79
|
-
position: 'absolute',
|
|
80
|
-
overflow: 'hidden',
|
|
81
|
-
whiteSpace: 'nowrap',
|
|
82
|
-
animation: '$loading 5s steps(80)',
|
|
83
|
-
maxWidth: '100%',
|
|
84
|
-
color: function color(props) {
|
|
85
|
-
return props.colorTyping;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
'@keyframes typing': {
|
|
90
|
-
from: {
|
|
91
|
-
width: 0
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
'@keyframes blinking': {
|
|
95
|
-
'0%': {
|
|
96
|
-
borderColor: 'transparent'
|
|
97
|
-
},
|
|
98
|
-
'50%': {
|
|
99
|
-
borderColor: 'black'
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
'@keyframes loading': {
|
|
103
|
-
'0%': {
|
|
104
|
-
maxWidth: 0
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
blink: {
|
|
108
|
-
margin: 0,
|
|
109
|
-
padding: 0,
|
|
110
|
-
borderRight: '.1em solid',
|
|
111
|
-
animation: '$blinking 0.8s linear infinite'
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
TextTyping.propTypes = {
|
|
115
|
-
/** Text to be demonstrated in the component */
|
|
116
|
-
text: _propTypes.default.string.isRequired,
|
|
117
|
-
|
|
118
|
-
/** Component to be used internally in the component */
|
|
119
|
-
component: _propTypes.default.elementType,
|
|
120
|
-
|
|
121
|
-
/** Text color */
|
|
122
|
-
colorText: _propTypes.default.string,
|
|
123
|
-
|
|
124
|
-
/** Background fill color */
|
|
125
|
-
colorTyping: _propTypes.default.string,
|
|
126
|
-
|
|
127
|
-
/** Show flashing text icon */
|
|
128
|
-
showBlink: _propTypes.default.bool,
|
|
129
|
-
|
|
130
|
-
/** Text speed appearing */
|
|
131
|
-
speed: _propTypes.default.number
|
|
132
|
-
};
|
|
133
|
-
TextTyping.defaultProps = {
|
|
134
|
-
component: 'h1',
|
|
135
|
-
showBlink: true,
|
|
136
|
-
colorText: '#FFF',
|
|
137
|
-
colorTyping: '#0075D7',
|
|
138
|
-
speed: 500
|
|
139
|
-
};
|
|
140
|
-
var _default = TextTyping;
|
|
141
|
-
exports.default = _default;
|
package/dist/TextTyping.test.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
6
|
-
|
|
7
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
8
|
-
|
|
9
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
-
|
|
11
|
-
var _react = _interopRequireDefault(require("react"));
|
|
12
|
-
|
|
13
|
-
var _react2 = require("@testing-library/react");
|
|
14
|
-
|
|
15
|
-
var _TextTyping = _interopRequireDefault(require("./TextTyping"));
|
|
16
|
-
|
|
17
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
18
|
-
|
|
19
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
-
|
|
21
|
-
describe('TextTyping Component', function () {
|
|
22
|
-
it('should render component', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
23
|
-
var text;
|
|
24
|
-
return _regenerator.default.wrap(function _callee$(_context) {
|
|
25
|
-
while (1) {
|
|
26
|
-
switch (_context.prev = _context.next) {
|
|
27
|
-
case 0:
|
|
28
|
-
text = 'rice';
|
|
29
|
-
createComponent({
|
|
30
|
-
text: text
|
|
31
|
-
});
|
|
32
|
-
_context.next = 4;
|
|
33
|
-
return (0, _react2.waitFor)(function () {
|
|
34
|
-
return _react2.screen.getByText(text);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
case 4:
|
|
38
|
-
expect(_react2.screen.getByText(text)).toBeDefined();
|
|
39
|
-
|
|
40
|
-
case 5:
|
|
41
|
-
case "end":
|
|
42
|
-
return _context.stop();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}, _callee);
|
|
46
|
-
})));
|
|
47
|
-
it('should render component with not show blink', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
48
|
-
var text;
|
|
49
|
-
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
50
|
-
while (1) {
|
|
51
|
-
switch (_context2.prev = _context2.next) {
|
|
52
|
-
case 0:
|
|
53
|
-
text = 'rice';
|
|
54
|
-
createComponent({
|
|
55
|
-
showBlink: false,
|
|
56
|
-
text: text
|
|
57
|
-
});
|
|
58
|
-
_context2.next = 4;
|
|
59
|
-
return (0, _react2.waitFor)(function () {
|
|
60
|
-
return _react2.screen.getByText(text);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
case 4:
|
|
64
|
-
expect(_react2.screen.getByText(text)).toBeDefined();
|
|
65
|
-
|
|
66
|
-
case 5:
|
|
67
|
-
case "end":
|
|
68
|
-
return _context2.stop();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}, _callee2);
|
|
72
|
-
})));
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
function createComponent() {
|
|
76
|
-
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
77
|
-
|
|
78
|
-
var defaultProps = _objectSpread({
|
|
79
|
-
text: 'Example',
|
|
80
|
-
showBlink: true,
|
|
81
|
-
colorText: '#FFF',
|
|
82
|
-
colorTyping: '#0075D7',
|
|
83
|
-
speed: 1
|
|
84
|
-
}, props);
|
|
85
|
-
|
|
86
|
-
return (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_TextTyping.default, defaultProps));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
;
|