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

Static HTML layouts and formatted text #27

Merged
merged 8 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 render-compose-html/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ kotlin {
implementation(compose.runtime)
implementation(libs.kotlinx.coroutines.core)
api(projects.structures)
implementation(projects.renderWebCommon)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package ink.ui.render.compose.html
import androidx.compose.runtime.Composable
import ink.ui.render.compose.html.renderer.*
import ink.ui.render.compose.html.renderer.CompositeElementRenderer
import ink.ui.render.web.gridTemplateColumns
import ink.ui.structures.Positioning
import ink.ui.structures.elements.UiElement
import ink.ui.structures.layouts.*
import ink.ui.structures.render.RenderResult
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.Section
Expand Down Expand Up @@ -41,7 +43,7 @@ class HtmlComposeRenderer(
attrs = {
classes("fixed-grid")
style {
gridTemplateColumns((0 until uiLayout.columns).joinToString(" ") { "auto" })
gridTemplateColumns(uiLayout.gridTemplateColumns)
}
}
) {
Expand All @@ -50,7 +52,6 @@ class HtmlComposeRenderer(
attrs = {
style {
gridColumn("span ${it.span}")
display(DisplayStyle.Flex)
when (it.horizontalPositioning) {
Positioning.Start -> {
justifyContent(JustifyContent.Start)
Expand Down Expand Up @@ -95,8 +96,9 @@ class HtmlComposeRenderer(

@Composable
fun renderElement(element: UiElement) {
when (uiRenderer.render(element, uiRenderer)) {
RenderResult.NotRendered -> throw IllegalArgumentException("No renderer registered for ${element::class.simpleName}")
when (val result = uiRenderer.render(element, uiRenderer)) {
RenderResult.Skipped -> throw IllegalArgumentException("No renderer registered for ${element::class.simpleName}")
is RenderResult.Failed -> throw result.exception
RenderResult.Rendered -> {}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.*
import ink.ui.render.web.toCssClass
import ink.ui.structures.Sentiment
import ink.ui.structures.elements.ProgressElement
import ink.ui.structures.elements.ThrobberElement
import ink.ui.structures.elements.UiElement
import ink.ui.structures.render.RenderResult
import kotlinx.coroutines.delay
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.*
Expand All @@ -18,7 +20,7 @@ object ActivityRenderer: ElementRenderer {
when (element) {
is ProgressElement -> ProgressBar(element)
is ThrobberElement -> Throbber(element.caption, element.sentiment)
else -> return RenderResult.NotRendered
else -> return RenderResult.Skipped
}

return RenderResult.Rendered
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.render.web.svgSrc
import ink.ui.render.web.toCssClass
import ink.ui.structures.elements.ButtonElement
import ink.ui.structures.elements.UiElement
import org.jetbrains.compose.web.dom.Button
import org.jetbrains.compose.web.dom.Img
import org.jetbrains.compose.web.dom.Text

object ButtonRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is ButtonElement) return RenderResult.NotRendered

Button(
attrs = {
classes(element.sentiment.toCssClass())
onClick {
element.onClick()
}
}
) {
val leadingSymbol = element.leadingSymbol
if (leadingSymbol != null) {
Img(
attrs = {
classes("icon", "svg-fill", element.sentiment.toCssClass())
},
src = leadingSymbol.svgSrc,
)
val ButtonRenderer = renderer<ButtonElement> { element ->
Button(
attrs = {
classes(element.sentiment.toCssClass())
onClick {
element.onClick()
}
Text(element.text)
}

return RenderResult.Rendered
) {
val leadingSymbol = element.leadingSymbol
if (leadingSymbol != null) {
Img(
attrs = {
classes("icon", "svg-fill", element.sentiment.toCssClass())
},
src = leadingSymbol.svgSrc,
)
}
Text(element.text)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.structures.elements.CheckBoxElement
import ink.ui.structures.elements.UiElement
import org.jetbrains.compose.web.attributes.InputType
import org.jetbrains.compose.web.dom.Input

object CheckBoxRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is CheckBoxElement) return RenderResult.NotRendered

Input(
type = InputType.Checkbox,
attrs = {
onClick { element.onClick() }
checked(element.checked)
}
)

return RenderResult.Rendered
}
val CheckBoxRenderer = renderer<CheckBoxElement> { element ->
Input(
type = InputType.Checkbox,
attrs = {
onClick { element.onClick() }
checked(element.checked)
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.structures.elements.UiElement
import ink.ui.structures.render.RenderResult
import ink.ui.structures.render.renderCatching

internal class CompositeElementRenderer(
private val renderers: List<ElementRenderer> = emptyList(),
): ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
renderers.forEach { renderer ->
if (renderer.render(element, this) == RenderResult.Rendered) {
return RenderResult.Rendered
val result = renderCatching { renderer.render(element, this) }

if (result != RenderResult.Skipped) {
return result
}
}
return RenderResult.NotRendered
return RenderResult.Skipped
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.structures.elements.UiElement
import ink.ui.structures.render.RenderResult
import ink.ui.structures.render.renderCatching

/**
* Renders a UI element in compose.
Expand All @@ -13,3 +15,19 @@ interface ElementRenderer {
parent: ElementRenderer
): RenderResult
}

inline fun <reified T: UiElement> renderer(
crossinline render: @Composable (element: T) -> Unit
): ElementRenderer = object: ElementRenderer {
@Composable
override fun render(
element: UiElement,
parent: ElementRenderer
): RenderResult {
if (element !is T) return RenderResult.Skipped
return renderCatching {
render(element)
RenderResult.Rendered
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.structures.elements.EmptyElement
import ink.ui.structures.elements.UiElement
import org.jetbrains.compose.web.dom.Span

object EmptyRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is EmptyElement) return RenderResult.NotRendered

val EmptyRenderer = renderer<EmptyElement> { element ->
Span {}

return RenderResult.Rendered
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
package ink.ui.render.compose.html.renderer

import androidx.compose.runtime.Composable
import ink.ui.render.web.svgSrc
import ink.ui.render.web.toCssClass
import ink.ui.structures.elements.IconElement
import ink.ui.structures.elements.UiElement
import org.jetbrains.compose.web.dom.Img

object IconRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is IconElement) return RenderResult.NotRendered

Img(
src = element.symbol.svgSrc,
attrs = {
classes("icon", "svg-fill", element.sentiment.toCssClass())
}
)

return RenderResult.Rendered
}
val IconRenderer = renderer<IconElement> { element ->
Img(
src = element.symbol.svgSrc,
attrs = {
classes("icon", "svg-fill", element.sentiment.toCssClass())
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import ink.ui.structures.GroupingStyle
import ink.ui.structures.Positioning
import ink.ui.structures.elements.ElementList
import ink.ui.structures.elements.UiElement
import ink.ui.structures.render.RenderResult
import org.jetbrains.compose.web.css.JustifyContent
import org.jetbrains.compose.web.css.justifyContent
import org.jetbrains.compose.web.dom.Div

object ListRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is ElementList) return RenderResult.NotRendered
if (element !is ElementList) return RenderResult.Skipped

Div(
attrs = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package ink.ui.render.compose.html.renderer
import androidx.compose.runtime.Composable
import ink.ui.structures.elements.MenuRowElement
import ink.ui.structures.elements.UiElement
import ink.ui.structures.render.RenderResult
import org.jetbrains.compose.web.dom.*

object MenuRowRenderer: ElementRenderer {
@Composable
override fun render(element: UiElement, parent: ElementRenderer): RenderResult {
if (element !is MenuRowElement) return RenderResult.NotRendered
if (element !is MenuRowElement) return RenderResult.Skipped
val elementOnClick = element.onClick
Div(
attrs = {
Expand Down

This file was deleted.

This file was deleted.

Loading