Skip to content

Commit f2f3628

Browse files
authored
Merge branch 'main' into dependency/dotnet/global-json-9.0.310
2 parents f2c2b3d + 389b9ca commit f2f3628

File tree

6 files changed

+248
-59
lines changed

6 files changed

+248
-59
lines changed

components/MarkdownTextBlock/samples/MarkdownTextBlock.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,4 @@ Try typing markdown and see it rendered in real-time:
3838
## Custom theme sample
3939
Try different styling options for all markdown elements with a custom theme:
4040

41-
> [!Sample MarkdownTextBlockCustomThemeSample]
42-
41+
> [!Sample MarkdownTextBlockCustomThemeSample]

components/MarkdownTextBlock/samples/MarkdownTextBlockCustomThemeSample.xaml.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ This sample demonstrates the **custom theming** capabilities of the `MarkdownTex
4040
4141
The image above automatically scales to respect the max width setting while maintaining its aspect ratio. Text continues to flow seamlessly below it.
4242
43+
![Shortcut Conflict](https://devblogs.microsoft.com/commandline/wp-content/uploads/sites/33/2025/09/ShortcutConflict.png)
44+
4345
## Code Blocks
4446
4547
```csharp

components/MarkdownTextBlock/src/MarkdownThemes.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ public sealed class MarkdownThemes : DependencyObject
4343

4444
public FontWeight H1FontWeight { get; set; } = FontWeights.SemiBold;
4545

46-
public FontWeight H2FontWeight { get; set; } = FontWeights.Normal;
46+
public FontWeight H2FontWeight { get; set; } = FontWeights.SemiBold;
4747

48-
public FontWeight H3FontWeight { get; set; } = FontWeights.Normal;
48+
public FontWeight H3FontWeight { get; set; } = FontWeights.SemiBold;
4949

50-
public FontWeight H4FontWeight { get; set;} = FontWeights.Normal;
50+
public FontWeight H4FontWeight { get; set;} = FontWeights.SemiBold;
5151

52-
public FontWeight H5FontWeight { get; set; } = FontWeights.Normal;
52+
public FontWeight H5FontWeight { get; set; } = FontWeights.SemiBold;
5353

54-
public FontWeight H6FontWeight { get; set; } = FontWeights.Normal;
54+
public FontWeight H6FontWeight { get; set; } = FontWeights.SemiBold;
5555

5656
public Thickness H1Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
5757
public Thickness H2Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
@@ -60,14 +60,14 @@ public sealed class MarkdownThemes : DependencyObject
6060
public Thickness H5Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
6161
public Thickness H6Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
6262

63-
public Brush BorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
63+
public Brush BorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
6464

65-
public Brush TableHeadingBackground { get; set; } = Extensions.GetAccentColorBrush(Windows.UI.ViewManagement.UIColorType.AccentLight3);
65+
public Brush TableHeadingBackground { get; set; } = (Brush)Application.Current.Resources["CardBackgroundFillColorDefaultBrush"];
6666

67-
public Brush InlineCodeBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
67+
public Brush InlineCodeBackground { get; set; } = (Brush)Application.Current.Resources["CardBackgroundFillColorSecondaryBrush"];
6868
public Brush InlineCodeForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
6969

70-
public Brush InlineCodeBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
70+
public Brush InlineCodeBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
7171

7272
public Thickness InlineCodeBorderThickness { get; set; } = new (1);
7373

@@ -79,12 +79,12 @@ public sealed class MarkdownThemes : DependencyObject
7979

8080
public FontWeight InlineCodeFontWeight { get; set; } = FontWeights.Normal;
8181

82-
public FontWeight BoldFontWeight { get; set; } = FontWeights.Bold;
82+
public FontWeight BoldFontWeight { get; set; } = FontWeights.SemiBold;
8383

8484
// Legacy parity properties (new)
8585
// Code block styling
86-
public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
87-
public Brush CodeBlockBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
86+
public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["CardBackgroundFillColorSecondaryBrush"];
87+
public Brush CodeBlockBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
8888
public Thickness CodeBlockBorderThickness { get; set; } = new Thickness(1);
8989
public Thickness CodeBlockPadding { get; set; } = new Thickness(8);
9090
public Thickness CodeBlockMargin { get; set; } = new Thickness(0, 8, 0, 8);
@@ -93,23 +93,23 @@ public sealed class MarkdownThemes : DependencyObject
9393
public CornerRadius CodeBlockCornerRadius { get; set; } = new CornerRadius(4);
9494

