Components
Components in Bonito are meant to be re-usable, easily shareable types and functions to create complex Bonito Apps. We invite everyone to share their Components by turning them into a Julia library.
There are two ways of defining components in Bonito:
- Write a function which returns
DOM
objects - Overload
jsrender
for a type
The first is a very lightweight form of defining reusable components, which should be preferred if possible.
But, for e.g. widgets the second form is unavoidable, since you will want to return a type that the user can register interactions with. Also, the second form is great for integrating existing types into Bonito like plot objects. How to do the latter for Plotly is described in Plotting.
Let's start with the simple function based components that reuses existing Bonito components:
using Dates
function CurrentMonth(date=now(); style=Styles(), div_attributes...)
current_day = Dates.day(date)
month = Dates.monthname(date)
ndays = Dates.daysinmonth(date)
current_day_style = Styles(style, "background-color" => "gray", "color" => "white")
days = map(1:ndays) do day
if day == current_day
return Card(Centered(day); style=current_day_style)
else
return Card(Centered(day); style=style)
end
end
grid = Grid(days...; columns="repeat(7, 1fr)")
return DOM.div(DOM.h2(month), grid; style=Styles("width" => "400px", "margin" => "5px"))
end
App(()-> CurrentMonth())
November
Now, we could define the same kind of rendering via overloading jsrender
, if a date is spliced into a DOM:
function Bonito.jsrender(session::Session, date::DateTime)
return Bonito.jsrender(session, CurrentMonth(date))
end
App() do
DOM.div(now())
end
November
Please note, that jsrender
is not applied recursively on its own, so one needs to apply it manually on the return value. It's not needed for simple divs and other Hyperscript elements, but e.g. Styles
requires a pass through jsrender
to do the deduplication etc.