not-a-spinner 0.1.1 → 0.2.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/dist/index.cjs +38 -16
- package/dist/index.mjs +38 -16
- package/dist/styles.css +0 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -316,10 +316,15 @@ function useTextRotation({
|
|
|
316
316
|
if (!initializedRef.current) {
|
|
317
317
|
poolRef.current = shufflePhrases(inputPhrases);
|
|
318
318
|
initializedRef.current = true;
|
|
319
|
-
|
|
319
|
+
setCycleId((c) => c + 1);
|
|
320
320
|
}
|
|
321
321
|
}, []);
|
|
322
|
+
const inputChangedRef = (0, import_react.useRef)(false);
|
|
322
323
|
(0, import_react.useEffect)(() => {
|
|
324
|
+
if (!inputChangedRef.current) {
|
|
325
|
+
inputChangedRef.current = true;
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
323
328
|
poolRef.current = shufflePhrases(inputPhrases);
|
|
324
329
|
setCurrentIndex(0);
|
|
325
330
|
}, [inputPhrases]);
|
|
@@ -470,16 +475,16 @@ var NotASpinner = React.forwardRef(
|
|
|
470
475
|
}
|
|
471
476
|
);
|
|
472
477
|
}
|
|
473
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
478
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
474
479
|
"div",
|
|
475
480
|
{
|
|
476
481
|
ref,
|
|
477
482
|
className: cn(notASpinnerVariants({ size, animation }), className),
|
|
478
483
|
...props,
|
|
479
|
-
children: [
|
|
480
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
484
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: getAnimationClass(), children: [
|
|
485
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: currentPhrase }),
|
|
481
486
|
dots && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "nas-dots", children: "..." })
|
|
482
|
-
]
|
|
487
|
+
] })
|
|
483
488
|
}
|
|
484
489
|
);
|
|
485
490
|
}
|
|
@@ -487,49 +492,66 @@ var NotASpinner = React.forwardRef(
|
|
|
487
492
|
NotASpinner.displayName = "NotASpinner";
|
|
488
493
|
var TypewriterRenderer = React.forwardRef(({ className, currentPhrase, cycleId, interval, dots, onEraseComplete, ...props }, ref) => {
|
|
489
494
|
const [displayedChars, setDisplayedChars] = React.useState(0);
|
|
495
|
+
const [displayedDots, setDisplayedDots] = React.useState(0);
|
|
490
496
|
const [phase, setPhase] = React.useState(
|
|
491
497
|
"typing"
|
|
492
498
|
);
|
|
493
499
|
const phraseRef = React.useRef(currentPhrase);
|
|
500
|
+
const eraseCalledRef = React.useRef(false);
|
|
494
501
|
React.useEffect(() => {
|
|
495
502
|
phraseRef.current = currentPhrase;
|
|
496
503
|
setDisplayedChars(0);
|
|
504
|
+
setDisplayedDots(0);
|
|
497
505
|
setPhase("typing");
|
|
506
|
+
eraseCalledRef.current = false;
|
|
498
507
|
}, [cycleId]);
|
|
499
508
|
React.useEffect(() => {
|
|
500
509
|
const totalChars = phraseRef.current.length;
|
|
501
510
|
if (totalChars === 0) return;
|
|
502
511
|
const typingSpeed = 50;
|
|
503
512
|
const erasingSpeed = 30;
|
|
513
|
+
const dotsTypingDuration = 3 * typingSpeed;
|
|
514
|
+
const dotsDismissDuration = 3 * erasingSpeed;
|
|
504
515
|
const typingDuration = totalChars * typingSpeed;
|
|
505
516
|
const erasingDuration = totalChars * erasingSpeed;
|
|
506
|
-
const holdDuration = Math.max(interval - typingDuration - erasingDuration, 500);
|
|
517
|
+
const holdDuration = Math.max(interval - typingDuration - dotsTypingDuration - dotsDismissDuration - erasingDuration, 500);
|
|
507
518
|
let timer;
|
|
508
519
|
if (phase === "typing") {
|
|
509
520
|
if (displayedChars < totalChars) {
|
|
510
521
|
timer = setTimeout(() => setDisplayedChars((c) => c + 1), typingSpeed);
|
|
522
|
+
} else {
|
|
523
|
+
timer = setTimeout(() => setPhase("typing-dots"), 0);
|
|
524
|
+
}
|
|
525
|
+
} else if (phase === "typing-dots") {
|
|
526
|
+
if (displayedDots < 3) {
|
|
527
|
+
timer = setTimeout(() => setDisplayedDots((d) => d + 1), typingSpeed);
|
|
511
528
|
} else {
|
|
512
529
|
timer = setTimeout(() => setPhase("holding"), 0);
|
|
513
530
|
}
|
|
514
531
|
} else if (phase === "holding") {
|
|
515
|
-
timer = setTimeout(() => setPhase("erasing"), holdDuration);
|
|
532
|
+
timer = setTimeout(() => setPhase("erasing-dots"), holdDuration);
|
|
533
|
+
} else if (phase === "erasing-dots") {
|
|
534
|
+
if (displayedDots > 0) {
|
|
535
|
+
timer = setTimeout(() => setDisplayedDots((d) => d - 1), erasingSpeed);
|
|
536
|
+
} else {
|
|
537
|
+
timer = setTimeout(() => setPhase("erasing"), 0);
|
|
538
|
+
}
|
|
516
539
|
} else if (phase === "erasing") {
|
|
517
540
|
if (displayedChars > 0) {
|
|
518
541
|
timer = setTimeout(() => setDisplayedChars((c) => c - 1), erasingSpeed);
|
|
519
|
-
} else {
|
|
542
|
+
} else if (!eraseCalledRef.current) {
|
|
543
|
+
eraseCalledRef.current = true;
|
|
520
544
|
onEraseComplete();
|
|
521
545
|
}
|
|
522
546
|
}
|
|
523
547
|
return () => clearTimeout(timer);
|
|
524
|
-
}, [phase, displayedChars, interval, onEraseComplete]);
|
|
548
|
+
}, [phase, displayedChars, displayedDots, interval, onEraseComplete]);
|
|
525
549
|
const displayedText = phraseRef.current.slice(0, displayedChars);
|
|
526
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
dots && displayedChars > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "nas-dots", children: "..." })
|
|
532
|
-
] });
|
|
550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "nas-text-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
551
|
+
displayedText,
|
|
552
|
+
dots && displayedChars > 0 && displayedDots > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "nas-dots", children: "...".slice(0, displayedDots) }),
|
|
553
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "nas-cursor" })
|
|
554
|
+
] }) }) });
|
|
533
555
|
});
|
|
534
556
|
TypewriterRenderer.displayName = "TypewriterRenderer";
|
|
535
557
|
|
package/dist/index.mjs
CHANGED
|
@@ -272,10 +272,15 @@ function useTextRotation({
|
|
|
272
272
|
if (!initializedRef.current) {
|
|
273
273
|
poolRef.current = shufflePhrases(inputPhrases);
|
|
274
274
|
initializedRef.current = true;
|
|
275
|
-
|
|
275
|
+
setCycleId((c) => c + 1);
|
|
276
276
|
}
|
|
277
277
|
}, []);
|
|
278
|
+
const inputChangedRef = useRef(false);
|
|
278
279
|
useEffect(() => {
|
|
280
|
+
if (!inputChangedRef.current) {
|
|
281
|
+
inputChangedRef.current = true;
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
279
284
|
poolRef.current = shufflePhrases(inputPhrases);
|
|
280
285
|
setCurrentIndex(0);
|
|
281
286
|
}, [inputPhrases]);
|
|
@@ -426,16 +431,16 @@ var NotASpinner = React.forwardRef(
|
|
|
426
431
|
}
|
|
427
432
|
);
|
|
428
433
|
}
|
|
429
|
-
return /* @__PURE__ */
|
|
434
|
+
return /* @__PURE__ */ jsx(
|
|
430
435
|
"div",
|
|
431
436
|
{
|
|
432
437
|
ref,
|
|
433
438
|
className: cn(notASpinnerVariants({ size, animation }), className),
|
|
434
439
|
...props,
|
|
435
|
-
children: [
|
|
436
|
-
/* @__PURE__ */ jsx("
|
|
440
|
+
children: /* @__PURE__ */ jsxs("span", { className: getAnimationClass(), children: [
|
|
441
|
+
/* @__PURE__ */ jsx("span", { children: currentPhrase }),
|
|
437
442
|
dots && /* @__PURE__ */ jsx("span", { className: "nas-dots", children: "..." })
|
|
438
|
-
]
|
|
443
|
+
] })
|
|
439
444
|
}
|
|
440
445
|
);
|
|
441
446
|
}
|
|
@@ -443,49 +448,66 @@ var NotASpinner = React.forwardRef(
|
|
|
443
448
|
NotASpinner.displayName = "NotASpinner";
|
|
444
449
|
var TypewriterRenderer = React.forwardRef(({ className, currentPhrase, cycleId, interval, dots, onEraseComplete, ...props }, ref) => {
|
|
445
450
|
const [displayedChars, setDisplayedChars] = React.useState(0);
|
|
451
|
+
const [displayedDots, setDisplayedDots] = React.useState(0);
|
|
446
452
|
const [phase, setPhase] = React.useState(
|
|
447
453
|
"typing"
|
|
448
454
|
);
|
|
449
455
|
const phraseRef = React.useRef(currentPhrase);
|
|
456
|
+
const eraseCalledRef = React.useRef(false);
|
|
450
457
|
React.useEffect(() => {
|
|
451
458
|
phraseRef.current = currentPhrase;
|
|
452
459
|
setDisplayedChars(0);
|
|
460
|
+
setDisplayedDots(0);
|
|
453
461
|
setPhase("typing");
|
|
462
|
+
eraseCalledRef.current = false;
|
|
454
463
|
}, [cycleId]);
|
|
455
464
|
React.useEffect(() => {
|
|
456
465
|
const totalChars = phraseRef.current.length;
|
|
457
466
|
if (totalChars === 0) return;
|
|
458
467
|
const typingSpeed = 50;
|
|
459
468
|
const erasingSpeed = 30;
|
|
469
|
+
const dotsTypingDuration = 3 * typingSpeed;
|
|
470
|
+
const dotsDismissDuration = 3 * erasingSpeed;
|
|
460
471
|
const typingDuration = totalChars * typingSpeed;
|
|
461
472
|
const erasingDuration = totalChars * erasingSpeed;
|
|
462
|
-
const holdDuration = Math.max(interval - typingDuration - erasingDuration, 500);
|
|
473
|
+
const holdDuration = Math.max(interval - typingDuration - dotsTypingDuration - dotsDismissDuration - erasingDuration, 500);
|
|
463
474
|
let timer;
|
|
464
475
|
if (phase === "typing") {
|
|
465
476
|
if (displayedChars < totalChars) {
|
|
466
477
|
timer = setTimeout(() => setDisplayedChars((c) => c + 1), typingSpeed);
|
|
478
|
+
} else {
|
|
479
|
+
timer = setTimeout(() => setPhase("typing-dots"), 0);
|
|
480
|
+
}
|
|
481
|
+
} else if (phase === "typing-dots") {
|
|
482
|
+
if (displayedDots < 3) {
|
|
483
|
+
timer = setTimeout(() => setDisplayedDots((d) => d + 1), typingSpeed);
|
|
467
484
|
} else {
|
|
468
485
|
timer = setTimeout(() => setPhase("holding"), 0);
|
|
469
486
|
}
|
|
470
487
|
} else if (phase === "holding") {
|
|
471
|
-
timer = setTimeout(() => setPhase("erasing"), holdDuration);
|
|
488
|
+
timer = setTimeout(() => setPhase("erasing-dots"), holdDuration);
|
|
489
|
+
} else if (phase === "erasing-dots") {
|
|
490
|
+
if (displayedDots > 0) {
|
|
491
|
+
timer = setTimeout(() => setDisplayedDots((d) => d - 1), erasingSpeed);
|
|
492
|
+
} else {
|
|
493
|
+
timer = setTimeout(() => setPhase("erasing"), 0);
|
|
494
|
+
}
|
|
472
495
|
} else if (phase === "erasing") {
|
|
473
496
|
if (displayedChars > 0) {
|
|
474
497
|
timer = setTimeout(() => setDisplayedChars((c) => c - 1), erasingSpeed);
|
|
475
|
-
} else {
|
|
498
|
+
} else if (!eraseCalledRef.current) {
|
|
499
|
+
eraseCalledRef.current = true;
|
|
476
500
|
onEraseComplete();
|
|
477
501
|
}
|
|
478
502
|
}
|
|
479
503
|
return () => clearTimeout(timer);
|
|
480
|
-
}, [phase, displayedChars, interval, onEraseComplete]);
|
|
504
|
+
}, [phase, displayedChars, displayedDots, interval, onEraseComplete]);
|
|
481
505
|
const displayedText = phraseRef.current.slice(0, displayedChars);
|
|
482
|
-
return /* @__PURE__ */
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
dots && displayedChars > 0 && /* @__PURE__ */ jsx("span", { className: "nas-dots", children: "..." })
|
|
488
|
-
] });
|
|
506
|
+
return /* @__PURE__ */ jsx("div", { ref, className, ...props, children: /* @__PURE__ */ jsx("div", { className: "nas-text-wrapper", children: /* @__PURE__ */ jsxs("span", { children: [
|
|
507
|
+
displayedText,
|
|
508
|
+
dots && displayedChars > 0 && displayedDots > 0 && /* @__PURE__ */ jsx("span", { className: "nas-dots", children: "...".slice(0, displayedDots) }),
|
|
509
|
+
/* @__PURE__ */ jsx("span", { className: "nas-cursor" })
|
|
510
|
+
] }) }) });
|
|
489
511
|
});
|
|
490
512
|
TypewriterRenderer.displayName = "TypewriterRenderer";
|
|
491
513
|
|
package/dist/styles.css
CHANGED
package/package.json
CHANGED