9595
// Horizontal rule
96-
public Brush HorizontalRuleBrush { get; set; } = new SolidColorBrush(Colors.Gray);
96+
public Brush HorizontalRuleBrush { get; set; } = (Brush)Application.Current.Resources["DividerStrokeColorDefaultBrush"];
9797
public double HorizontalRuleThickness { get; set; } = 1.0;
9898
public Thickness HorizontalRuleMargin { get; set; } = new Thickness(0, 12, 0, 12);
9999

100100
// Link styling
101-
public Brush LinkForeground { get; set; } = (Brush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"] ?? new SolidColorBrush(Colors.DodgerBlue);
101+
public Brush LinkForeground { get; set; } = (Brush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"];
102102

103103
// Paragraph / list
104104
public Thickness ParagraphMargin { get; set; } = new Thickness(0, 8, 0, 8);
105105
public double ParagraphLineHeight { get; set; } = 0; // 0 = default
106106
public double ListBulletSpacing { get; set; } = 4; // spaces after bullet
107-
public double ListGutterWidth { get; set; } = 30; // indent delta per level
107+
public double ListGutterWidth { get; set; } = 32; // indent delta per level
108108
public Thickness ListMargin { get; set; } = new Thickness(0, 4, 0, 4);
109109

110110
// Quote styling
111111
public Brush QuoteBackground { get; set; } = new SolidColorBrush(Colors.Transparent);
112-
public Brush QuoteBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
112+
public Brush QuoteBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
113113
public Thickness QuoteBorderThickness { get; set; } = new Thickness(4, 0, 0, 0);
114114
public Brush QuoteForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
115115
public Thickness QuoteMargin { get; set; } = new Thickness(0, 4, 0, 4);
@@ -122,12 +122,12 @@ public sealed class MarkdownThemes : DependencyObject
122122
public Stretch ImageStretch { get; set; } = Stretch.Uniform;
123123

124124
// Table styling
125-
public Brush TableBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
125+
public Brush TableBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
126126
public double TableBorderThickness { get; set; } = 1;
127127
public Thickness TableCellPadding { get; set; } = new Thickness(4);
128-
public Thickness TableMargin { get; set; } = new Thickness(0, 10, 0, 10);
128+
public Thickness TableMargin { get; set; } = new Thickness(0, 8, 0, 8);
129129

130130
// YAML / not currently used - placeholders for parity
131-
public Brush YamlBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
131+
public Brush YamlBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
132132
public Thickness YamlBorderThickness { get; set; } = new Thickness(1);
133133
}

components/MarkdownTextBlock/src/TextElements/MyImage.cs

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,31 @@ private async void LoadImage(object sender, RoutedEventArgs e)
9292
if (_loaded) return;
9393
try
9494
{
95+
// Track whether we have valid natural dimensions to constrain against
96+
bool hasNaturalWidth = false;
97+
bool hasNaturalHeight = false;
98+
9599
if (_imageProvider != null && _imageProvider.ShouldUseThisProvider(_uri.AbsoluteUri))
96100
{
97101
_image = await _imageProvider.GetImage(_uri.AbsoluteUri);
98102
_container.Child = _image;
103+
104+
// Capture natural dimensions as max constraints from the provider image
105+
// Then clear fixed Width/Height so images can shrink responsively
106+
if (_image.Width > 0 && !double.IsNaN(_image.Width) && !double.IsInfinity(_image.Width))
107+
{
108+
_image.MaxWidth = _image.Width;
109+
_image.Width = double.NaN; // Clear fixed width to allow shrinking
110+
hasNaturalWidth = true;
111+
}
112+
if (_image.Height > 0 && !double.IsNaN(_image.Height) && !double.IsInfinity(_image.Height))
113+
{
114+
_image.MaxHeight = _image.Height;
115+
_image.Height = double.NaN; // Clear fixed height to allow shrinking
116+
hasNaturalHeight = true;
117+
}
118+
119+
_loaded = true;
99120
}
100121
else
101122
{
@@ -137,53 +158,50 @@ private async void LoadImage(object sender, RoutedEventArgs e)
137158
await bitmap.SetSourceAsync(stream);
138159
}
139160
_image.Source = bitmap;
140-
_image.Width = bitmap.PixelWidth == 0 ? bitmap.DecodePixelWidth : bitmap.PixelWidth;
141-
_image.Height = bitmap.PixelHeight == 0 ? bitmap.DecodePixelHeight : bitmap.PixelHeight;
161+
// Don't set fixed Width/Height - let layout system handle it
162+
// Store natural dimensions for MaxWidth/MaxHeight constraints
163+
double naturalWidth = bitmap.PixelWidth == 0 ? bitmap.DecodePixelWidth : bitmap.PixelWidth;
164+
double naturalHeight = bitmap.PixelHeight == 0 ? bitmap.DecodePixelHeight : bitmap.PixelHeight;
142165

166+
// Use natural size as max constraint so image doesn't upscale
167+
if (naturalWidth > 0)
168+
{
169+
_image.MaxWidth = naturalWidth;
170+
hasNaturalWidth = true;
171+
}
172+
if (naturalHeight > 0)
173+
{
174+
_image.MaxHeight = naturalHeight;
175+
hasNaturalHeight = true;
176+
}
143177
}
144178

145179
_loaded = true;
146180
}
147181

