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

Added footer component #61

Merged
merged 29 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
afe1860
Added footer component
Dejiah Dec 3, 2023
1abfe08
Added note to footer component to README.md
Dejiah Dec 4, 2023
06aa679
Merge branch 'main' into footer-component
Dejiah Dec 4, 2023
f4c8658
Made extraText camelcase in frontend
Dejiah Dec 4, 2023
f57dd79
Merge remote-tracking branch 'origin/footer-component' into footer-co…
Dejiah Dec 4, 2023
5d98ef7
Moved bootstrap-specific code out of generic footer
Dejiah Dec 5, 2023
2277be4
Fixed imports
Dejiah Dec 5, 2023
f9427df
Merge branch 'main' into footer-component
Dejiah Dec 5, 2023
4d757dd
Fixed merge conflicts
Dejiah Dec 5, 2023
3568341
Fixed merge conflicts
Dejiah Dec 5, 2023
0e2f544
Fixed python typing hints in footer
Dejiah Dec 5, 2023
1126c57
Merge branch 'main' into footer-component
Dejiah Dec 11, 2023
68c8a53
Made Footer extraText a string
Dejiah Dec 11, 2023
2fce090
Fixed class_name field in footer
Dejiah Dec 11, 2023
0660854
Made tests pass
Dejiah Dec 11, 2023
2f1c5c0
Merge branch 'main' into footer-component
Dejiah Dec 14, 2023
0ed11ba
Changed pydantic to _p
Dejiah Dec 14, 2023
b521ebf
fied Footer pydantic fields
samuelcolvin Dec 17, 2023
b8baa9e
Update demo/shared.py
Dejiah Dec 19, 2023
583feb8
Added Github as footer link
Dejiah Dec 19, 2023
4b33658
Removed horizontal line in footer
Dejiah Dec 19, 2023
aa4e045
Merge branch 'main' into footer-component
Dejiah Dec 19, 2023
4393fe8
Applied linting
Dejiah Dec 19, 2023
93044f1
Fixed demo tests
Dejiah Dec 19, 2023
991335b
Merge branch 'main' into Dejiah-footer-component
samuelcolvin Dec 22, 2023
c1f8d81
fix possitioning
samuelcolvin Dec 22, 2023
0b5bb54
fix tests
samuelcolvin Dec 22, 2023
126f037
stop rendering to root
samuelcolvin Dec 28, 2023
c53dfe9
revert prebuilt_html
samuelcolvin Dec 28, 2023
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ FastUI already defines the following components, all are shown in the [demo app]
- `Link` — renders a link `<a>`
- `LinkList` — renders a list of links
- `Navbar` — renders a navbar `<nav>`
- `Footer` — renders a footer `<footer>` with links and/or text
- `Modal` — renders a modal dialog that opens triggered by an event
- `ServerLoad` — render components fetched from the server, also provides SSE mode to update components based on server sent events
- `Table` — renders a table
Expand Down
9 changes: 9 additions & 0 deletions demo/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,13 @@ def demo_page(*components: AnyComponent, title: str | None = None) -> list[AnyCo
*components,
],
),
c.Footer(
extra_text=c.Text(text='FastUI Demo - Extra footer text'),
links=[
c.Link(components=[c.Text(text='Home')], on_click=GoToEvent(url='/')),
c.Link(components=[c.Text(text='Components')], on_click=GoToEvent(url='/components')),
Dejiah marked this conversation as resolved.
Show resolved Hide resolved
c.Link(components=[c.Text(text='Tables')], on_click=GoToEvent(url='/table/cities')),
c.Link(components=[c.Text(text='Forms')], on_click=GoToEvent(url='/forms/login')),
],
),
]
30 changes: 30 additions & 0 deletions src/npm-fastui-bootstrap/src/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { FC } from 'react'
import { components, useClassName } from 'fastui'

export const Footer: FC<components.FooterProps> = (props) => {
const links = props.links.map((link) => {
link.mode = link.mode || 'footer'
return link
})
const extraSeparatorProp = useClassName(props, { el: 'extra-separator' })
Dejiah marked this conversation as resolved.
Show resolved Hide resolved
const extraProp = useClassName(props, { el: 'extra' })
return (
<div className={useClassName(props, { el: 'contents' })}>
Dejiah marked this conversation as resolved.
Show resolved Hide resolved
<footer className={useClassName(props)}>
<ul className={useClassName(props, { el: 'link-list' })}>
{links.map((link, i) => (
<li className="nav-item">
<components.LinkComp key={i} {...link} />
</li>
))}
</ul>
{props.extraText && props.links.length > 0 && <div className={extraSeparatorProp} />}
{props.extraText && (
<div className={extraProp}>
<components.TextComp {...props.extraText} />
</div>
)}
</footer>
</div>
)
}
19 changes: 18 additions & 1 deletion src/npm-fastui-bootstrap/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import type { ClassNameGenerator, CustomRender, ClassName } from 'fastui'
import { Modal } from './modal'
import { Navbar } from './navbar'
import { Pagination } from './pagination'
import { Footer } from './footer'

