Prepare the Example App as a Public Example Page
So far you've been using the example application soley for your own internal testing.
But with a bit of effort, you can turn it into an interactive example page!
Add Bootstrap to the Example App#
You'll use Bootstrap to style the example app. The create-react-app documentation recommends the following steps for adding Bootstrap to a create-react-app
. First, install bootstrap:
xxxxxxxxxx
npm install --save bootstrap
Then, in src/index.ts
, you can import
the bootstrap CSS file:
xxxxxxxxxx
import "bootstrap/dist/css/bootstrap.css";
Add a Container to the Example App#
Get started by creating markup for the example page in App.tsx
. The idea is using Bootstrap's container
class to wrap around the entire app, making the page responsive and nicer to look at all around:
xxxxxxxxxx
<div className="container">// ...</div>
Add Header Markup#
You can start adding some information about usePleaseStay
itself within the container div:
xxxxxxxxxx
<h1><pre>react-use-please-stay</pre></h1>
<h2>
A React hook that animates the document title and/or favicon when focus from the page is lost.
</h2>
Add State Variables for all usePleaseStay
parameters#
For each parameter than can be passed to usePleaseStay
, you should make a trackable state value for it, and then build a proper UI element for each. Start with the state variables, picking sensible defaults later on:
xxxxxxxxxx
const [titles, setTitles] = useState<ArrayOfOneOrMore<string>>([
"Newline!",
"TypeScript!",
]);
const [intervalTime, setIntervalTime] = useState<number>(1000);
const [animationType, setAnimationType] = useState<AnimationType>(
AnimationType.LOOP
);
const [faviconLinks, setfaviconLinks] = useState<Array<string>>([
"https://d8dgeb1f3fxgw.cloudfront.net/static/img/icons/apple-touch-icon.png",
"https://www.typescriptlang.org/favicon-32x32.png",
]);
const [shouldAlwaysPlay, setShouldAlwaysPlay] = useState<boolean>(true);
and below these state variables, you can call usePleaseStay:
xxxxxxxxxx
usePleaseStay({
titles,
interval,
animationType,
faviconLinks,
shouldAlwaysPlay,
});
Build an Interactive Form for Each Hook Field#
For the titles, you can use a textarea and prompt to the user that they can comma separate each title. Due to the custom type ArrayOfOneOrMore
, you need to use a bit of custom syntax by using the first title and then spreading the rest of the titles:
xxxxxxxxxx
<div className="form-group">
<label htmlFor="titles">
<pre>title</pre>
</label>
<br />
<small className="form-text text-muted">
You can comma separate multiple titles
</small>
<textarea
id="titles"
className="form-control"
value={titles}
onChange={(event) => {
const titles = event.target.value.split(",");
setTitles(
titles.length > 0
? [titles[0], titles.slice(1, titles.length)]
: [""]
);
}}
></textarea>
</div>
For the interval, also add an input of type number
:
xxxxxxxxxx
<div className="form-group">
<label htmlFor="interval">
<pre>interval</pre>
</label>
<input
type="number"
className="form-control"
id="interval"
placeholder="Enter interval"
value={interval}
onChange={(e) => setInterval(parseInt(e.target.value))}
/>
</div>
For the animationType
, use a radio button group, since only one type of animationType
can be selected at a time:
xxxxxxxxxx
<div className="form-group">
<label htmlFor="animationType">
<pre>animationType</pre>
</label>
<div className="form-check">
<input
className="form-check-input"
type="radio"
name="animationType"
id="animationType1"
value={AnimationType.LOOP}
checked={animationType === AnimationType.LOOP}
onChange={(e) => setAnimationType(e.target.value as AnimationType)}
/>
<label className="form-check-label" htmlFor="animationType1">
AnimationType.LOOP
</label>
</div>
<div className="form-check">
<input
className="form-check-input"
type="radio"
name="animationType"
id="animationType2"
value={AnimationType.CASCADE}
checked={animationType === AnimationType.CASCADE}
onChange={(e) => setAnimationType(e.target.value as AnimationType)}
/>
<label className="form-check-label" htmlFor="animationType2">
AnimationType.CASCADE
</label>
</div>
<div className="form-check">
<input
className="form-check-input"
type="radio"
name="animationType"
id="animationType2"
value={AnimationType.MARQUEE}
checked={animationType === AnimationType.MARQUEE}
onChange={(e) => setAnimationType(e.target.value as AnimationType)}
/>
<label className="form-check-label" htmlFor="animationType2">
AnimationType.MARQUEE
</label>
</div>
</div>
This lesson preview is part of the Master Custom React Hooks with TypeScript course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Master Custom React Hooks with TypeScript, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
