Skip to content

Commit

Permalink
Add basic toast
Browse files Browse the repository at this point in the history
  • Loading branch information
Chaoyingz committed Dec 19, 2023
1 parent 6b7c7cb commit feb74b1
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 0 deletions.
13 changes: 13 additions & 0 deletions demo/components_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ class Delivery(BaseModel):
],
class_name='border-top mt-3 pt-1',
),
c.Div(
components=[
c.Heading(text='Button and Toast', level=2),
c.Paragraph(text='The button below will open a toast.'),
c.Button(text='Show Toast', on_click=PageEvent(name='show-toast')),
c.Toast(
title='Toast',
body=[c.Paragraph(text='This is some static content that was set when the modal was defined.')],
open_trigger=PageEvent(name='show-toast'),
),
],
class_name='border-top mt-3 pt-1',
),
title='Components',
)

Expand Down
1 change: 1 addition & 0 deletions demo/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def api_index() -> list[AnyComponent]:
* `Table` — See [cities table](/table/cities) and [users table](/table/users)
* `Pagination` — See the bottom of the [cities table](/table/cities)
* `ModelForm` — See [forms](/forms/login)
* `Toast` - example [here](/components#toast)
"""
return demo_page(c.Markdown(text=markdown))

Expand Down
3 changes: 3 additions & 0 deletions src/npm-fastui-bootstrap/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ClassNameGenerator, CustomRender, ClassName } from 'fastui'
import { Modal } from './modal'
import { Navbar } from './navbar'
import { Pagination } from './pagination'
import { Toast } from './toast'

export const customRender: CustomRender = (props) => {
const { type } = props
Expand All @@ -15,6 +16,8 @@ export const customRender: CustomRender = (props) => {
return () => <Modal {...props} />
case 'Pagination':
return () => <Pagination {...props} />
case 'Toast':
return () => <Toast {...props} />
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/npm-fastui-bootstrap/src/toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FC } from 'react'
import { components, events, renderClassName, EventContextProvider } from 'fastui'
import BootstrapToast from 'react-bootstrap/Toast'
import BootstrapToastContainer from 'react-bootstrap/ToastContainer'

export const Toast: FC<components.ToastProps> = (props) => {
const { className, title, body, openTrigger, openContext } = props

const { eventContext, fireId, clear } = events.usePageEventListen(openTrigger, openContext)

return (
<EventContextProvider context={eventContext}>
<BootstrapToastContainer>
<BootstrapToast className={renderClassName(className)} show={!!fireId} onClose={clear}>
<BootstrapToast.Header>
<strong className="me-auto">{title}</strong>
</BootstrapToast.Header>
<BootstrapToast.Body>
<components.AnyCompList propsList={body} />
</BootstrapToast.Body>
</BootstrapToast>
</BootstrapToastContainer>
</EventContextProvider>
)
}
5 changes: 5 additions & 0 deletions src/npm-fastui/src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { IframeComp, IframeProps } from './Iframe'
import { VideoComp, VideoProps } from './video'
import { FireEventComp, FireEventProps } from './FireEvent'
import { CustomComp, CustomProps } from './Custom'
import { ToastComp, ToastProps } from './toast'

export type {
TextProps,
Expand Down Expand Up @@ -73,6 +74,7 @@ export type {
VideoProps,
FireEventProps,
CustomProps,
ToastProps,
}

// TODO some better way to export components
Expand Down Expand Up @@ -106,6 +108,7 @@ export type FastProps =
| VideoProps
| FireEventProps
| CustomProps
| ToastProps

export type FastClassNameProps = Exclude<FastProps, TextProps | AllDisplayProps | ServerLoadProps | PageTitleProps>

Expand Down Expand Up @@ -194,6 +197,8 @@ export const AnyComp: FC<FastProps> = (props) => {
return <FireEventComp {...props} />
case 'Custom':
return <CustomComp {...props} />
case 'Toast':
return <ToastComp {...props} />
default:
unreachable('Unexpected component type', type, props)
return <DisplayError title="Invalid Server Response" description={`Unknown component type: "${type}"`} />
Expand Down
33 changes: 33 additions & 0 deletions src/npm-fastui/src/components/toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FC, useEffect } from 'react'

import type { FastProps } from './index'
import type { ContextType } from '../hooks/eventContext'

import { ClassName } from '../hooks/className'
import { PageEvent, usePageEventListen } from '../events'

export interface ToastProps {
type: 'Toast'
title: string
body: FastProps[]
openTrigger?: PageEvent
openContext?: ContextType
className?: ClassName
}

export const ToastComp: FC<ToastProps> = (props) => {
const { title, openTrigger, openContext } = props

const { fireId, clear } = usePageEventListen(openTrigger, openContext)

useEffect(() => {
if (fireId) {
setTimeout(() => {
alert(`${title}\n\nNote: toasts are not implemented by pure FastUI, implement a component for 'ToastProps'.`)
clear()
})
}
}, [fireId, title, clear])

return <></>
}
10 changes: 10 additions & 0 deletions src/python-fastui/fastui/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ class Custom(_p.BaseModel, extra='forbid'):
type: _t.Literal['Custom'] = 'Custom'


class Toast(_p.BaseModel, extra='forbid'):
title: str
body: '_t.List[AnyComponent]'
open_trigger: _t.Union[events.PageEvent, None] = _p.Field(default=None, serialization_alias='openTrigger')
open_context: _t.Union[events.ContextType, None] = _p.Field(default=None, serialization_alias='openContext')
class_name: _class_name.ClassNameField = None
type: _t.Literal['Toast'] = 'Toast'


AnyComponent = _te.Annotated[
_t.Union[
Text,
Expand Down Expand Up @@ -280,6 +289,7 @@ class Custom(_p.BaseModel, extra='forbid'):
Form,
FormField,
ModelForm,
Toast,
],
_p.Field(discriminator='type'),
]
31 changes: 31 additions & 0 deletions src/python-fastui/tests/react-fastui-json-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@
},
{
"$ref": "#/definitions/CustomProps"
},
{
"$ref": "#/definitions/ToastProps"
}
]
},
Expand Down Expand Up @@ -1385,6 +1388,34 @@
"required": ["text", "type"],
"type": "object"
},
"ToastProps": {
"properties": {
"body": {
"items": {
"$ref": "#/definitions/FastProps"
},
"type": "array"
},
"className": {
"$ref": "#/definitions/ClassName"
},
"openContext": {
"$ref": "#/definitions/ContextType"
},
"openTrigger": {
"$ref": "#/definitions/PageEvent"
},
"title": {
"type": "string"
},
"type": {
"const": "Toast",
"type": "string"
}
},
"required": ["body", "title", "type"],
"type": "object"
},
"VideoProps": {
"properties": {
"autoplay": {
Expand Down

0 comments on commit feb74b1

Please sign in to comment.