# NPM
$ npm install windups --save
import React, { StrictMode } from "react";
import { render } from "react-dom";
import useWindupString from "./react/useWindupString";
import WindupChildren, { useSkip, useRewind } from "./react/WindupChildren";
import Pace from "./react/Pace";
import OnChar from "./react/OnChar";
import Pause from "./react/Pause";
import Effect from "./react/Effect";
import CharWrapper from "./react/CharWrapper";
import Linebreaker from "./react/Linebreaker";
const TestComponent: React.FC = ({ children }) => {
return <b>{children}</b>;
};
const AnotherTestComponent: React.FC = ({ children }) => {
return <em>{children}</em>;
};
const RedChar: React.FC = ({ children }) => {
return <span style={{ color: "red" }}>{children}</span>;
};
const FunctionChildrenComponent = ({
children
}: {
children: (value: string) => React.ReactNode;
}) => {
const value = "blue";
return <>{children(value)}</>;
};
function SkipButton() {
const skip = useSkip();
return <button onClick={skip}>{"Skip"}</button>;
}
function RewindButton() {
const rewind = useRewind();
return <button onClick={rewind}>{"Rewind"}</button>;
}
const Example = () => {
const [string] = useWindupString("This text came from a hook!");
return (
<StrictMode>
<WindupChildren>
<img src="hi.jpg" />
</WindupChildren>
<Linebreaker width={100} fontStyle={"24px Arial"}>
<WindupChildren
onFinished={() => {
console.log("I want to see this only once!");
}}
>
<div
style={{
width: 100,
font: "24px Arial",
border: "1px black solid"
}}
>
{"Hello!"}
<div>
{"Nice to meet you, "}
<em>{"truly!"}</em>
</div>
</div>
</WindupChildren>
</Linebreaker>
<div>{string}</div>
<WindupChildren onFinished={() => console.log("Finished!")}>
<CharWrapper element={RedChar}>
{"hello "}
<FunctionChildrenComponent>
{value => (
<div>{`I have function children with a value of ${value}`}</div>
)}
</FunctionChildrenComponent>
<SkipButton />
<RewindButton />
<Pause ms={2000} />
<Effect fn={() => console.log("Paused for a bit there!")} />
<OnChar fn={char => console.log(char)}>
{"Way"}
<OnChar fn={char => console.log(`✨${char}`)}>{" cool!"}</OnChar>
</OnChar>
{1}
{false}
<Pace ms={20}>
{"I'm in a fragment!💙"}
<Pace ms={200}>
{"Hee hee hee!"}
<Pace ms={1000}>
<em>{"Hm..."}</em>
</Pace>
</Pace>
</Pace>
<div>{"I'm in a div!"}</div>
<TestComponent>{"I'm in a function component!"}</TestComponent>
<TestComponent>
{"I'm in a "}
<AnotherTestComponent>
<s>{"very "}</s>
{"nested "}
</AnotherTestComponent>
{"test component!!!"}
</TestComponent>
</CharWrapper>
</WindupChildren>
</StrictMode>
);
};
A typewriter effect library for React.
Apply the typewriter (or, ahem, “windup”) effect to:
Use the API to:
Examples, API docs, and guides can all be found at the docs site!
Where the action is happening in this codebase.
src/Windup.ts
The bulk of the file are functions which return modified versions of a windup (e.g. next
, rewind
), utilities (e.g. isUnplayed
), or functions for creating a Windup data structure (e.g. windupFromString
).
The windup data structure is also described here:
src/react/useWindup.ts
This is a hook that is used internally by WindupChildren
and useWindupString
. It does the bulk of the work of a windup: scheduling the next update, triggering effects, returning callbacks for rewinding/skipping etc.
src/react/useWindupString.ts
This hook does very little: it just turns a string into a windup and passes it along to useWindup
.
src/react/WindupChildren.tsx
A lot going on in this one: transforming the children
data type into a Windup, and a rough heuristic to determine when the value of children
has ‘changed’ (big quotation marks).
Author: sgwilym
Live Demo: https://windups.gwil.co/
GitHub: https://github.com/sgwilym/windups
#reactjs #react #javascript #react-js