-module(gbr@ui). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src\\gbr\\ui.gleam"). -export([loader/1, primary_with_breadcrumb/4, primary/3, partial/2, horizontal/1, grid/3, box/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( "\n" " 🎨 Gleam UI library by @gleam-br\n" "\n" " Loader:\n" "\n" " ```gleam\n" " fn view(model: Model) -> Element(ModelEvent) {\n" " let Model(loading:) = model\n" "\n" " loading\n" " |> ui.loader()\n" " }\n" " ```\n" "\n" " Horizontal:\n" "\n" " ```gleam\n" " pub fn render(in: Login) -> Element(LoginEvent) {\n" " let Login(basic:, logo:) = in\n" "\n" " [basic, logo]\n" " |> ui.horizontal()\n" " }\n" " ```\n" "\n" " Main:\n" "\n" " ```gleam\n" " pub fn render(in: AdminHome) -> Element(AdminEvent) {\n" " let AdminHome(sidebar:, header:, content:, breadcrumb:) = in\n" "\n" " ui.primary(header:, sidebar:, content:, breadcrumb:)\n" " }\n" " ```\n" "\n" ). -file("src\\gbr\\ui.gleam", 89). ?DOC( " UI loader layout with ui screen full blur and a center spin loader.\n" "\n" " Better choice to work with [gbr_js](https://github.com/gleam-br/gbr_js) and `gbr/js/global.{dom_content_loaded}`.\n" "\n" " Supose on dom loaded dispatch OnLoading(False) when:\n" " - init: Model(loading: True)\n" " - after: Model(loading: False):\n" "\n" " ```gleam\n" " fn on_dom_loaded(runtime) {\n" " use _ <- function.tap(runtime)\n" " use _ <- global.dom_content_loaded()\n" "\n" " AdminEventOnLoading(False)\n" " |> lustre.dispatch()\n" " |> lustre.send(runtime, _)\n" " }\n" "\n" " fn view(model: Model) -> Element(ModelEvent) {\n" " let Model(loading:) = model\n" "\n" " loading\n" " |> ui.loader()\n" " }\n" " ```\n" "\n" " ### Fn desc: Trasform one `1 -> 1`\n" "\n" " Bool type to loader element layout\n" "\n" " - `True`: Render loader\n" " - `False`: Render `lustre/element.{none}`\n" ). -spec loader(boolean()) -> lustre@vdom@vnode:element(any()). loader(Loading) -> gleam@bool:guard( not Loading, lustre@element:none(), fun() -> lustre@element@html:'div'( [lustre@attribute:class( <<"fixed left-0 top-0 z-999999 flex h-screen w-screen items-center justify-center bg-white dark:bg-black"/utf8>> )], [lustre@element@html:'div'( [lustre@attribute:class( <<"h-16 w-16 animate-spin rounded-full border-4 border-solid border-brand-500 border-t-transparent"/utf8>> )], [] )] ) end ). -file("src\\gbr\\ui.gleam", 212). ?DOC( " Same of `gbr/ui.primary` with optional breadcrumb element.\n" "\n" " TODO: WIP\n" ). -spec primary_with_breadcrumb( lustre@vdom@vnode:element(OHI), lustre@vdom@vnode:element(OHI), gleam@option:option(lustre@vdom@vnode:element(OHI)), gleam@option:option(lustre@vdom@vnode:element(OHI)) ) -> lustre@vdom@vnode:element(OHI). primary_with_breadcrumb(Header, Sidebar, Content, Breadcrumb) -> Breadcrumb@1 = gleam@option:unwrap(Breadcrumb, lustre@element:none()), Content@1 = gleam@option:unwrap(Content, lustre@element:none()), lustre@element@html:'div'( [lustre@attribute:class( <<"flex h-screen overflow-hidden bg-gray-100 dark:bg-gray-900"/utf8>> )], [Sidebar, lustre@element@html:'div'( [lustre@attribute:class( <<"relative flex flex-1 flex-col overflow-x-hidden overflow-y-auto"/utf8>> )], [Header, lustre@element@html:main( [], [lustre@element@html:'div'( [lustre@attribute:class( <<"mx-auto max-w-(--breakpoint-2xl) p-4 md:p-6"/utf8>> )], [Breadcrumb@1, Content@1] )] )] )] ). -file("src\\gbr\\ui.gleam", 156). ?DOC( " UI primary layout with header, sidebar, breadcrumb and content.\n" "\n" " Excelent layout to admin home page.\n" "\n" " Better choise to work with [gbr_ui_router](https://github.com/gleam-br/gbr_ui_router) links in sidebar to update content element.\n" "\n" " Supose admin home render function:\n" "\n" " ```gleam\n" " pub fn render(in: AdminHome) -> Element(AdminEvent) {\n" " let AdminHome(sidebar:, header:, content:, breadcrumb:) = in\n" "\n" " ui.primary(header:, sidebar:, content:, breadcrumb:)\n" " }\n" " ```\n" "\n" " ### Fn desc: Transform three `3 -> 1`\n" "\n" " Three elements to one element with primary layout.\n" ). -spec primary( lustre@vdom@vnode:element(OGU), lustre@vdom@vnode:element(OGU), gleam@option:option(lustre@vdom@vnode:element(OGU)) ) -> lustre@vdom@vnode:element(OGU). primary(Header, Sidebar, Content) -> primary_with_breadcrumb(Header, Sidebar, Content, none). -file("src\\gbr\\ui.gleam", 129). ?DOC( " UI layout partial with header and sidebar only.\n" "\n" " Better choise when you need only partial primary layout.\n" "\n" " ### Fn desc: Transform two `2 -> 1`\n" "\n" " Two elements to one element with partial primary layout ui.\n" ). -spec partial(lustre@vdom@vnode:element(OGQ), lustre@vdom@vnode:element(OGQ)) -> lustre@vdom@vnode:element(OGQ). partial(Header, Sidebar) -> primary(Header, Sidebar, none). -file("src\\gbr\\ui.gleam", 115). ?DOC( " UI layout with horizontal inner elements.\n" "\n" " Better choise to work with `gbr/ui/login.{basic}`.\n" "\n" " Supose login render function:\n" "\n" " ```gleam\n" " pub fn render(in: Login) -> Element(LoginEvent) {\n" " let Login(basic:, logo:) = in\n" "\n" " [basic, logo]\n" " |> ui.horizontal()\n" " }\n" " ```\n" " ### Fn desc: Reduce `* -> 1`\n" "\n" " List of elements to one element with horizontal layout inner elements.\n" ). -spec horizontal(list(lustre@vdom@vnode:element(OGN))) -> lustre@vdom@vnode:element(OGN). horizontal(Inner) -> lustre@element@html:'div'( [lustre@attribute:class(<<"relative p-6 sm:p-0"/utf8>>)], [lustre@element@html:'div'( [lustre@attribute:class( <<"relative flex flex-col justify-center w-full h-screen bg-white dark:bg-gray-900 sm:p-0 lg:flex-row"/utf8>> )], Inner )] ). -file("src\\gbr\\ui.gleam", 185). ?DOC( " UI grid layout with left, right, inner elements.\n" "\n" " Excelent layout to one page message from errors, e.g. 404 or page to payment success message.\n" "\n" " Supose page 404 with grid img background render function:\n" "\n" " ```gleam\n" " pub fn render() -> Element(Msg) {\n" " let img = html.img([src(\"/assets/grid-01.svg\"), alt(\"Grid\")])\n" " let inner = [\n" " html.h1([], [html.text(\"404: Not found\")])\n" " ]\n" "\n" " ui.grid(left: img, right: img, inner:)\n" " }\n" " ```\n" "\n" " ### Fn desc: Transform three `3 -> 1`\n" "\n" " Three elements to one element with grid layout.\n" ). -spec grid( list(lustre@vdom@vnode:element(OGZ)), list(lustre@vdom@vnode:element(OGZ)), list(lustre@vdom@vnode:element(OGZ)) ) -> lustre@vdom@vnode:element(OGZ). grid(Left, Right, Inner) -> lustre@element@html:'div'( [lustre@attribute:class( <<"relative items-center hidden w-full h-full bg-brand-950 dark:bg-white/5 lg:grid lg:w-1/2"/utf8>> )], [lustre@element@html:'div'( [lustre@attribute:class( <<"flex items-center justify-center z-1"/utf8>> )], [lustre@element@html:'div'( [lustre@attribute:class( <<"absolute right-0 top-0 -z-1 w-full max-w-[250px] xl:max-w-[450px]"/utf8>> )], Left ), lustre@element@html:'div'( [lustre@attribute:class( <<"absolute bottom-0 left-0 -z-1 w-full max-w-[250px] rotate-180 xl:max-w-[450px]"/utf8>> )], Right ) | Inner] )] ). -file("src\\gbr\\ui.gleam", 245). -spec box_inner(list(gbr@ui@core@model:u_i_box(OJW))) -> list(lustre@vdom@vnode:element(OJW)). box_inner(In) -> gleam@list:map( lists:reverse(In), fun(Box) -> {u_i_box, Title, Content, Footer, Attrs} = Box, lustre@element@html:'div'( Attrs, [lustre@element@html:h3( [lustre@attribute:class( <<"mb-2 font-semibold text-gray-900 dark:text-white"/utf8>> )], [Title] ), lustre@element@html:p( [lustre@attribute:class( <<"mb-4 text-theme-sm text-gray-500 dark:text-gray-400"/utf8>> )], [Content] ), lustre@element@html:'div'( [lustre@attribute:class( <<"flex items-center justify-center rounded-lg bg-brand-500 p-3 text-theme-sm font-medium text-white hover:bg-brand-600"/utf8>> )], [Footer] )] ) end ). -file("src\\gbr\\ui.gleam", 201). ?DOC(" UI boxes layout\n"). -spec box( list(gbr@ui@core@model:u_i_box(OHE)), list(lustre@vdom@vattr:attribute(OHE)) ) -> lustre@vdom@vnode:element(OHE). box(In, Attrs) -> Attrs@1 = [lustre@attribute:class( <<"mx-auto mb-10 w-full max-w-60 rounded-2xl bg-gray-50 px-4 py-5 text-center dark:bg-white/[0.03]"/utf8>> ) | Attrs], Inner = box_inner(In), lustre@element@html:'div'(Attrs@1, Inner).