export const customRender: CustomRender = (props) => {
const { type } = props
switch (type) {
case 'Navbar':
return () => <Navbar {...props} />
case 'Footer':
return () => <Footer {...props} />
case 'Modal':
return () => <Modal {...props} />
case 'Pagination':
Expand Down Expand Up @@ -100,10 +103,24 @@ export const classNameGenerator: ClassNameGenerator = ({ props, fullPath, subEle
default:
return 'border-bottom fixed-top bg-body'
}
case 'Footer':
switch (subElement) {
case 'contents':
return 'border-top py-3 my-3'
case 'link-list':
return 'nav justify-content-center pb-3'
case 'extra-separator':
return 'border-top'
case 'extra':
return 'text-center text-muted pt-3'
default:
return 'container'
}
case 'Link':
return {
active: pathMatch(props.active, fullPath),
'nav-link': props.mode === 'navbar' || props.mode === 'tabs',
'nav-link': props.mode === 'navbar' || props.mode === 'tabs' || props.mode === 'footer',
'text-muted': props.mode === 'footer',
}
case 'LinkList':
if (subElement === 'link-list-item' && props.mode) {
Expand Down
31 changes: 31 additions & 0 deletions src/npm-fastui/src/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ClassName, useClassName } from '../hooks/className'

import { LinkProps, LinkComp } from './link'
import { TextComp, TextProps } from './text'

export interface FooterProps {
type: 'Footer'
extraText?: TextProps
Dejiah marked this conversation as resolved.
Show resolved Hide resolved
links: LinkProps[]
className?: ClassName
}

export const FooterComp = (props: FooterProps) => {
const links = props.links.map((link) => {
link.mode = link.mode || 'footer'
return link
})
const extraTextClassName = useClassName(props, { el: 'extra' })
return (
<footer className={useClassName(props)}>
{links.map((link, i) => (
<LinkComp key={i} {...link} />
))}
{props.extraText && (
<div className={extraTextClassName}>
<TextComp {...props.extraText} />
</div>
)}
</footer>
)
}
7 changes: 6 additions & 1 deletion src/npm-fastui/src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from './display'
import { JsonComp, JsonProps } from './Json'
import { ServerLoadComp, ServerLoadProps } from './ServerLoad'
import { FooterComp, FooterProps } from './footer'
import { ImageComp, ImageProps } from './image'
import { IframeComp, IframeProps } from './Iframe'

Expand All @@ -61,6 +62,7 @@ export type {
LinkProps,
LinkListProps,
NavbarProps,
FooterProps,
AllDisplayProps,
DisplayPrimitiveProps,
JsonProps,
Expand All @@ -70,7 +72,7 @@ export type {
}

// TODO some better way to export components
export { LinkComp, LinkRender }
export { LinkComp, LinkRender, TextComp }

export type FastProps =
| TextProps
Expand All @@ -92,6 +94,7 @@ export type FastProps =
| LinkProps
| LinkListProps
| NavbarProps
| FooterProps
| AllDisplayProps
| JsonProps
| ServerLoadProps
Expand Down Expand Up @@ -142,6 +145,8 @@ export const AnyComp: FC<FastProps> = (props) => {
return <LinkListComp {...props} />
case 'Navbar':
return <NavbarComp {...props} />
case 'Footer':
return <FooterComp {...props} />
case 'Form':
case 'ModelForm':
return <FormComp {...props} />
Expand Down
2 changes: 1 addition & 1 deletion src/npm-fastui/src/components/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { FastProps, AnyCompList } from './index'
export interface LinkProps {
type: 'Link'
components: FastProps[]
mode?: 'navbar' | 'tabs' | 'vertical' | 'pagination'
mode?: 'navbar' | 'footer' | 'tabs' | 'vertical' | 'pagination'
active?: boolean | string
locked?: boolean
onClick?: AnyEvent
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 @@ -37,6 +37,7 @@
'Button',
'Modal',
'ModelForm',
'Footer',
'FormFieldInput',
'FormFieldBoolean',
'FormFieldFile',
Expand Down Expand Up @@ -126,7 +127,7 @@ class Button(pydantic.BaseModel, extra='forbid'):
class Link(pydantic.BaseModel, extra='forbid'):
components: '_t.List[AnyComponent]'
on_click: _t.Union[events.AnyEvent, None] = pydantic.Field(default=None, serialization_alias='onClick')
mode: _t.Union[_t.Literal['navbar', 'tabs', 'vertical', 'pagination'], None] = None
mode: _t.Union[_t.Literal['navbar', 'footer', 'tabs', 'vertical', 'pagination'], None] = None
active: _t.Union[bool, str, None] = None
locked: _t.Union[bool, None] = None
class_name: _class_name.ClassName = None
Expand All @@ -148,6 +149,13 @@ class Navbar(pydantic.BaseModel, extra='forbid'):
type: _t.Literal['Navbar'] = 'Navbar'


class Footer(pydantic.BaseModel, extra='forbid'):
extra_text: _t.Union[Text, None] = pydantic.Field(default=None, serialization_alias='extraText')
links: _t.List[Link] = pydantic.Field(default_factory=list)
class_name: _class_name.ClassName = None
type: _t.Literal['Footer'] = 'Footer'


class Modal(pydantic.BaseModel, extra='forbid'):
title: str
body: '_t.List[AnyComponent]'
Expand Down Expand Up @@ -216,6 +224,7 @@ class Iframe(pydantic.BaseModel, extra='forbid'):
Link,
LinkList,
Navbar,
Footer,
Modal,
ServerLoad,
Table,
Expand Down