feat(flutter_sanity_portable_text): support scoped PortableTextConfig per block#56
feat(flutter_sanity_portable_text): support scoped PortableTextConfig per block#56JoshStrobl wants to merge 2 commits intovyuh-tech:mainfrom
Conversation
… per block PortableTextBlock always reads from the global PortableTextConfig.shared singleton, which means properties like itemPadding cannot be overridden per-instance. I ran into this when I was trying to render blocks inside a Row with CrossAxisAlignment.center. The default 8px bottom itemPadding inflates each block's layout height, causing the cross-axis center to be calculated against the padded height rather than the visible text. I checked using Flutter's debugDumpApp widget tree output, which showed the padding persisting regardless of attempts to temporarily mutate the shared config, since PortableTextBlock.build() reads the config at framework build time, not at widget creation time. Added PortableTextConfig.from() factory constructor that creates a new config instance by copying an existing one with optional overrides. Added an optional config parameter to PortableTextBlock so callers can pass a scoped config instead of relying on the shared singleton. This means the PortableTextBlock styling can more easily differ across multiple instances in an app. Not specify will use the default shared config, so there should be no functional regressions. Just in case I added a bunch of tests.
| factory PortableTextConfig.from( | ||
| PortableTextConfig source, { | ||
| EdgeInsets? itemPadding, | ||
| double? listIndent, | ||
| BulletRenderer? bulletRenderer, | ||
| TextStyle? Function(BuildContext)? baseStyle, | ||
| }) { | ||
| final copy = PortableTextConfig._(); | ||
| copy.styles.addAll(source.styles); | ||
| copy.blocks.addAll(source.blocks); | ||
| copy.blockContainers.addAll(source.blockContainers); | ||
| copy.markDefs.addAll(source.markDefs); | ||
| copy.baseStyle = baseStyle ?? source.baseStyle; | ||
| copy.bulletRenderer = bulletRenderer ?? source.bulletRenderer; | ||
| copy.itemPadding = itemPadding ?? source.itemPadding; | ||
| copy.listIndent = listIndent ?? source.listIndent; | ||
| return copy; | ||
| } |
There was a problem hiding this comment.
Instead of a factory method, you can actually use an instance method with copyFrom, which is the typical Flutter-based pattern, or you can name it apply, where you pass on all the parameters that you want to overwrite. That way, you can use an existing instance and then override from that.
There was a problem hiding this comment.
Fair! I'll get this squared away :)
There was a problem hiding this comment.
@pavanpodila I went ahead and implemented it as a copyWith as there was already an apply function that would simply override the existing properties on the class. The copyWith will return a new PortableTextConfig, using the existing one as a baseline for properties.
So in my app I'd do something like PortableTextConfig.shared.copyWith(...) which provides me the same end result, enabling me to override styling and item padding in a copy without impacting the shared instance.
Does this seem good to you?
There was a problem hiding this comment.
ya that should work for your use case. You will baseline from shared and override with your values.
PortableTextBlock always reads from the global PortableTextConfig.shared singleton, which means properties like itemPadding cannot be overridden per-instance.
I ran into this when I was trying to render blocks inside a Row with CrossAxisAlignment.center. The default 8px bottom itemPadding inflates each block's layout height, causing the cross-axis center to be calculated against the padded height rather than the visible text.
I checked using Flutter's debugDumpApp widget tree output, which showed the padding persisting regardless of attempts to temporarily mutate the shared config, since PortableTextBlock.build() reads the config at framework build time, not at widget creation time.
Added PortableTextConfig.from() factory constructor that creates a new config instance by copying an existing one with optional overrides. Added an optional config parameter to PortableTextBlock so callers can pass a scoped config instead of relying on the shared singleton. This means the PortableTextBlock styling can more easily differ across multiple instances in an app.
Not specify will use the default shared config, so there should be no functional regressions. Just in case I added a bunch of tests.