Skip to content

refactor: generate Mix styling layer with mix_generator#98

Merged
leoafarias merged 5 commits into
mainfrom
leoafarias/mix-codegen-simplify
Jul 13, 2026
Merged

refactor: generate Mix styling layer with mix_generator#98
leoafarias merged 5 commits into
mainfrom
leoafarias/mix-codegen-simplify

Conversation

@leoafarias

Copy link
Copy Markdown
Collaborator

Intent

Replace ~1,450 lines of hand-written Mix Spec/Styler boilerplate (copyWith, lerp, resolve, merge, props, debugFillProperties) with mix_generator output — the same codegen Mix 2.x uses for its own specs. Net −1,160 hand-written lines in the styling layer; what remains by hand is only what carries meaning (field declarations, constructor defaults, SlideSpec.of, toStyle()).

Architecture

Two tiers, split for a reason proven empirically before committing:

  • Leaf specs (alert type, blockquote, checkbox, codeblock, list, table): fully spec-driven — @MixableSpec generates the entire *Styler class, including a fluent API these classes never had (per-field setters, field factories, onHovered/onFocused variant helpers).
  • Aggregators (slide.dart, markdown_alert.dart): generated spec mixin + hand-written styler (fields + two constructors) on the legacy @MixableStyler mixin. Forced: nested custom specs need @MixableField(setterType: MarkdownAlertStyler), but annotation type arguments cannot reference same-package generated classes — build phases hide them from the resolver and the generator silently degrades to value semantics (replacement instead of Mix merge accumulation). Hand-written constructors can reference generated classes freely, so the hybrid keeps correct Prop.maybeMix semantics. Rationale recorded in build.yaml and both file headers.

Breaking changes

  • Canonical styler names are now *Styler (SlideStyler, MarkdownAlertStyler, ...) per the Mix idiom; old *Style names remain as typedef aliases.
  • TextStyle-typed styler params are now TextStyleMix (wrap existing values with TextStyleMix.value(...)); these fields gain Mix field-wise merge semantics through the style cascade.

Also in this PR

  • Drop vestigial custom_lint dev dep (no plugin configured anywhere; it pinned analyzer <9 and hard-blocked mix_generator).
  • Changelog the MarkdownText* deprecation that shipped unchangelogged in fix: apply SlideSpec styles to inline Markdown #97.
  • Root CHANGELOG.md was a drifted copy of the package changelog; it now points at per-package changelogs.

Impacted packages

superdeck (styling, deck, markdown, tests), demo, playground, plugins/pdf (rename only), docs.

Verification

  • melos run analyze (dart analyze + DCM, fatal warnings) green across all packages
  • flutter test: superdeck 654/654, pdf plugin 27/27 — goldens included
  • .g.dart output regenerates byte-identically from a clean build cache in a single pass, with zero degraded setters (grep-verified Prop.maybeMix on all nested spec fields)

Follow-up

mix_generator could derive nested StyleSpec<XSpec> setter types by the same XSpec → XStyler naming convention it already uses for class names — pure string derivation, no analyzer resolution — which would let the two aggregators go fully spec-driven and delete every setterType: annotation. Upstream PR against btwld/mix incoming.

Replace ~1,450 lines of hand-written Spec/Styler boilerplate (copyWith,
lerp, resolve, merge, props, debugFillProperties) with mix_generator
output, the same codegen Mix 2.x uses for its own specs.

- Leaf specs (alert type, blockquote, checkbox, codeblock, list, table)
  are fully spec-driven: @MixableSpec generates the *Styler class.
- Aggregators (slide, markdown_alert) nest same-package generated
  stylers, which @MixableField(setterType:) cannot reference during
  generation, so their stylers stay hand-written on the legacy
  @MixableStyler mixin path (fields + constructors only).
- Canonical styler names follow the Mix idiom (*Styler); old *Style
  names remain as typedef aliases.
- BREAKING: TextStyle-typed styler params are now TextStyleMix and gain
  Mix field-wise merge semantics.
- Stylers gain generated fluent setters, field factories, and
  widget-state variant helpers (onHovered, onFocused, ...).
- Drop vestigial custom_lint dev dep (no plugin configured; it pinned
  analyzer <9 and blocked mix_generator).
- Changelog the MarkdownText* deprecation shipped in #97.

Impacted packages: superdeck (styling, deck, markdown, tests), demo,
playground, plugins/pdf (rename only), docs.

Verified: melos run analyze (dart + DCM) green; superdeck 654 tests and
pdf 27 tests pass incl. goldens; .g.dart output byte-identical when
regenerated from a clean build cache.
The root CHANGELOG.md was a drifted copy of packages/superdeck's (stale
at 1.0.0, missing the Unreleased section). Per-package changelogs are
the source of truth in this monorepo; make the root file a pointer so
it cannot drift again.
@docs-page

docs-page Bot commented Jul 10, 2026

Copy link
Copy Markdown

To preview the documentation for this pull request, visit the following URL:

docs.page/btwld/superdeck~98

Documentation is deployed and generated using docs.page

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 6f6cd87):

https://superdeck-dev--pr98-leoafarias-mix-codeg-fofbz161.web.app

(expires Tue, 11 Aug 2026 17:54:24 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: bd68fc230762285849207e7e120aaf87cd4ca2f9

@leoafarias

Copy link
Copy Markdown
Collaborator Author

Upstream generator change is up: btwld/mix#961 — once it ships in mix_generator 2.1.2, the two aggregator stylers here (SlideStyler, MarkdownAlertStyler) can drop the legacy @MixableStyler path and every @MixableField(setterType:) annotation, going fully spec-driven.

@leoafarias leoafarias merged commit 9915be9 into main Jul 13, 2026
6 checks passed
@leoafarias leoafarias deleted the leoafarias/mix-codegen-simplify branch July 13, 2026 03:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant