Powered by Cookiecutter, this project shows how to use FastUI with a custom component.
- Python:
>=3.10
(older versions can work, but are not tested) - Cookiecutter:
pipx install cookiecutter
- Poetry:
pipx install poetry
- Node.js:
>=v18.16.1
- npm:
>=9.5.1
# Create a new project from the template
cookiecutter gh:JulianSobott/cookiecutter-fastui-starter
# Change into the new directory (adjust the name if you changed it)
cd fastui_starter
# Install python dependencies
poetry install
cd fastui_starter_app
# Install node dependencies
npm install
Since something is wrong with the fastui-bootstrap
package, you need to adjust it manually.
In fastui_starter_app/node_modules/@pydantic/fastui-bootstrap.package.json
change the following lines:
{
"name": "@pydantic/fastui-bootstrap",
"version": "0.0.22",
"description": "Boostrap renderer for FastUI",
- "main": "dist/index.js",
+ "main": "dist/npm-fastui-bootstrap/src/index.js",
- "types": "dist/index.d.ts",
+ "types": "dist/npm-fastui-bootstrap/src/index.d.ts",
Final file should start like this:
{
"name": "@pydantic/fastui-bootstrap",
"version": "0.0.22",
"description": "Boostrap renderer for FastUI",
"main": "dist/npm-fastui-bootstrap/src/index.js",
"types": "dist/npm-fastui-bootstrap/src/index.d.ts",
"author": "Samuel Colvin",
}
Start backend and frontend with hot-reload.
# start the backend with reload (adjust fastui_starter to your project name)
poetry run uvicorn fastui_starter_app.main:app --reload
cd fastui_starter_app
# run the frontend in development mode
npm run dev
# build frontend
cd fastui_starter_app
npm run build
cd ..
# start backend
poetry run uvicorn fastui_starter_app.main:app
- Create a new React function component. For example in
src/App.tsx
const MyComponent: FC<{ text: string }> = ({ text }) => {
return <div>Message from my own component: {text}</div>;
}
- return it in the
customRender
function insrc/App.tsx
const customRender: CustomRender = (props) => {
const { type } = props
// You can name your library whatever you want (e.g. yourLib)
if (type === 'Custom' && props.library === "yourLib") {
switch (props.subType) {
// Add your components here
case 'MyComponent':
return () => <MyComponent text={props.data as string} />
default:
return bootstrap.customRender(props)
}
} else {
return bootstrap.customRender(props)
}
}
- Use it with the
Custom
class:
return [
c.Page( # Page provides a basic container for components
components=[
c.Custom(data='This is a custom component', sub_type="myComponent", library="yourLib"),
]
),
]
- Optionally, you can create a function to generate the
Custom
component:
def my_component(text: str) -> c.Custom:
return c.Custom(data=text, sub_type="myComponent", library="yourLib")
# ...
return [
c.Page( # Page provides a basic container for components
components=[
my_component('This is a custom component'),
]
),
]