-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Problem
Currently, mention styling is determined entirely by the indicator character — all mentions with the same indicator share one style. There's no way to style individual mentions differently based on their state or metadata.
Use case: In our app, we use mentions for template variables (%custom_var% and {{mapping_var}}). Some variables are "pending" (not yet configured by the user) and need to be visually distinct — e.g., orange instead of blue — so users can see at a glance which variables need attention. Since both valid and pending variables share the same indicator, we can't differentiate them with the current API.
Proposed API
A new mentionStyleRules property on htmlStyle that allows declarative, attribute-based style overrides:
<EnrichedTextInput
htmlStyle={{
mention: {
"@": { color: "blue", backgroundColor: "lightblue", textDecorationLine: "none" },
},
mentionStyleRules: [
{
match: { pending: "true" },
style: { color: "orange", backgroundColor: "lightyellow", textDecorationLine: "none" },
},
{
match: { type: "urgent", priority: "high" },
style: { color: "red", backgroundColor: "pink", textDecorationLine: "underline" },
},
],
}}
mentionIndicators={["@"]}
/>When committing a mention with matching attributes:
ref.current?.setMention("@", "John", { pending: "true" });
// → renders with orange style instead of the default blueHow it works
- Each rule has
match(key-value pairs) andstyle(MentionStyleProperties) matchis checked against the mention's attributes (the third arg tosetMention, which are already stored on both iOS and Android)- First matching rule wins; unmatched mentions fall back to indicator-based style
- Fully declarative — no lambdas, serializable over the bridge
Why this design
- No indicator hacking: We tried using separate indicator characters for different states, but indicators are tightly coupled to detection triggers and the native editor displays them as visible prefixes.
- Composable: Multiple rules for different conditions, each with independent match criteria.
- Backwards compatible: No rules = existing behavior. The
attributesparameter ofsetMentionis already supported but unused for styling. - No codegen changes: Rules are embedded in the existing
mentiondict (which isUnsafeMixed) and extracted on the native side.
Implementation
I have a working iOS implementation in PR #493. Happy to adjust the approach based on feedback. The Android and web implementations would follow the same pattern.
Summary of changes
JS: mentionStyleRules on HtmlStyle, processed in normalizeHtmlStyle (color conversion), embedded as __rules__ in the mention dict for native transport.
iOS native: InputConfig stores rules and exposes mentionStylePropsForIndicator:attributes: which deserializes the mention's JSON attributes and matches against rules. MentionStyle.mm uses the attribute-aware lookup.