Skip to content

Commit

Permalink
Implement proper Markdown link styling
Browse files Browse the repository at this point in the history
We weren't using the TextLinkStyles provided by the LinkAnnotation API,
and as a result, our links weren't stateful. We were also not properly
setting a disabled colour — now we do.

Also changed, we force the Markdown text to not be focusable, even if it
is clickable, since we don't want it to get focused. Now only links are
focused while tabbing through Markdown.

This also removes some testing harness left around from #425, and that
we don't need anymore.

Note: links should have a border around them when they are focused, but
that's not possible with the Compose APIs. What we do instead is show
a subtle background color,
taken from the ActionButtons' hover and pressed states, for our focused
and pressed states, respectively.
  • Loading branch information
rock3r committed Jul 18, 2024
1 parent 4dcf63b commit 229b2da
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 69 deletions.
7 changes: 6 additions & 1 deletion markdown/core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,17 @@ public final class org/jetbrains/jewel/markdown/rendering/InlineMarkdownRenderer
public final class org/jetbrains/jewel/markdown/rendering/InlinesStyling {
public static final field $stable I
public static final field Companion Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling$Companion;
public fun <init> (Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Z)V
public fun <init> (Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Z)V
public fun equals (Ljava/lang/Object;)Z
public final fun getEmphasis ()Landroidx/compose/ui/text/SpanStyle;
public final fun getInlineCode ()Landroidx/compose/ui/text/SpanStyle;
public final fun getInlineHtml ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLink ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLinkDisabled ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLinkFocused ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLinkHovered ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLinkPressed ()Landroidx/compose/ui/text/SpanStyle;
public final fun getLinkVisited ()Landroidx/compose/ui/text/SpanStyle;
public final fun getRenderInlineHtml ()Z
public final fun getStrongEmphasis ()Landroidx/compose/ui/text/SpanStyle;
public final fun getTextStyle ()Landroidx/compose/ui/text/TextStyle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public fun Markdown(
}
} else {
Column(
modifier.semantics { rawMarkdown = markdown },
modifier = modifier.semantics { rawMarkdown = markdown },
verticalArrangement = Arrangement.spacedBy(markdownStyling.blockVerticalSpacing),
) {
for (block in markdownBlocks) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.AnnotatedString.Builder
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import org.commonmark.renderer.text.TextContentRenderer
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
Expand Down Expand Up @@ -40,6 +41,15 @@ public open class DefaultInlineMarkdownRenderer(
enabled: Boolean,
onUrlClicked: ((String) -> Unit)? = null,
) {
// TODO move to InlineMarkdown to avoid recomputing after #416 is done
val linkStyling =
TextLinkStyles(
styling.link,
styling.linkFocused,
styling.linkHovered,
styling.linkPressed,
)

for (child in inlineMarkdown) {
when (child) {
is InlineMarkdown.Text -> append(child.nativeNode.literal)
Expand All @@ -62,18 +72,21 @@ public open class DefaultInlineMarkdownRenderer(
}

is InlineMarkdown.Link -> {
withStyles(styling.link.withEnabled(enabled), child) {
val index =
if (enabled) {
val destination = it.nativeNode.destination
val destination = child.nativeNode.destination
val link =
LinkAnnotation.Clickable(
tag = destination,
linkInteractionListener = { _ -> onUrlClicked?.invoke(destination) },
styles = linkStyling,
)
pushLink(link)
} else {
pushStyle(styling.linkDisabled)
}
appendInlineMarkdownFrom(it.children, styling, enabled)
}
appendInlineMarkdownFrom(child.children, styling, enabled)
pop(index)
}

is InlineMarkdown.Code -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.isSpecified
Expand Down Expand Up @@ -141,11 +142,13 @@ public open class DefaultMarkdownBlockRenderer(

Text(
modifier =
Modifier.clickable(
interactionSource = interactionSource,
indication = null,
onClick = onTextClick,
),
Modifier
.focusProperties { canFocus = false }
.clickable(
interactionSource = interactionSource,
indication = null,
onClick = onTextClick,
),
text = renderedContent,
style = mergedStyle,
)
Expand Down Expand Up @@ -212,6 +215,7 @@ public open class DefaultMarkdownBlockRenderer(
Text(
text = renderedContent,
style = mergedStyle,
modifier = Modifier.focusProperties { canFocus = false },
)

if (underlineWidth > 0.dp && underlineColor.isSpecified) {
Expand Down Expand Up @@ -295,6 +299,7 @@ public open class DefaultMarkdownBlockRenderer(
color = styling.numberStyle.color.takeOrElse { LocalContentColor.current },
modifier =
Modifier
.focusProperties { canFocus = false }
.widthIn(min = styling.numberMinWidth)
.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
textAlign = styling.numberTextAlign,
Expand Down Expand Up @@ -333,7 +338,9 @@ public open class DefaultMarkdownBlockRenderer(
text = styling.bullet.toString(),
style = styling.bulletStyle,
color = styling.bulletStyle.color.takeOrElse { LocalContentColor.current },
modifier = Modifier.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
modifier =
Modifier.focusProperties { canFocus = false }
.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
)

Spacer(Modifier.width(styling.bulletContentGap))
Expand Down Expand Up @@ -384,7 +391,7 @@ public open class DefaultMarkdownBlockRenderer(
style = styling.editorTextStyle,
color = styling.editorTextStyle.color.takeOrElse { LocalContentColor.current },
modifier =
Modifier
Modifier.focusProperties { canFocus = false }
.padding(styling.padding)
.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
)
Expand Down Expand Up @@ -418,7 +425,9 @@ public open class DefaultMarkdownBlockRenderer(
text = block.content,
style = styling.editorTextStyle,
color = styling.editorTextStyle.color.takeOrElse { LocalContentColor.current },
modifier = Modifier.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
modifier =
Modifier.focusProperties { canFocus = false }
.pointerHoverIcon(PointerIcon.Default, overrideDescendants = true),
)

if (block.mimeType != null && styling.infoPosition.verticalAlignment == Alignment.Bottom) {
Expand Down Expand Up @@ -447,6 +456,7 @@ public open class DefaultMarkdownBlockRenderer(
text = infoText,
style = textStyle,
color = textStyle.color.takeOrElse { LocalContentColor.current },
modifier = Modifier.focusProperties { canFocus = false },
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ public class InlinesStyling(
public val textStyle: TextStyle,
public val inlineCode: SpanStyle,
public val link: SpanStyle,
public val linkDisabled: SpanStyle,
public val linkFocused: SpanStyle,
public val linkHovered: SpanStyle,
public val linkPressed: SpanStyle,
public val linkVisited: SpanStyle,
public val emphasis: SpanStyle,
public val strongEmphasis: SpanStyle,
public val inlineHtml: SpanStyle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ public final class org/jetbrains/jewel/intui/markdown/bridge/BridgeProvideMarkdo
}

public final class org/jetbrains/jewel/intui/markdown/bridge/styling/BridgeMarkdownStylingKt {
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling$Companion;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Z)Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling;
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling$Companion;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Z)Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling;
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Indented;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Fenced;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code;
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H1;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H2;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H3;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H4;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H5;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H6;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading;
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Ordered;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Unordered;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List;
public static final fun create (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Paragraph$Companion;Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Paragraph;
public static synthetic fun create$default (Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling$Companion;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;ZILjava/lang/Object;)Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling;
public static synthetic fun create$default (Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling$Companion;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/SpanStyle;ZILjava/lang/Object;)Lorg/jetbrains/jewel/markdown/rendering/InlinesStyling;
public static synthetic fun create$default (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Indented;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code$Fenced;ILjava/lang/Object;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Code;
public static synthetic fun create$default (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H1;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H2;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H3;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H4;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H5;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading$H6;ILjava/lang/Object;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$Heading;
public static synthetic fun create$default (Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Companion;Landroidx/compose/ui/text/TextStyle;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Ordered;Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List$Unordered;ILjava/lang/Object;)Lorg/jetbrains/jewel/markdown/rendering/MarkdownStyling$List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,19 +371,37 @@ public fun InlinesStyling.Companion.create(
color = JBUI.CurrentTheme.Link.Foreground.ENABLED.toComposeColor(),
textDecoration = TextDecoration.Underline,
).toSpanStyle(),
linkDisabled: SpanStyle = link.copy(color = JBUI.CurrentTheme.Link.Foreground.DISABLED.toComposeColor()),
linkHovered: SpanStyle = link.copy(color = JBUI.CurrentTheme.Link.Foreground.HOVERED.toComposeColor()),
linkFocused: SpanStyle =
link.copy(
color = JBUI.CurrentTheme.Link.Foreground.ENABLED.toComposeColor(),
background = JBUI.CurrentTheme.ActionButton.hoverBackground().toComposeColor(),
),
linkPressed: SpanStyle =
link.copy(
color = JBUI.CurrentTheme.Link.Foreground.PRESSED.toComposeColor(),
background = JBUI.CurrentTheme.ActionButton.pressedBackground().toComposeColor(),
),
linkVisited: SpanStyle = link.copy(color = JBUI.CurrentTheme.Link.Foreground.VISITED.toComposeColor()),
emphasis: SpanStyle = textStyle.copy(fontStyle = FontStyle.Italic).toSpanStyle(),
strongEmphasis: SpanStyle = textStyle.copy(fontWeight = FontWeight.Bold).toSpanStyle(),
inlineHtml: SpanStyle = textStyle.toSpanStyle(),
renderInlineHtml: Boolean = false,
): InlinesStyling =
InlinesStyling(
textStyle,
inlineCode,
link,
emphasis,
strongEmphasis,
inlineHtml,
renderInlineHtml,
textStyle = textStyle,
inlineCode = inlineCode,
link = link,
linkDisabled = linkDisabled,
linkHovered = linkHovered,
linkFocused = linkFocused,
linkPressed = linkPressed,
linkVisited = linkVisited,
emphasis = emphasis,
strongEmphasis = strongEmphasis,
inlineHtml = inlineHtml,
renderInlineHtml = renderInlineHtml,
)

private val defaultTextStyle
Expand Down
Loading

0 comments on commit 229b2da

Please sign in to comment.