diff --git a/components/MarkdownTextBlock/src/HtmlWriter.cs b/components/MarkdownTextBlock/src/HtmlWriter.cs
index 1b2557992..40c4b932c 100644
--- a/components/MarkdownTextBlock/src/HtmlWriter.cs
+++ b/components/MarkdownTextBlock/src/HtmlWriter.cs
@@ -49,6 +49,7 @@ public static void WriteHtml(WinUIRenderer renderer, HtmlNodeCollection nodes)
else
{
var myHyperlink = new MyHyperlink(node, renderer.Config.BaseUrl);
+ myHyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground;
myHyperlink.ClickEvent += (sender, e) =>
{
var uri = sender.NavigateUri;
diff --git a/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs b/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs
index 8dae4cad1..06ad510cc 100644
--- a/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs
+++ b/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs
@@ -108,6 +108,23 @@ public partial class MarkdownTextBlock
typeof(MarkdownTextBlock),
new PropertyMetadata(null));
+ ///
+ /// Identifies the dependency property.
+ ///
+ private static readonly DependencyProperty IsTextSelectionEnabledProperty = DependencyProperty.Register(
+ nameof(IsTextSelectionEnabled),
+ typeof(bool),
+ typeof(MarkdownTextBlock),
+ new PropertyMetadata(false, OnIsTextSelectionEnabledChanged));
+
+ private static void OnIsTextSelectionEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is MarkdownTextBlock mtb && mtb._document != null)
+ {
+ mtb._document.RichTextBlock.IsTextSelectionEnabled = (bool)e.NewValue;
+ }
+ }
+
public MarkdownConfig Config
{
get => (MarkdownConfig)GetValue(ConfigProperty);
@@ -203,4 +220,13 @@ public MarkdownDocument? MarkdownDocument
get => (MarkdownDocument)GetValue(MarkdownDocumentProperty);
private set => SetValue(MarkdownDocumentProperty, value);
}
+
+ ///
+ /// Gets or sets a value indicating whether text selection is enabled.
+ ///
+ public bool IsTextSelectionEnabled
+ {
+ get => (bool)GetValue(IsTextSelectionEnabledProperty);
+ set => SetValue(IsTextSelectionEnabledProperty, value);
+ }
}
diff --git a/components/MarkdownTextBlock/src/MarkdownThemes.cs b/components/MarkdownTextBlock/src/MarkdownThemes.cs
index d29ec9bf5..ad0317cfd 100644
--- a/components/MarkdownTextBlock/src/MarkdownThemes.cs
+++ b/components/MarkdownTextBlock/src/MarkdownThemes.cs
@@ -34,9 +34,14 @@ public sealed class MarkdownThemes : DependencyObject
public double H6FontSize { get; set; } = 12;
- public Brush HeadingForeground { get; set; } = Extensions.GetAccentColorBrush();
+ public Brush H1Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Brush H2Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Brush H3Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Brush H4Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Brush H5Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Brush H6Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
- public FontWeight H1FontWeight { get; set; } = FontWeights.Bold;
+ public FontWeight H1FontWeight { get; set; } = FontWeights.SemiBold;
public FontWeight H2FontWeight { get; set; } = FontWeights.Normal;
@@ -48,10 +53,10 @@ public sealed class MarkdownThemes : DependencyObject
public FontWeight H6FontWeight { get; set; } = FontWeights.Normal;
- public Thickness H1Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
- public Thickness H2Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
- public Thickness H3Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
- public Thickness H4Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
+ public Thickness H1Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
+ public Thickness H2Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
+ public Thickness H3Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
+ public Thickness H4Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
public Thickness H5Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
public Thickness H6Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
@@ -73,4 +78,54 @@ public sealed class MarkdownThemes : DependencyObject
public double InlineCodeFontSize { get; set; } = 10;
public FontWeight InlineCodeFontWeight { get; set; } = FontWeights.Normal;
+
+ // Legacy parity properties (new)
+ // Code block styling
+ public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
+ public Brush CodeBlockBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
+ public Thickness CodeBlockBorderThickness { get; set; } = new Thickness(1);
+ public Thickness CodeBlockPadding { get; set; } = new Thickness(8);
+ public Thickness CodeBlockMargin { get; set; } = new Thickness(0, 8, 0, 8);
+ public FontFamily CodeBlockFontFamily { get; set; } = new FontFamily("Consolas");
+ public Brush CodeBlockForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public CornerRadius CodeBlockCornerRadius { get; set; } = new CornerRadius(4);
+
+ // Horizontal rule
+ public Brush HorizontalRuleBrush { get; set; } = new SolidColorBrush(Colors.Gray);
+ public double HorizontalRuleThickness { get; set; } = 1.0;
+ public Thickness HorizontalRuleMargin { get; set; } = new Thickness(0, 12, 0, 12);
+
+ // Link styling
+ public Brush LinkForeground { get; set; } = (Brush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"] ?? new SolidColorBrush(Colors.DodgerBlue);
+
+ // Paragraph / list
+ public Thickness ParagraphMargin { get; set; } = new Thickness(0, 8, 0, 8);
+ public double ParagraphLineHeight { get; set; } = 0; // 0 = default
+ public double ListBulletSpacing { get; set; } = 4; // spaces after bullet
+ public double ListGutterWidth { get; set; } = 30; // indent delta per level
+ public Thickness ListMargin { get; set; } = new Thickness(0, 4, 0, 4);
+
+ // Quote styling
+ public Brush QuoteBackground { get; set; } = new SolidColorBrush(Colors.Transparent);
+ public Brush QuoteBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
+ public Thickness QuoteBorderThickness { get; set; } = new Thickness(4, 0, 0, 0);
+ public Brush QuoteForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
+ public Thickness QuoteMargin { get; set; } = new Thickness(0, 4, 0, 4);
+ public Thickness QuotePadding { get; set; } = new Thickness(4);
+ public CornerRadius QuoteCornerRadius { get; set; } = new CornerRadius(4);
+
+ // Image styling
+ public double ImageMaxWidth { get; set; } = 0; // 0 = no constraint
+ public double ImageMaxHeight { get; set; } = 0;
+ public Stretch ImageStretch { get; set; } = Stretch.Uniform;
+
+ // Table styling
+ public Brush TableBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
+ public double TableBorderThickness { get; set; } = 1;
+ public Thickness TableCellPadding { get; set; } = new Thickness(4);
+ public Thickness TableMargin { get; set; } = new Thickness(0, 10, 0, 10);
+
+ // YAML / not currently used - placeholders for parity
+ public Brush YamlBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
+ public Thickness YamlBorderThickness { get; set; } = new Thickness(1);
}
diff --git a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs
index 08b290ea1..c514c45de 100644
--- a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs
+++ b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs
@@ -43,11 +43,14 @@ protected override void Write(WinUIRenderer renderer, LinkInline link)
// Optionally restore later; not needed unless reused.
}
};
+ // Apply link foreground to nested RichTextBlock content
+ // (Handled in MyHyperlinkButton initialization via MarkdownConfig.Default for now)
renderer.Push(myHyperlinkButton);
}
else
{
var hyperlink = new MyHyperlink(link, renderer.Config.BaseUrl);
+ hyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground;
hyperlink.ClickEvent += (sender, e) =>
{
var uri = sender.NavigateUri;
diff --git a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs
index 139db86d9..bdc1b3210 100644
--- a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs
+++ b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs
@@ -14,7 +14,7 @@ protected override void Write(WinUIRenderer renderer, QuoteBlock obj)
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
if (obj == null) throw new ArgumentNullException(nameof(obj));
- var quote = new MyQuote(obj);
+ var quote = new MyQuote(obj, renderer.Config.Themes);
renderer.Push(quote);
renderer.WriteChildren(obj);
diff --git a/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs b/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs
index c60109e0d..f7502b9e3 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs
@@ -24,11 +24,15 @@ public MyCodeBlock(CodeBlock codeBlock, MarkdownConfig config)
_paragraph = new Paragraph();
var container = new InlineUIContainer();
var border = new Border();
- border.Background = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
- border.Padding = _config.Themes.Padding;
- border.Margin = _config.Themes.InternalMargin;
- border.CornerRadius = _config.Themes.CornerRadius;
+ border.Background = _config.Themes.CodeBlockBackground;
+ border.BorderBrush = _config.Themes.CodeBlockBorderBrush;
+ border.BorderThickness = _config.Themes.CodeBlockBorderThickness;
+ border.Padding = _config.Themes.CodeBlockPadding;
+ border.Margin = _config.Themes.CodeBlockMargin;
+ border.CornerRadius = _config.Themes.CodeBlockCornerRadius;
var richTextBlock = new RichTextBlock();
+ richTextBlock.FontFamily = _config.Themes.CodeBlockFontFamily;
+ richTextBlock.Foreground = _config.Themes.CodeBlockForeground;
#if false
if (codeBlock is FencedCodeBlock fencedCodeBlock)
diff --git a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs
index 43ceae327..ab8a85392 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs
@@ -60,7 +60,15 @@ private void SetHProperties(int level)
5 => _config.Themes.H5FontSize,
_ => _config.Themes.H6FontSize,
};
- _paragraph.Foreground = _config.Themes.HeadingForeground;
+ _paragraph.Foreground = level switch
+ {
+ 1 => _config.Themes.H1Foreground,
+ 2 => _config.Themes.H2Foreground,
+ 3 => _config.Themes.H3Foreground,
+ 4 => _config.Themes.H4Foreground,
+ 5 => _config.Themes.H5Foreground,
+ _ => _config.Themes.H6Foreground,
+ };
_paragraph.FontWeight = level switch
{
1 => _config.Themes.H1FontWeight,
diff --git a/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs b/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs
index bb4feea3d..fdbb9ad6d 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs
@@ -41,6 +41,7 @@ public MyHyperlink(LinkInline linkInline, string? baseUrl)
_hyperlink = new Hyperlink()
{
NavigateUri = Extensions.GetUri(url, baseUrl),
+ Foreground = MarkdownConfig.Default.Themes.LinkForeground
};
}
@@ -52,6 +53,7 @@ public MyHyperlink(HtmlNode htmlNode, string? baseUrl)
_hyperlink = new Hyperlink()
{
NavigateUri = Extensions.GetUri(url, baseUrl),
+ Foreground = MarkdownConfig.Default.Themes.LinkForeground
};
}
diff --git a/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs b/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs
index 927083ac4..594d6fd66 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs
@@ -65,7 +65,8 @@ private MyHyperlinkButton(string? url, string? baseUrl, HtmlNode? htmlNode, Link
_flowDoc = new MyFlowDocument(_linkInline!);
}
_inlineUIContainer.Child = _hyperLinkButton;
- _hyperLinkButton.Content = _flowDoc.RichTextBlock;
+ _flowDoc.RichTextBlock.Foreground = MarkdownConfig.Default.Themes.LinkForeground;
+ _hyperLinkButton.Content = _flowDoc.RichTextBlock;
}
public void AddChild(IAddChild child)
diff --git a/components/MarkdownTextBlock/src/TextElements/MyImage.cs b/components/MarkdownTextBlock/src/TextElements/MyImage.cs
index 4a2e35df8..64b94fd84 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyImage.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyImage.cs
@@ -150,6 +150,18 @@ private async void LoadImage(object sender, RoutedEventArgs e)
{
_image.Height = _precedentHeight;
}
+
+ // Apply theme constraints if provided
+ var themes = MarkdownConfig.Default.Themes;
+ if (themes.ImageMaxWidth > 0)
+ {
+ _image.MaxWidth = themes.ImageMaxWidth;
+ }
+ if (themes.ImageMaxHeight > 0)
+ {
+ _image.MaxHeight = themes.ImageMaxHeight;
+ }
+ _image.Stretch = themes.ImageStretch;
}
catch (Exception) { }
}
diff --git a/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs b/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs
index 25ef22618..65ffbf5a0 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs
@@ -26,10 +26,15 @@ public MyParagraph(ParagraphBlock paragraphBlock, WinUIRenderer renderer)
// Lists are plain Paragraph_s, one per item.
// This is so that you can select across list items.
- Thickness margin = new Thickness(0, 8, 0, 8); // renderer.Config.Themes.BlockMargin;
+ var themes = renderer.Config.Themes;
+ Thickness margin = themes.ParagraphMargin;
int bulletCount = renderer.GetListBulletCount();
- margin.Left += 30 * bulletCount;
+ margin.Left += themes.ListGutterWidth * bulletCount;
_paragraph.Margin = margin;
+ if (themes.ParagraphLineHeight > 0)
+ {
+ _paragraph.LineHeight = themes.ParagraphLineHeight;
+ }
if (bulletCount != 0)
{
@@ -37,7 +42,7 @@ public MyParagraph(ParagraphBlock paragraphBlock, WinUIRenderer renderer)
Run bulletRun = new Run { Text = bullet + "\t" };
_paragraph.Inlines.Add(bulletRun);
- _paragraph.TextIndent = -30;
+ _paragraph.TextIndent = -themes.ListGutterWidth;
}
}
diff --git a/components/MarkdownTextBlock/src/TextElements/MyQuote.cs b/components/MarkdownTextBlock/src/TextElements/MyQuote.cs
index 077a22eb7..6633c5bdb 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyQuote.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyQuote.cs
@@ -11,15 +11,17 @@ internal class MyQuote : IAddChild
private Paragraph _paragraph;
private MyFlowDocument _flowDocument;
private QuoteBlock _quoteBlock;
+ private MarkdownThemes _themes;
public TextElement TextElement
{
get => _paragraph;
}
- public MyQuote(QuoteBlock quoteBlock)
+ public MyQuote(QuoteBlock quoteBlock, MarkdownThemes themes)
{
_quoteBlock = quoteBlock;
+ _themes = themes;
_paragraph = new Paragraph();
_flowDocument = new MyFlowDocument(quoteBlock);
@@ -30,20 +32,24 @@ public MyQuote(QuoteBlock quoteBlock)
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
var bar = new Grid();
- bar.Width = 4;
- bar.Background = new SolidColorBrush(Colors.Gray);
+ var borderThickness = _themes.QuoteBorderThickness.Left > 0 ? _themes.QuoteBorderThickness.Left : 4;
+ bar.Width = borderThickness;
+ bar.Background = _themes.QuoteBorderBrush ?? new SolidColorBrush(Colors.Gray);
bar.SetValue(Grid.ColumnProperty, 0);
bar.VerticalAlignment = VerticalAlignment.Stretch;
bar.Margin = new Thickness(0, 0, 4, 0);
grid.Children.Add(bar);
- var rightGrid = new Grid();
- rightGrid.Padding = new Thickness(4);
+ var rightGrid = new Grid();
+ rightGrid.Padding = _themes.QuotePadding;
+ rightGrid.Background = _themes.QuoteBackground;
+ rightGrid.CornerRadius = _themes.QuoteCornerRadius;
rightGrid.Children.Add(_flowDocument.RichTextBlock);
+ _flowDocument.RichTextBlock.Foreground = _themes.QuoteForeground;
rightGrid.SetValue(Grid.ColumnProperty, 1);
grid.Children.Add(rightGrid);
- grid.Margin = new Thickness(0, 2, 0, 2);
+ grid.Margin = _themes.QuoteMargin;
inlineUIContainer.Child = grid;
diff --git a/components/MarkdownTextBlock/src/TextElements/MyTable.cs b/components/MarkdownTextBlock/src/TextElements/MyTable.cs
index 423b9fbc8..2cd341cb5 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyTable.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyTable.cs
@@ -29,10 +29,11 @@ public MyTable(Table table, MarkdownThemes themes)
(
column,
table.Count,
- borderThickness: 1,
- themes.BorderBrush,
+ borderThickness: themes.TableBorderThickness,
+ themes.TableBorderBrush ?? themes.BorderBrush,
themes.TableHeadingBackground,
- themes.CornerRadius
+ themes.CornerRadius,
+ themes.TableMargin
);
var inlineUIContainer = new InlineUIContainer();
diff --git a/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs b/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs
index a9ec2634a..1374b7afd 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs
@@ -66,7 +66,8 @@ public MyTableCell(TableCell tableCell, TextAlignment textAlignment, bool isHead
_ => HorizontalAlignment.Left,
};
- _container.Padding = new Thickness(4);
+ // Use themed table cell padding if available
+ _container.Padding = MarkdownConfig.Default.Themes.TableCellPadding;
if (_isHeader)
{
_flowDocument.RichTextBlock.FontWeight = FontWeights.Bold;
diff --git a/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs b/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs
index 585cf304a..687a9398c 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs
@@ -18,13 +18,12 @@ internal partial class MyTableUIElement : Panel
private double[]? _columnWidths;
private double[]? _rowHeights;
- public MyTableUIElement(int columnCount, int rowCount, double borderThickness, Brush borderBrush, Brush headingBrush, CornerRadius cornerRadius)
+ public MyTableUIElement(int columnCount, int rowCount, double borderThickness, Brush borderBrush, Brush headingBrush, CornerRadius cornerRadius, Thickness tableMargin)
{
_columnCount = columnCount;
_rowCount = rowCount;
_borderThickness = borderThickness;
-
- Margin = new Thickness(left: 0, top: 10, right: 0, bottom: 10);
+ Margin = tableMargin;
Children.Add(new Border
{
diff --git a/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs b/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs
index 152b16fb1..771ef37c2 100644
--- a/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs
+++ b/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs
@@ -26,9 +26,10 @@ public MyThematicBreak(ThematicBreakBlock thematicBreakBlock, MarkdownThemes the
Line line = new Line
{
Stretch = Stretch.Fill,
- Stroke = themes.BorderBrush,
+ Stroke = themes.HorizontalRuleBrush ?? themes.BorderBrush,
X2 = 1,
- Margin = new Thickness(0, 12, 0, 12)
+ StrokeThickness = themes.HorizontalRuleThickness,
+ Margin = themes.HorizontalRuleMargin
};
inlineUIContainer.Child = line;
_paragraph.Inlines.Add(inlineUIContainer);