Use case
ContextVariant accepts an arbitrary bool Function(BuildContext) and therefore retains identity equality. When a pure style factory constructs the same logical custom variant on each invocation, the resulting styles compare unequal and their variants do not share merge identity.
This surfaced in conceptadev/remix#121: CheckboxStyler.onIndeterminate created the same logical variant on every call, but each instance contained a new closure. conceptadev/remix#124 works around it by reusing a single variant instance.
Downstream custom variants currently have two choices:
- retain a shared singleton; or
- subclass
ContextVariant and repeat operator ==/hashCode boilerplate already implemented independently by Mix's built-in variants.
Using ContextVariant.key as equality is unsafe because Mix documents it as a human-readable diagnostic label and deliberately keeps it out of semantic merge identity.
Relevant implementation:
Proposal
Provide an opt-in API for custom context variants with explicit value semantics while preserving the identity behavior of the existing ContextVariant constructor.
One possible API is an abstract base class:
abstract base class ValueContextVariant extends ContextVariant {
const ValueContextVariant(super.key, super.shouldApply);
List<Object?> get props => const [];
@override
bool operator ==(Object other) =>
identical(this, other) ||
other.runtimeType == runtimeType &&
other is ValueContextVariant &&
propsEquals(props, other.props);
@override
int get hashCode => propsHash(runtimeType, props);
}
Proposed downstream usage:
final class IndeterminateVariant extends ValueContextVariant {
const IndeterminateVariant()
: super('on_indeterminate', _shouldApply);
static bool _shouldApply(BuildContext context) {
return CheckboxState.maybeOf(context)?.isChecked == null;
}
}
The exact API could instead be a constructor/factory accepting an explicit semantic identity. The important requirements are:
- existing directly constructed
ContextVariants retain identity semantics;
- custom variants can opt into consistent equality and hash codes;
- semantic identity is separate from the diagnostic
key;
- different variant types or value properties cannot collide accidentally;
VariantStyle equality and merge behavior honor the custom value semantics;
- tests cover equal instances, unequal properties, identical diagnostic keys with distinct identities, and unchanged built-in variant behavior.
Use case
ContextVariantaccepts an arbitrarybool Function(BuildContext)and therefore retains identity equality. When a pure style factory constructs the same logical custom variant on each invocation, the resulting styles compare unequal and their variants do not share merge identity.This surfaced in
conceptadev/remix#121:CheckboxStyler.onIndeterminatecreated the same logical variant on every call, but each instance contained a new closure.conceptadev/remix#124works around it by reusing a single variant instance.Downstream custom variants currently have two choices:
ContextVariantand repeatoperator ==/hashCodeboilerplate already implemented independently by Mix's built-in variants.Using
ContextVariant.keyas equality is unsafe because Mix documents it as a human-readable diagnostic label and deliberately keeps it out of semantic merge identity.Relevant implementation:
ContextVariantand its diagnostic keyProposal
Provide an opt-in API for custom context variants with explicit value semantics while preserving the identity behavior of the existing
ContextVariantconstructor.One possible API is an abstract base class:
Proposed downstream usage:
The exact API could instead be a constructor/factory accepting an explicit semantic identity. The important requirements are:
ContextVariants retain identity semantics;key;VariantStyleequality and merge behavior honor the custom value semantics;