Focus: Multi-window capabilities, desktop-specific features, and advanced styling. Goal: Enable complex desktop-class applications, advanced web workflows, and eliminate raw CSS/HTML workarounds.
Requirement: Provide kotlinx.html-like syntax for web developers who prefer working directly with HTML elements.
Motivation: Web developers familiar with HTML find the Compose-like DSL (Row, Column, Box) abstract. An HTML DSL provides familiar semantic elements (Nav, Article, Section, H1, P, Ul, Li) while maintaining full integration with Summon's reactivity and Modifier system.
Approach: Create @Composable wrapper functions for HTML5 elements that delegate to PlatformRenderer.renderHtmlTag().
Target Syntax:
@Composable
fun MyPage() {
Nav(modifier = Modifier().className("navbar")) {
A(href = "/home") { Text("Home") }
A(href = "/about") { Text("About") }
}
Main {
Article {
H1 { Text("Welcome") }
P { Text("Content here") }
Ul {
Li { Text("Item 1") }
Li { Text("Item 2") }
}
}
}
}
New Package: codes.yousef.summon.components.html/
| File | Elements |
|---|---|
HtmlElements.kt |
Header, Nav, Main, Footer, Section, Article, Aside |
TextElements.kt |
H1-H6, P, Blockquote, Pre, Code, Strong, Em, Small, Mark |
ListElements.kt |
Ul, Ol, Li, Dl, Dt, Dd |
TableElements.kt |
Table, Thead, Tbody, Tfoot, Tr, Th, Td, Caption |
InlineElements.kt |
A, Strong, Em, Code, Time, Abbr, Cite, Q, Kbd |
MediaElements.kt |
Figure, Figcaption, Picture, Audio, Video |
Files to Modify:
JvmPlatformRenderer.kt - Expand renderHtmlTag switch to handle all HTML5 tags via kotlinx.htmlseo/routes/SemanticHTML.kt - Deprecate in favor of new packageStandard Element:
@Composable
fun Nav(
modifier: Modifier = Modifier(),
content: @Composable FlowContent.() -> Unit
) {
LocalPlatformRenderer.current.renderHtmlTag("nav", modifier, content)
}
Element with Convenience Parameters:
@Composable
fun A(
href: String,
target: String? = null,
modifier: Modifier = Modifier(),
content: @Composable FlowContent.() -> Unit
) {
val finalModifier = modifier
.attribute("href", href)
.let { if (target != null) it.attribute("target", target) else it }
LocalPlatformRenderer.current.renderHtmlTag("a", finalModifier, content)
}
when statement)createElement(tagName) directly (already works)Estimated Effort: 2-3 days
Requirement: Control application windows programmatically. Technical Specs:
window.open() and PWA display modes.Requirement: Style elements based on interaction state without raw CSS. Technical Specs:
Modifier.hover { ... } applies styles on mouse hover.Modifier.focus { ... } applies styles when element is focused.Modifier.active { ... } applies styles during click/press.Modifier.visited { ... } for link visited state.Modifier()
.backgroundColor(Colors.SURFACE)
.hover { backgroundColor(Colors.SURFACE_HOVER) }
.focus { borderColor(Colors.ACCENT) }
Requirement: Apply styles conditionally based on viewport size without GlobalStyle. Technical Specs:
Modifier.media(minWidth = 768.px) { ... } for responsive styles.Modifier.sm { }, .md { }, .lg { }, .xl { } shortcuts.@media queries with scoped class selectors.Modifier()
.flexDirection(FlexDirection.Column)
.md { flexDirection(FlexDirection.Row) }
.padding(16.px)
.lg { padding(32.px) }
Requirement: Apply CSS rules to descendants without global pollution. Technical Specs:
Modifier.descendant("a") { color(Colors.LINK) } targets child elements.Modifier.child("img") { maxWidth(100.percent) } targets immediate children.Modifier.className("prose").descendant("code") { ... } for specific contexts.Column(
modifier = Modifier()
.className("prose")
.descendant("a") {
color(Colors.LINK)
textDecoration(TextDecoration.Underline)
}
.descendant("a").hover { color(Colors.LINK_HOVER) }
)
Requirement: Native collapsible disclosure widget without RawHtml. Technical Specs:
open parameter for programmatic control.onToggle callback when state changes.Details(
open = isExpanded,
onToggle = { isExpanded = it },
modifier = Modifier().marginBottom(12.px)
) {
Summary(modifier = Modifier().fontWeight(FontWeight.SemiBold)) {
Text("Navigation")
}
// Collapsible content
Column {
NavLink("Home", "/")
NavLink("About", "/about")
}
}
Status: Consolidated into #12 HTML DSL above.
The Nav component is now part of the comprehensive HTML DSL feature, which includes Nav, Header, Footer, Article, Section, and all other semantic HTML5 elements.
Requirement: Application-level menu bar (File, Edit, View). Technical Specs:
Requirement: System-native dialogs for opening and saving files. Technical Specs:
<input type="file">.Requirement: Persistent icon in the OS system tray / status area. Technical Specs:
Requirement: Message passing between different windows/tabs of the same application. Technical Specs:
BroadcastChannel API.Requirement: Drag items from one app window and drop them into another. Technical Specs:
BroadcastChannel or shared storage to coordinate drag state between windows if the platform treats them as separate processes (like browser tabs).Requirement: State persistence that automatically syncs across open windows/tabs. Technical Specs:
remember) that reads/writes to persistent storage.localStorage + storage event listener.Requirement: Support for "Always on Top" mini-windows for arbitrary content. Technical Specs:
