From 3536e23d049be29ebb6081a11dd525c2a99a7e33 Mon Sep 17 00:00:00 2001 From: Sean Holbert Date: Wed, 22 Jul 2026 21:17:56 -0700 Subject: [PATCH] fix(input): derive heading bold from the base font on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A heading with a bold fontWeight (the shared default) built its font with UIFont systemFontOfSize:weight:, discarding the editor's base font family — custom-font editors got system-font headings. Android already folds heading weight into the current typeface (InputHeadingSpan), so iOS now derives the bold face from the base font via a font-descriptor trait, falling back to the system font only when the family has no bold face. Non-bold explicit weights keep the previous system-font behavior. Co-Authored-By: Claude Fable 5 --- .../ios/input/ENRMInputFormatter.mm | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/react-native-enriched-markdown/ios/input/ENRMInputFormatter.mm b/packages/react-native-enriched-markdown/ios/input/ENRMInputFormatter.mm index ad66ac48b..b671b5962 100644 --- a/packages/react-native-enriched-markdown/ios/input/ENRMInputFormatter.mm +++ b/packages/react-native-enriched-markdown/ios/input/ENRMInputFormatter.mm @@ -112,8 +112,22 @@ - (UIFont *)headingFontForLevel:(NSInteger)level } NSString *weightString = _headingFontWeights[level]; - UIFont *font = weightString.length > 0 ? [UIFont systemFontOfSize:size weight:ENRMFontWeightFromString(weightString)] - : [_baseFont fontWithSize:size]; + UIFont *font; + if (weightString.length > 0 && ENRMFontWeightFromString(weightString) >= UIFontWeightBold) { + // Derive the bold face of the base (content) font — matching Android's + // InputHeadingSpan, which folds heading weight into the current typeface — + // so a custom editor font keeps its family in headings. Fall back to the + // system font only when the family has no bold face. + UIFont *sized = [_baseFont fontWithSize:size]; + UIFontDescriptor *descriptor = [sized.fontDescriptor + fontDescriptorWithSymbolicTraits:sized.fontDescriptor.symbolicTraits | UIFontDescriptorTraitBold]; + font = descriptor ? [UIFont fontWithDescriptor:descriptor size:size] + : [UIFont systemFontOfSize:size weight:UIFontWeightBold]; + } else if (weightString.length > 0) { + font = [UIFont systemFontOfSize:size weight:ENRMFontWeightFromString(weightString)]; + } else { + font = [_baseFont fontWithSize:size]; + } _headingFontCache[level] = font; return font; }