Skip to content

Commit eebe613

Browse files
committed
Add a loading prop to RenderConfig
1 parent 53b5f26 commit eebe613

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

src/components/common/indicators/loading-indicator.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
export default function LoadingIndicator(props: { className?: string }) {
2-
const letters = ['L', 'o', 'a', 'd', 'i', 'n', 'g', '\u00A0', '.', '.', '.'];
1+
export default function LoadingIndicator(props: { message?: string, className?: string }) {
2+
const chars = Array.from(props.message ?? 'Loading ...');
33

44
return (
55
<span className={`${props.className} inline-flex`}>
66
{
7-
letters.map((char, index) =>
7+
chars.map((char, i) =>
88
<span
9-
key={index}
9+
key={i}
1010
className='italic animate-(--animate-glow)'
11-
style={{animationDelay: `${index * 0.1}s`}}
11+
style={{animationDelay: `${i * 0.1}s`}}
1212
>
13-
{char}
13+
{char === ' ' ? '\u00A0' : char}
1414
</span>
1515
)
1616
}

src/components/content/home-page/stats/stat-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default function StatCard<T>(props: {
2525
<props.dataState.Render
2626
value={props.value}
2727
errorFallback={<ErrorWithRefetch refetch={props.dataState.fetch} />}
28-
loadingFallback={<LoadingIndicator />}
28+
loading='Loading ...'
2929
/>
3030
</div>
3131
</div>

src/lib/data-state.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Dispatch, ReactNode, SetStateAction, useCallback, useEffect, useMemo, useRef, useState } from 'react';
22
import ErrorIndicator from '@/components/common/indicators/error-indicator';
33
import LoadingPulse from '@/components/common/indicators/loading-pulse';
4+
import LoadingIndicator from '@/components/common/indicators/loading-indicator';
45

56

67
type ValueRoot<T> = {
@@ -54,9 +55,12 @@ interface DataStateMethods<T> {
5455
// either the `ValueState`'s value, or the `ErrorState`'s error.
5556
interface RenderConfig {
5657
// Optional callback function for rendering a subfield of the `ValueState`'s value IFF that value is present:
58+
// (Can optionally use the className provided to the render function, see below)
5759
value?: (className?: string) => ReactNode;
58-
// Optional short error to display instead of full error:
60+
// Optional error message to display instead of 'Error':
5961
error?: string;
62+
// Optional message to display while loading:
63+
loading?: string;
6064
// Optionally don't display fallback components like Loading- or ErrorIndicators:
6165
showFallback?: boolean;
6266
// Optionally display another component instead of the default LoadingIndicator:
@@ -162,7 +166,7 @@ export const DataState = {
162166
const useInit = () => useEffect(() => { fetch() }, [fetch]);
163167

164168
const Render = (conf: RenderConfig = {}): ReactNode => {
165-
const { value, error, showFallback = true, loadingFallback, errorFallback, className } = conf;
169+
const { value, error, loading, showFallback = true, loadingFallback, errorFallback, className } = conf;
166170

167171
if (dataRoot.value) {
168172
return value ?
@@ -172,13 +176,13 @@ export const DataState = {
172176
}
173177
else if (dataRoot.error) {
174178
if (showFallback) {
175-
return errorFallback ?
176-
errorFallback : <ErrorIndicator error={error} className={className} />;
179+
return errorFallback ?? <ErrorIndicator error={error} className={className} />;
177180
}
178181
}
179182
else if (showFallback) {
180-
return loadingFallback ?
181-
loadingFallback : <LoadingPulse className={className} />;
183+
if (loadingFallback) return loadingFallback;
184+
if (loading) return <LoadingIndicator message={loading} className={className} />;
185+
return <LoadingPulse className={className} />;
182186
}
183187
}
184188

0 commit comments

Comments
 (0)