Skip to content

Commit

Permalink
feat(Markdown): Material3 inspired tables
Browse files Browse the repository at this point in the history
  • Loading branch information
wingio committed Jan 18, 2025
1 parent d429ce7 commit 598cd20
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 16 deletions.
66 changes: 62 additions & 4 deletions shared/src/commonMain/moko-resources/assets/markdown/markdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ body {
color: var(--onSurface);
}

themed-picture,
img {
img,
themed-picture {
max-width: 100%;
}

Expand All @@ -52,8 +52,66 @@ a.anchor {
display: none;
}

.highlight pre,
pre {
pre,
.highlight pre {
word-wrap: normal;
white-space: pre;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre,
.markdown-body details {
margin-top: 0;
margin-bottom: 1rem;
}

/* Table */
/* This is based on the table design featured in https://m3.material.io/ */

.markdown-body table a {
word-break: normal;
}

table, table *, pre {
touch-action: pan-x;
}

.markdown-body table {
display: block;
overflow: auto;

width: fit-content; /* Makes sure the table border doesn't extend further than the content */
max-width: 100%;

border-radius: 16px;
border: 0.5px solid var(--outline);
border-spacing: 0;
border-collapse: collapse;
}

.markdown-body table td,
.markdown-body table th { /* All table cells */
padding: 12px 18px;
border-top: 0.5px solid var(--outline);
border-right: 0.5px solid var(--outline);
}

.markdown-body thead:first-child tr:first-child th,
.markdown-body tbody:first-child tr:first-child td {
border-top: 0; /* Prevents cell borders at the top of the table from making the border thicker */
}

.markdown-body tr :last-child {
border-right: 0; /* Prevents cell borders at the end of the table from making the border thicker */
}

.markdown-body thead th { /* Header table cells */
background-color: var(--surfaceContainer);
color: var(--onSurfaceVariant);
font-weight: 500;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@

<style>
/* Colors are injected in order to sync with device theming */
:root {
* {
--primary: $primary$;
--onSurface: $onSurface$;
--onSurfaceVariant: $onSurfaceVariant$;
--surfaceContainer: $surfaceContainer$;
--scrim: $scrim$;
--outline: $outline$;
}
</style>
</head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import cafe.adriel.voyager.core.screen.Screen
import dev.icerock.moko.resources.compose.stringResource
import dev.materii.gloom.Res
import dev.materii.gloom.ui.screen.settings.component.SettingsCategory
import dev.materii.gloom.ui.component.toolbar.LargeToolbar
import dev.icerock.moko.resources.compose.stringResource
import dev.materii.gloom.ui.screen.settings.component.SettingsCategory

class DeveloperSettingsScreen : Screen {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.materii.gloom.ui.util.markdown

import androidx.compose.material3.ColorScheme
import dev.materii.gloom.ui.util.hexCode

object MarkdownUtil {

/**
* Replaces the color variables in the markdown template with the runtime theme colors
*
* @see `shared/src/commonMain/moko-resources/assets/markdown/markdown.html`
*
* @param markdownTemplate The template text where the color variables are, should be lazy loaded at runtime.
* @param isLight Whether or not the theme is designed to be light.
* @param colorScheme The Material3 color scheme used to theme markdown elements
*/
// TODO: Add all m3 colors
fun injectAppTheme(
markdownTemplate: String,
isLight: Boolean,
colorScheme: ColorScheme
): String {
return markdownTemplate // Insert theme colors
.replace("\$primary$", "#" + colorScheme.primary.hexCode)
.replace("\$onSurface$", "#" + colorScheme.onSurface.hexCode)
.replace("\$onSurfaceVariant$", "#" + colorScheme.onSurfaceVariant.hexCode)
.replace("\$surfaceContainer$", "#" + colorScheme.surfaceContainer.hexCode)
.replace("\$scrim$", "#" + colorScheme.scrim.hexCode)
.replace("\$outline$", "#" + colorScheme.outline.hexCode)
.replace("\$theme$", if (isLight) "light" else "dark") // Support the old way of theming images
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import androidx.compose.ui.graphics.luminance
import com.apollographql.apollo.api.http.internal.urlEncode
import com.benasher44.uuid.uuid4
import dev.materii.gloom.Res
import dev.materii.gloom.ui.util.hexCode
import dev.materii.gloom.ui.util.markdown.MarkdownJSMessageHandler
import dev.materii.gloom.ui.util.markdown.MarkdownRequestInterceptor
import dev.materii.gloom.util.LocalLinkHandler
import com.multiplatform.webview.jsbridge.rememberWebViewJsBridge
import com.multiplatform.webview.web.NativeWebView
import com.multiplatform.webview.web.WebView
import com.multiplatform.webview.web.rememberWebViewNavigator
import com.multiplatform.webview.web.rememberWebViewStateWithHTMLData
import dev.icerock.moko.resources.compose.readTextAsState
import dev.materii.gloom.ui.util.markdown.MarkdownUtil
import dev.materii.gloom.util.LocalLinkHandler

private var MarkdownTemplate = "" // Cache the loaded markdown html template
private val PrefersLightRx = "prefers-color-scheme:\\s*light".toRegex(RegexOption.IGNORE_CASE)
Expand All @@ -41,7 +41,7 @@ fun Markdown(
html: String,
modifier: Modifier
) {
val linkHandler = dev.materii.gloom.util.LocalLinkHandler.current
val linkHandler = LocalLinkHandler.current

val messageHandler = MarkdownJSMessageHandler()
val interceptor = MarkdownRequestInterceptor(linkHandler)
Expand Down Expand Up @@ -73,18 +73,18 @@ fun Markdown(
MarkdownTemplate = file ?: ""; MarkdownTemplate
}

val state = rememberWebViewStateWithHTMLData(
data = template // Insert theme colors
.replace("\$primary$", "#" + MaterialTheme.colorScheme.primary.hexCode)
.replace("\$onSurface$", "#" + MaterialTheme.colorScheme.onSurface.hexCode)
.replace("\$theme$", if (isLight) "light" else "dark") // Support the old way of theming images
)
val colorScheme = MaterialTheme.colorScheme
val state = rememberWebViewStateWithHTMLData(data = MarkdownUtil.injectAppTheme(template, isLight, colorScheme))

LaunchedEffect(state.isLoading) {
// See shared/src/commonMain/moko-resources/assets/markdown/markdown.js
if (!state.isLoading) navigator.loadUrl("javascript:gloom.load(\"$id\", \"$markdown\")")
}

LaunchedEffect(markdown) {
navigator.loadUrl("javascript:gloom.load(\"$id\", \"$markdown\")")
}

WebView(
state = state,
navigator = navigator,
Expand Down

0 comments on commit 598cd20

Please sign in to comment.