Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make spinner a component #182

Merged
merged 2 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions demo/components_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,19 @@ class Delivery(BaseModel):
],
class_name='border-top mt-3 pt-1',
),
c.Div(
components=[
c.Heading(text='Spinner', level=2),
c.Paragraph(
text=(
'A component displayed while waiting for content to load, '
'this is also used automatically while loading server content.'
)
),
c.Spinner(text='Content incoming...'),
],
class_name='border-top mt-3 pt-1',
),
c.Div(
components=[
c.Heading(text='Video', level=2),
Expand Down
8 changes: 8 additions & 0 deletions src/npm-fastui-bootstrap/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,13 @@ export const classNameGenerator: ClassNameGenerator = ({
} else {
return 'error-alert alert alert-danger m-3'
}
case 'Spinner':
if (subElement === 'text') {
return 'd-flex justify-content-center mb-2'
} else if (subElement === 'animation') {
return 'd-flex justify-content-center'
} else {
return 'my-4'
}
}
}
7 changes: 0 additions & 7 deletions src/npm-fastui-prebuilt/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export default function App() {
classNameGenerator={bootstrap.classNameGenerator}
customRender={customRender}
NotFound={NotFound}
Spinner={Spinner}
Transition={Transition}
/>
)
Expand All @@ -30,12 +29,6 @@ const NotFound = ({ url }: { url: string }) => (
</div>
)

const Spinner = () => (
<div className="container d-flex justify-content-center my-3" role="status">
<div className="spinner" />
</div>
)

const Transition: FC<{ children: ReactNode; transitioning: boolean }> = ({ children, transitioning }) => (
<>
<div className={renderClassName({ 'transition-overlay': true, transitioning })} />
Expand Down
15 changes: 7 additions & 8 deletions src/npm-fastui-prebuilt/src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ h6 {
}

// custom spinner from https://cssloaders.github.io/

.spinner,
.spinner:before,
.spinner:after {
.fastui-spinner-animation,
.fastui-spinner-animation:before,
.fastui-spinner-animation:after {
border-radius: 50%;
width: 2.5em;
height: 2.5em;
animation-fill-mode: both;
animation: dots 1.8s infinite ease-in-out;
animation: spinner-dots 1.8s infinite ease-in-out;
}
.spinner {
.fastui-spinner-animation {
top: -2.5em;
color: var(--bs-dark);
font-size: 7px;
position: relative;
Expand All @@ -105,8 +105,7 @@ h6 {
left: 3.5em;
}
}

@keyframes dots {
@keyframes spinner-dots {
0%,
80%,
100% {
Expand Down
2 changes: 0 additions & 2 deletions src/npm-fastui/src/Defaults.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { FC, ReactNode } from 'react'

export const DefaultSpinner: FC = () => <div>loading...</div>

export const DefaultNotFound: FC<{ url: string }> = ({ url }) => <div>Page not found: {url}</div>

// default here does nothing
Expand Down
9 changes: 5 additions & 4 deletions src/npm-fastui/src/components/ServerLoad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import type { ServerLoad, PageEvent, FastProps } from '../models'

import { ErrorContext } from '../hooks/error'
import { useRequest, useSSE } from '../tools'
import { DefaultSpinner, DefaultNotFound, DefaultTransition } from '../Defaults'
import { DefaultNotFound, DefaultTransition } from '../Defaults'
import { ConfigContext } from '../hooks/config'
import { usePageEventListen } from '../events'
import { EventContextProvider, useEventContext } from '../hooks/eventContext'
import { LocationContext } from '../hooks/locationContext'

import { AnyCompList } from './index'

import { SpinnerComp } from './spinner'

export const ServerLoadComp: FC<ServerLoad> = ({ path, components, loadTrigger, sse }) => {
if (components) {
return <ServerLoadDefer path={path} components={components} loadTrigger={loadTrigger} sse={sse} />
Expand Down Expand Up @@ -103,8 +105,7 @@ const Render: FC<{ propsList: FastProps[] | null; notFoundUrl?: string; transiti
transitioning,
}) => {
const { error } = useContext(ErrorContext)
const { Spinner, NotFound, Transition } = useContext(ConfigContext)
const SpinnerComp = Spinner ?? DefaultSpinner
const { NotFound, Transition } = useContext(ConfigContext)
const NotFoundComp = NotFound ?? DefaultNotFound
const TransitionComp = Transition ?? DefaultTransition

Expand All @@ -114,7 +115,7 @@ const Render: FC<{ propsList: FastProps[] | null; notFoundUrl?: string; transiti
if (error) {
return <></>
} else {
return <SpinnerComp />
return <SpinnerComp type="Spinner" />
}
} else {
return (
Expand Down
4 changes: 4 additions & 0 deletions src/npm-fastui/src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { IframeComp } from './Iframe'
import { VideoComp } from './video'
import { FireEventComp } from './FireEvent'
import { ErrorComp } from './error'
import { SpinnerComp } from './spinner'
import { CustomComp } from './Custom'

// TODO some better way to export components
Expand Down Expand Up @@ -73,6 +74,7 @@ export {
VideoComp,
FireEventComp,
ErrorComp,
SpinnerComp,
CustomComp,
LinkRender,
}
Expand Down Expand Up @@ -160,6 +162,8 @@ export const AnyComp: FC<FastProps> = (props) => {
return <FireEventComp {...props} />
case 'Error':
return <ErrorComp {...props} />
case 'Spinner':
return <SpinnerComp {...props} />
case 'Custom':
return <CustomComp {...props} />
default:
Expand Down
18 changes: 18 additions & 0 deletions src/npm-fastui/src/components/spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FC } from 'react'

import type { Spinner } from '../models'

import { useClassName } from '../hooks/className'

export const SpinnerComp: FC<Spinner> = (props) => {
const { text } = props

return (
<div className={useClassName(props)}>
<div className={useClassName(props, { el: 'text' })}>{text}</div>
<div className={useClassName(props, { el: 'animation' })}>
<div className="fastui-spinner-animation">loading...</div>
</div>
</div>
)
}
1 change: 0 additions & 1 deletion src/npm-fastui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export interface FastUIProps {
APIPathMode?: 'append' | 'query'
// start of the path to remove from the URL before making a request to the API
APIPathStrip?: string
Spinner?: FC
NotFound?: FC<{ url: string }>
Transition?: FC<{ children: ReactNode; transitioning: boolean }>
classNameGenerator?: ClassNameGenerator
Expand Down
6 changes: 6 additions & 0 deletions src/npm-fastui/src/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type FastProps =
| Video
| FireEvent
| Error
| Spinner
| Custom
| Table
| Pagination
Expand Down Expand Up @@ -256,6 +257,11 @@ export interface Error {
type: 'Error'
children?: ReactNode
}
export interface Spinner {
text?: string
className?: ClassName
type: 'Spinner'
}
export interface Custom {
data: JsonData
subType: string
Expand Down
11 changes: 10 additions & 1 deletion src/python-fastui/fastui/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from .tables import Pagination, Table

__all__ = (
# first we include everything from `AnyComponent`
# first we include all components from this file
'Text',
'Paragraph',
'PageTitle',
Expand All @@ -48,7 +48,9 @@
'Iframe',
'FireEvent',
'Error',
'Spinner',
'Custom',
# then we include components from other files
'Table',
'Pagination',
'Display',
Expand Down Expand Up @@ -291,6 +293,12 @@ def __get_pydantic_json_schema__(
return json_schema


class Spinner(_p.BaseModel, extra='forbid'):
text: _t.Union[str, None] = None
class_name: _class_name.ClassNameField = None
type: _t.Literal['Spinner'] = 'Spinner'


class Custom(_p.BaseModel, extra='forbid'):
data: _types.JsonData
sub_type: str = _p.Field(serialization_alias='subType')
Expand Down Expand Up @@ -322,6 +330,7 @@ class Custom(_p.BaseModel, extra='forbid'):
Video,
FireEvent,
Error,
Spinner,
Custom,
Table,
Pagination,
Expand Down
Loading