148-
// Determine the actual image dimensions
149-
double actualWidth = _precedentWidth != 0 ? _precedentWidth : _image.Width;
150-
double actualHeight = _precedentHeight != 0 ? _precedentHeight : _image.Height;
151-
152-
// Apply max constraints and calculate the final size
153-
// When using Uniform stretch with max constraints, we need to calculate
154-
// the actual rendered size to avoid gaps
155-
double finalWidth = actualWidth;
156-
double finalHeight = actualHeight;
157-
158-
bool hasMaxWidth = _themes.ImageMaxWidth > 0;
159-
bool hasMaxHeight = _themes.ImageMaxHeight > 0;
160-
161-
if (hasMaxWidth || hasMaxHeight)
182+
// Apply precedent (markdown-specified) dimensions if provided
183+
// Precedent always takes priority and sets a known dimension
184+
if (_precedentWidth != 0)
162185
{
163-
double scaleX = hasMaxWidth && actualWidth > _themes.ImageMaxWidth
164-
? _themes.ImageMaxWidth / actualWidth
165-
: 1.0;
166-
double scaleY = hasMaxHeight && actualHeight > _themes.ImageMaxHeight
167-
? _themes.ImageMaxHeight / actualHeight
168-
: 1.0;
169-
170-
// For Uniform stretch, use the smaller scale to maintain aspect ratio
171-
if (_themes.ImageStretch == Stretch.Uniform || _themes.ImageStretch == Stretch.UniformToFill)
172-
{
173-
double uniformScale = Math.Min(scaleX, scaleY);
174-
finalWidth = actualWidth * uniformScale;
175-
finalHeight = actualHeight * uniformScale;
176-
}
177-
else
178-
{
179-
// For other stretch modes, apply constraints independently
180-
finalWidth = actualWidth * scaleX;
181-
finalHeight = actualHeight * scaleY;
182-
}
186+
_image.MaxWidth = _precedentWidth;
187+
hasNaturalWidth = true;
188+
}
189+
if (_precedentHeight != 0)
190+
{
191+
_image.MaxHeight = _precedentHeight;
192+
hasNaturalHeight = true;
183193
}
184194

185-
_image.Width = finalWidth;
186-
_image.Height = finalHeight;
195+
// Apply theme constraints - only if we have a known dimension to constrain
196+
// This prevents theme constraints from enlarging images with unknown natural size
197+
if (_themes.ImageMaxWidth > 0 && hasNaturalWidth && _themes.ImageMaxWidth < _image.MaxWidth)
198+
{
199+
_image.MaxWidth = _themes.ImageMaxWidth;
200+
}
201+
if (_themes.ImageMaxHeight > 0 && hasNaturalHeight && _themes.ImageMaxHeight < _image.MaxHeight)
202+
{
203+
_image.MaxHeight = _themes.ImageMaxHeight;
204+
}
187205
_image.Stretch = _themes.ImageStretch;
188206
}
189207
catch (Exception) { }

0 commit comments

Comments
 (0)