diff --git a/packages/fastui-bootstrap/src/main.scss b/packages/fastui-bootstrap/src/main.scss index 1a05a3fe..54adde9c 100644 --- a/packages/fastui-bootstrap/src/main.scss +++ b/packages/fastui-bootstrap/src/main.scss @@ -1,7 +1 @@ @import 'bootstrap/scss/bootstrap'; - -.modal { - &.show { - display: block; - } -} diff --git a/packages/fastui/src/components/PageTitle.tsx b/packages/fastui/src/components/PageTitle.tsx new file mode 100644 index 00000000..54915db5 --- /dev/null +++ b/packages/fastui/src/components/PageTitle.tsx @@ -0,0 +1,16 @@ +import { FC, useEffect } from 'react' + +export interface PageTitleProps { + type: 'PageTitle' + text: string +} + +export const PageTitleComp: FC = (props) => { + const { text } = props + + useEffect(() => { + document.title = text + }, [text]) + + return <> +} diff --git a/packages/fastui/src/components/index.tsx b/packages/fastui/src/components/index.tsx index 7ee44c0c..35097e64 100644 --- a/packages/fastui/src/components/index.tsx +++ b/packages/fastui/src/components/index.tsx @@ -4,8 +4,10 @@ import { ErrorContext } from '../hooks/error' import { useCustomRender } from '../hooks/config' import { unreachable } from '../tools' -import { AllDivProps, DivComp } from './div' import { TextProps, TextComp } from './text' +import { ParagraphProps, ParagraphComp } from './paragraph' +import { PageTitleProps, PageTitleComp } from './PageTitle' +import { AllDivProps, DivComp } from './div' import { HeadingComp, HeadingProps } from './heading' import { FormComp, FormProps, ModelFormProps } from './form' import { @@ -34,6 +36,8 @@ import { ServerLoadComp, ServerLoadProps } from './ServerLoad' export type { TextProps, + ParagraphProps, + PageTitleProps, AllDivProps, HeadingProps, FormProps, @@ -56,6 +60,8 @@ export { LinkComp, LinkRender } export type FastProps = | TextProps + | ParagraphProps + | PageTitleProps | AllDivProps | HeadingProps | FormProps @@ -71,7 +77,7 @@ export type FastProps = | JsonProps | ServerLoadProps -export type FastClassNameProps = Exclude +export type FastClassNameProps = Exclude export const AnyCompList: FC<{ propsList: FastProps[] }> = ({ propsList }) => ( <> @@ -94,6 +100,10 @@ export const AnyComp: FC = (props) => { switch (type) { case 'Text': return + case 'Paragraph': + return + case 'PageTitle': + return case 'Div': case 'Page': case 'Row': diff --git a/packages/fastui/src/components/modal.css b/packages/fastui/src/components/modal.css deleted file mode 100644 index bd3ad80a..00000000 --- a/packages/fastui/src/components/modal.css +++ /dev/null @@ -1,49 +0,0 @@ -.fu-modal-overlay { - position: fixed; - display: none; - z-index: 1; - left: 0; - top: 0; - width: 100%; - height: 100%; - overflow: auto; - background-color: rgba(0, 0, 0, 0.4); -} - -.fu-modal-overlay.open { - display: block; -} - -.fu-modal-content { - background: white; - margin: 100px auto; - border: 1px solid #888; - width: 95%; - max-width: 500px; - border-radius: 8px; -} - -.fu-model-header { - display: flex; - justify-content: space-between; - padding: 10px 20px; - border-bottom: 1px solid #ccc; -} - -.fu-close { - color: #aaa; - font-size: 28px; - font-weight: bold; - cursor: pointer; -} - -.fu-modal-body { - padding: 20px; -} - -.fu-modal-footer { - display: flex; - justify-content: right; - padding: 10px 20px 20px; - border-top: 1px solid #ccc; -} diff --git a/packages/fastui/src/components/modal.tsx b/packages/fastui/src/components/modal.tsx index c9269d61..d4459fb8 100644 --- a/packages/fastui/src/components/modal.tsx +++ b/packages/fastui/src/components/modal.tsx @@ -1,9 +1,9 @@ -import { FC, lazy } from 'react' +import { FC, useEffect } from 'react' -import { ClassName, renderClassName, useClassName } from '../hooks/className' +import { ClassName } from '../hooks/className' import { PageEvent, useEventListenerToggle } from '../hooks/events' -import { FastProps, AnyCompList } from './index' +import { FastProps } from './index' export interface ModalProps { type: 'Modal' @@ -15,35 +15,19 @@ export interface ModalProps { className?: ClassName } -// @ts-expect-error typescript doesn't understand `./modal.css` -const DefaultCss = lazy(() => import('./modal.css')) - export const ModalComp: FC = (props) => { - const { title, body, footer, openTrigger } = props + const { title, openTrigger } = props const [open, toggle] = useEventListenerToggle(openTrigger, props.open) - return ( - <> - -
-
-
-

{title}

-
- × -
-
-
- -
- {footer && ( -
- -
- )} -
-
- - ) + useEffect(() => { + if (open) { + setTimeout(() => { + alert(`${title}\n\nNote: modals are not implemented by pure FastUI, implement a component for 'ModalProps'.`) + toggle() + }) + } + }, [open, title, toggle]) + + return <> } diff --git a/packages/fastui/src/components/paragraph.tsx b/packages/fastui/src/components/paragraph.tsx new file mode 100644 index 00000000..91311a72 --- /dev/null +++ b/packages/fastui/src/components/paragraph.tsx @@ -0,0 +1,15 @@ +import { FC } from 'react' + +import { ClassName, useClassName } from '../hooks/className' + +export interface ParagraphProps { + type: 'Paragraph' + text: string + className?: ClassName +} + +export const ParagraphComp: FC = (props) => { + const { text } = props + + return

{text}

+} diff --git a/packages/vanilla/index.html b/packages/vanilla/index.html index eb6806f1..d470742d 100644 --- a/packages/vanilla/index.html +++ b/packages/vanilla/index.html @@ -3,7 +3,7 @@ - FastUI +
diff --git a/python/demo/main.py b/python/demo/main.py index a2cdcbaa..c6187061 100644 --- a/python/demo/main.py +++ b/python/demo/main.py @@ -24,6 +24,7 @@ def navbar() -> AnyComponent: links=[ c.Link(components=[c.Text(text='Home')], on_click=GoToEvent(url='/'), active='/'), c.Link(components=[c.Text(text='Table')], on_click=GoToEvent(url='/table'), active='/table'), + c.Link(components=[c.Text(text='Forms')], on_click=GoToEvent(url='/form'), active='/form'), ], ) @@ -31,10 +32,12 @@ def navbar() -> AnyComponent: @app.get('/api/', response_model=FastUI, response_model_exclude_none=True) def read_root() -> list[AnyComponent]: return [ + c.PageTitle(text='FastUI Demo'), navbar(), c.Page( components=[ c.Heading(text='Hello World'), + c.Paragraph(text='This is a demo of FastUI.'), c.Row( components=[ c.Col(components=[c.Text(text='Hello World')]), @@ -72,6 +75,7 @@ async def modal_view() -> list[AnyComponent]: def table_view() -> list[AnyComponent]: return [ navbar(), + c.PageTitle(text='FastUI Demo - Table'), c.Page( components=[ c.Heading(text='Table'), @@ -130,6 +134,7 @@ def name_validator(cls, v: str) -> str: def form_view() -> list[AnyComponent]: return [ navbar(), + c.PageTitle(text='FastUI Demo - Form Examples'), c.Page( components=[ c.Heading(text='Form'), diff --git a/python/fastui/components/__init__.py b/python/fastui/components/__init__.py index 83fe8421..6849a96a 100644 --- a/python/fastui/components/__init__.py +++ b/python/fastui/components/__init__.py @@ -41,6 +41,20 @@ class Text(pydantic.BaseModel, extra='forbid'): type: typing.Literal['Text'] = 'Text' +class Paragraph(pydantic.BaseModel, extra='forbid'): + text: str + type: typing.Literal['Paragraph'] = 'Paragraph' + + +class PageTitle(pydantic.BaseModel, extra='forbid'): + """ + This sets the title of the HTML page via the `document.title` property. + """ + + text: str + type: typing.Literal['PageTitle'] = 'PageTitle' + + class Div(pydantic.BaseModel, extra='forbid'): components: list[AnyComponent] class_name: extra.ClassName | None = None @@ -132,6 +146,8 @@ class ServerLoad(pydantic.BaseModel, extra='forbid'): AnyComponent = typing.Annotated[ Text + | Paragraph + | PageTitle | Div | Page | Heading