diff --git a/packages/stream_core_flutter/CHANGELOG.md b/packages/stream_core_flutter/CHANGELOG.md index 0dc6f4bf..315fb1e0 100644 --- a/packages/stream_core_flutter/CHANGELOG.md +++ b/packages/stream_core_flutter/CHANGELOG.md @@ -16,6 +16,7 @@ - `StreamRemoveControl` now meets the 48 dp minimum tap target by default while keeping its 20 dp visible badge anchored to the top-end corner. Exposes `tapTargetSize`, `visualDensity`, and `semanticLabel`, and announces itself as a button to screen readers. - Added `textAlignVertical` to `StreamTextInput` (and `StreamTextInputProps`) for controlling the vertical alignment of the text within the input. - Added `cursorColor`, `cursorErrorColor`, `cursorWidth`, `cursorHeight`, and `cursorRadius` to `StreamTextInputStyle` for customizing the text input cursor. `cursorErrorColor` is applied automatically when `helperState` is `StreamHelperState.error`. `StreamMessageComposerInputField` also honors these cursor properties from the theme. +- Exported `DefaultStreamEmoji` so consumers can compose with or wrap the default emoji rendering when overriding via `StreamComponentFactory`. ### 🐞 Fixed @@ -26,6 +27,7 @@ - Changed `StreamTextInput` default `textCapitalization` to `TextCapitalization.sentences`. - Updated `StreamReactionPicker` spacing to match the Figma specification. - Updated `StreamStepper` button style to match the Figma specification. +- `StreamEmoji` now pins its primary `fontFamily` to the platform's native emoji font (Apple Color Emoji on iOS/macOS, Segoe UI Emoji on Windows, Noto Color Emoji elsewhere) so the existing per-platform `fontSize` correction lines up with the font that actually renders the glyph. `fontFamilyFallback` is unchanged. ### 💥 Breaking Changes diff --git a/packages/stream_core_flutter/lib/src/components.dart b/packages/stream_core_flutter/lib/src/components.dart index 6b25d117..3696cb64 100644 --- a/packages/stream_core_flutter/lib/src/components.dart +++ b/packages/stream_core_flutter/lib/src/components.dart @@ -1,5 +1,5 @@ export 'components/accessories/stream_audio_waveform.dart'; -export 'components/accessories/stream_emoji.dart' hide DefaultStreamEmoji; +export 'components/accessories/stream_emoji.dart'; export 'components/accessories/stream_file_type_icon.dart' hide DefaultStreamFileTypeIcon; export 'components/avatar/stream_avatar.dart' hide DefaultStreamAvatar; export 'components/avatar/stream_avatar_group.dart' hide DefaultStreamAvatarGroup; diff --git a/packages/stream_core_flutter/lib/src/components/accessories/stream_emoji.dart b/packages/stream_core_flutter/lib/src/components/accessories/stream_emoji.dart index 17bb1cf6..14dce883 100644 --- a/packages/stream_core_flutter/lib/src/components/accessories/stream_emoji.dart +++ b/packages/stream_core_flutter/lib/src/components/accessories/stream_emoji.dart @@ -324,6 +324,21 @@ class _UnicodeEmojiWidget extends StatelessWidget { _ => size * _kNotoEmojiScale, }; + // Pin the primary [fontFamily] to the platform's native emoji font so the + // [fontSize] correction above lines up with the font that actually renders + // the glyph. [fontFamilyFallback] still covers cases where the primary + // font is unavailable. + // + // On web, leave [fontFamily] as null and let [fontFamilyFallback] resolve: + // CanvasKit bundles Noto Color Emoji and the HTML renderer defers to the + // browser, so a fixed primary name would lie about what actually renders. + final fontFamily = switch (platform) { + _ when kIsWeb => null, + .iOS || .macOS => 'Apple Color Emoji', + .windows => 'Segoe UI Emoji', + _ => 'Noto Color Emoji', + }; + // Both fonts produce a [Text] whose layout is larger than the visible glyph — Apple Color // Emoji adds whitespace above, below, and to the right; Noto has similar extra metrics. // See: @@ -351,6 +366,7 @@ class _UnicodeEmojiWidget extends StatelessWidget { ), style: TextStyle( fontSize: fontSize, + fontFamily: fontFamily, decoration: .none, // Commonly available fallback fonts for emoji rendering. fontFamilyFallback: const [