Skip to content

Commit f26041e

Browse files
authored
make spinner a component (#182)
1 parent 10a0a66 commit f26041e

File tree

11 files changed

+71
-23
lines changed

11 files changed

+71
-23
lines changed

demo/components_list.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,19 @@ class Delivery(BaseModel):
192192
],
193193
class_name='border-top mt-3 pt-1',
194194
),
195+
c.Div(
196+
components=[
197+
c.Heading(text='Spinner', level=2),
198+
c.Paragraph(
199+
text=(
200+
'A component displayed while waiting for content to load, '
201+
'this is also used automatically while loading server content.'
202+
)
203+
),
204+
c.Spinner(text='Content incoming...'),
205+
],
206+
class_name='border-top mt-3 pt-1',
207+
),
195208
c.Div(
196209
components=[
197210
c.Heading(text='Video', level=2),

src/npm-fastui-bootstrap/src/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,13 @@ export const classNameGenerator: ClassNameGenerator = ({
150150
} else {
151151
return 'error-alert alert alert-danger m-3'
152152
}
153+
case 'Spinner':
154+
if (subElement === 'text') {
155+
return 'd-flex justify-content-center mb-2'
156+
} else if (subElement === 'animation') {
157+
return 'd-flex justify-content-center'
158+
} else {
159+
return 'my-4'
160+
}
153161
}
154162
}

src/npm-fastui-prebuilt/src/App.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export default function App() {
1111
classNameGenerator={bootstrap.classNameGenerator}
1212
customRender={customRender}
1313
NotFound={NotFound}
14-
Spinner={Spinner}
1514
Transition={Transition}
1615
/>
1716
)
@@ -30,12 +29,6 @@ const NotFound = ({ url }: { url: string }) => (
3029
</div>
3130
)
3231

33-
const Spinner = () => (
34-
<div className="container d-flex justify-content-center my-3" role="status">
35-
<div className="spinner" />
36-
</div>
37-
)
38-
3932
const Transition: FC<{ children: ReactNode; transitioning: boolean }> = ({ children, transitioning }) => (
4033
<>
4134
<div className={renderClassName({ 'transition-overlay': true, transitioning })} />

src/npm-fastui-prebuilt/src/main.scss

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ h6 {
7474
}
7575

7676
// custom spinner from https://cssloaders.github.io/
77-
78-
.spinner,
79-
.spinner:before,
80-
.spinner:after {
77+
.fastui-spinner-animation,
78+
.fastui-spinner-animation:before,
79+
.fastui-spinner-animation:after {
8180
border-radius: 50%;
8281
width: 2.5em;
8382
height: 2.5em;
8483
animation-fill-mode: both;
85-
animation: dots 1.8s infinite ease-in-out;
84+
animation: spinner-dots 1.8s infinite ease-in-out;
8685
}
87-
.spinner {
86+
.fastui-spinner-animation {
87+
top: -2.5em;
8888
color: var(--bs-dark);
8989
font-size: 7px;
9090
position: relative;
@@ -105,8 +105,7 @@ h6 {
105105
left: 3.5em;
106106
}
107107
}
108-
109-
@keyframes dots {
108+
@keyframes spinner-dots {
110109
0%,
111110
80%,
112111
100% {

src/npm-fastui/src/Defaults.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { FC, ReactNode } from 'react'
22

3-
export const DefaultSpinner: FC = () => <div>loading...</div>
4-
53
export const DefaultNotFound: FC<{ url: string }> = ({ url }) => <div>Page not found: {url}</div>
64

75
// default here does nothing

src/npm-fastui/src/components/ServerLoad.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import type { ServerLoad, PageEvent, FastProps } from '../models'
44

55
import { ErrorContext } from '../hooks/error'
66
import { useRequest, useSSE } from '../tools'
7-
import { DefaultSpinner, DefaultNotFound, DefaultTransition } from '../Defaults'
7+
import { DefaultNotFound, DefaultTransition } from '../Defaults'
88
import { ConfigContext } from '../hooks/config'
99
import { usePageEventListen } from '../events'
1010
import { EventContextProvider, useEventContext } from '../hooks/eventContext'
1111
import { LocationContext } from '../hooks/locationContext'
1212

1313
import { AnyCompList } from './index'
1414

15+
import { SpinnerComp } from './spinner'
16+
1517
export const ServerLoadComp: FC<ServerLoad> = ({ path, components, loadTrigger, sse }) => {
1618
if (components) {
1719
return <ServerLoadDefer path={path} components={components} loadTrigger={loadTrigger} sse={sse} />
@@ -103,8 +105,7 @@ const Render: FC<{ propsList: FastProps[] | null; notFoundUrl?: string; transiti
103105
transitioning,
104106
}) => {
105107
const { error } = useContext(ErrorContext)
106-
const { Spinner, NotFound, Transition } = useContext(ConfigContext)
107-
const SpinnerComp = Spinner ?? DefaultSpinner
108+
const { NotFound, Transition } = useContext(ConfigContext)
108109
const NotFoundComp = NotFound ?? DefaultNotFound
109110
const TransitionComp = Transition ?? DefaultTransition
110111

@@ -114,7 +115,7 @@ const Render: FC<{ propsList: FastProps[] | null; notFoundUrl?: string; transiti
114115
if (error) {
115116
return <></>
116117
} else {
117-
return <SpinnerComp />
118+
return <SpinnerComp type="Spinner" />
118119
}
119120
} else {
120121
return (

src/npm-fastui/src/components/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { IframeComp } from './Iframe'
3939
import { VideoComp } from './video'
4040
import { FireEventComp } from './FireEvent'
4141
import { ErrorComp } from './error'
42+
import { SpinnerComp } from './spinner'
4243
import { CustomComp } from './Custom'
4344

4445
// TODO some better way to export components
@@ -73,6 +74,7 @@ export {
7374
VideoComp,
7475
FireEventComp,
7576
ErrorComp,
77+
SpinnerComp,
7678
CustomComp,
7779
LinkRender,
7880
}
@@ -160,6 +162,8 @@ export const AnyComp: FC<FastProps> = (props) => {
160162
return <FireEventComp {...props} />
161163
case 'Error':
162164
return <ErrorComp {...props} />
165+
case 'Spinner':
166+
return <SpinnerComp {...props} />
163167
case 'Custom':
164168
return <CustomComp {...props} />
165169
default:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { FC } from 'react'
2+
3+
import type { Spinner } from '../models'
4+
5+
import { useClassName } from '../hooks/className'
6+
7+
export const SpinnerComp: FC<Spinner> = (props) => {
8+
const { text } = props
9+
10+
return (
11+
<div className={useClassName(props)}>
12+
<div className={useClassName(props, { el: 'text' })}>{text}</div>
13+
<div className={useClassName(props, { el: 'animation' })}>
14+
<div className="fastui-spinner-animation">loading...</div>
15+
</div>
16+
</div>
17+
)
18+
}

src/npm-fastui/src/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export interface FastUIProps {
2424
APIPathMode?: 'append' | 'query'
2525
// start of the path to remove from the URL before making a request to the API
2626
APIPathStrip?: string
27-
Spinner?: FC
2827
NotFound?: FC<{ url: string }>
2928
Transition?: FC<{ children: ReactNode; transitioning: boolean }>
3029
classNameGenerator?: ClassNameGenerator

src/npm-fastui/src/models.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export type FastProps =
2626
| Video
2727
| FireEvent
2828
| Error
29+
| Spinner
2930
| Custom
3031
| Table
3132
| Pagination
@@ -256,6 +257,11 @@ export interface Error {
256257
type: 'Error'
257258
children?: ReactNode
258259
}
260+
export interface Spinner {
261+
text?: string
262+
className?: ClassName
263+
type: 'Spinner'
264+
}
259265
export interface Custom {
260266
data: JsonData
261267
subType: string

0 commit comments

Comments
 (0)