Problem
Several components have a property called prefix, which collides with the native HTML prefix attribute (an RDFa global attribute). This causes multiple problems:
-
Attribute interception in JSX: The conventional way to set component props is via attributes in JSX. A prop called prefix intercepts the native prefix attribute — consumers cannot set the native attribute even if they want to, because the component claims it.
-
Type conflicts: The component's prefix prop type clashes with the native HTML prefix attribute type in TypeScript/JSX, forcing unnecessary type casts in consuming code. (We have examples of this in lime-crm-building-blocks.)
-
Reflected attribute collision: When the prop is reflected to an attribute (which it currently is on all affected components), it writes to the native prefix attribute on the element, which could cause unexpected behavior.
Simply stopping reflection (removing reflect: true) would not solve problems 1 and 2 — the property name itself is the issue.
suffix does not have the same native attribute collision, but should be renamed in the same pass for consistency.
Affected components
| Component |
Current props |
Reflected? |
limel-circular-progress |
prefix, suffix |
Yes |
limel-info-tile |
prefix, suffix |
Yes |
limel-input-field |
prefix, suffix |
Yes |
Additionally, the InfoTileProgress interface has prefix and suffix properties (used for the embedded circular progress in info-tile).
Proposed solution
Rename to valuePrefix / valueSuffix (attribute: value-prefix / value-suffix).
This keeps the semantic meaning clear (these are prefixes/suffixes of the displayed value, like $, €, %, kr) while completely avoiding the native attribute collision.
Migration plan
Phase 1: Add new properties, deprecate old ones (non-breaking)
- Add
valuePrefix and valueSuffix properties to all three components
- Add
valuePrefix and valueSuffix to the InfoTileProgress interface
- In component logic: prefer new prop, fall back to old prop (e.g.
this.valuePrefix ?? this.prefix)
- Mark old
prefix/suffix props with @deprecated in JSDoc
- Add a
console.warn at runtime if the deprecated props are used, guiding consumers to the new names
- Update all examples and documentation to use the new property names
Phase 2: Migrate all known consumers
- Update all Lime-owned codebases that use these components (Lime CRM, etc.)
- Update all known configs that reference these properties (this is the hard part — configs may use attribute names in templates)
- Coordinate with teams to ensure all deployments are updated
Phase 3: Remove deprecated properties (breaking — major version)
- Remove old
prefix/suffix props from all three components
- Remove old properties from
InfoTileProgress interface
- This is a breaking change and must go in a major version bump
Notes
- Phase 1 should be a single PR with a
feat: commit (new properties) — no breaking change
- Phase 2 is the long tail and depends on how many consumers exist
- Phase 3 should only happen after sufficient deprecation period and when we are confident all consumers have migrated
- The deprecation console warnings from Phase 1 will help us track whether old props are still in use
Problem
Several components have a property called
prefix, which collides with the native HTMLprefixattribute (an RDFa global attribute). This causes multiple problems:Attribute interception in JSX: The conventional way to set component props is via attributes in JSX. A prop called
prefixintercepts the nativeprefixattribute — consumers cannot set the native attribute even if they want to, because the component claims it.Type conflicts: The component's
prefixprop type clashes with the native HTMLprefixattribute type in TypeScript/JSX, forcing unnecessary type casts in consuming code. (We have examples of this in lime-crm-building-blocks.)Reflected attribute collision: When the prop is reflected to an attribute (which it currently is on all affected components), it writes to the native
prefixattribute on the element, which could cause unexpected behavior.Simply stopping reflection (removing
reflect: true) would not solve problems 1 and 2 — the property name itself is the issue.suffixdoes not have the same native attribute collision, but should be renamed in the same pass for consistency.Affected components
limel-circular-progressprefix,suffixlimel-info-tileprefix,suffixlimel-input-fieldprefix,suffixAdditionally, the
InfoTileProgressinterface hasprefixandsuffixproperties (used for the embedded circular progress in info-tile).Proposed solution
Rename to
valuePrefix/valueSuffix(attribute:value-prefix/value-suffix).This keeps the semantic meaning clear (these are prefixes/suffixes of the displayed value, like
$,€,%,kr) while completely avoiding the native attribute collision.Migration plan
Phase 1: Add new properties, deprecate old ones (non-breaking)
valuePrefixandvalueSuffixproperties to all three componentsvaluePrefixandvalueSuffixto theInfoTileProgressinterfacethis.valuePrefix ?? this.prefix)prefix/suffixprops with@deprecatedin JSDocconsole.warnat runtime if the deprecated props are used, guiding consumers to the new namesPhase 2: Migrate all known consumers
Phase 3: Remove deprecated properties (breaking — major version)
prefix/suffixprops from all three componentsInfoTileProgressinterfaceNotes
feat:commit (new properties) — no breaking change