Skip to content

Gs/transition by property model#2

Open
augyg wants to merge 27 commits intomasterfrom
gs/transition-by-property-model
Open

Gs/transition by property model#2
augyg wants to merge 27 commits intomasterfrom
gs/transition-by-property-model

Conversation

@augyg
Copy link
Owner

@augyg augyg commented Feb 19, 2026

No description provided.

augyg added 27 commits February 19, 2026 14:41
Add core WithTransition module that enables property-specific transitions
rather than global transitions. Key features:

- WithTransition wrapper type pairs values with optional TransitionConfig
- AutoWrap typeclass for backwards compatibility with existing code
- Builder pattern: withTransition, withTiming, withDelay
- All-at-once function: withTransitionAll
- Rendering helpers: renderWithTransitionTW, compileWithTransitionTW
- Simplified TransitionConfig (no WhenTW) to avoid illegal nesting
- Preserved TransitionConfigGlobal for backwards compatibility

Transitions now apply to individual property values across screen sizes
and pseudo-classes (hover, focus, etc.) instead of globally.
Update background color, opacity, and shadow to support per-value
transitions:

- _bgColor: WhenTW Color -> WhenTW (WithTransition Color)
- _bgOpacity: WhenTW Int -> WhenTW (WithTransition Int)
- _shadow: WhenTW BoxShadow -> WhenTW (WithTransition BoxShadow)
- _transition: TransitionConfig -> TransitionConfigGlobal

Remove local renderWithTransitionTW and compileWithTransitionTW
definitions in favor of importing from Classh.WithTransition module.

Update ShowTW and CompileStyle instances to use the new helpers with
proper TransitionProperty inference (Transition_Colors for colors,
Transition_Opacity for opacity, etc.).
Update all border properties to support per-value transitions:

Border Color (BorderColorSides):
- All fields: WhenTW Color -> WhenTW (WithTransition Color)
- Add FlexibleInstances pragma for SetSides instance

Border Width (BorderWidthSides):
- All fields: WhenTW BorderWidth -> WhenTW (WithTransition BorderWidth)
- Add FlexibleInstances pragma for SetSides instance

Border Radius (BorderRadiusCorners):
- All fields: WhenTW BorderRadius' -> WhenTW (WithTransition BorderRadius')
- Add FlexibleInstances pragma for SetSides instance

Remove local renderWithTransitionTW definitions, use centralized version
from Classh.WithTransition module.
Update padding and margin properties to support per-value transitions:

BoxPadding:
- All fields: WhenTW TWSize -> WhenTW (WithTransition TWSize)
- Add FlexibleInstances pragma for SetSides instance
- Remove local renderWithTransitionTW/compileWithTransitionTW

BoxMargin:
- All fields: WhenTW TWSize -> WhenTW (WithTransition TWSize)
- Add FlexibleInstances pragma for SetSides instance
- Remove local renderWithTransitionTW definition

Both modules now use centralized rendering helpers from
Classh.WithTransition module.
Update all sizing-related properties to support per-value transitions:

BoxSizing:
- _width: WhenTW TWSizeOrFraction -> WhenTW (WithTransition TWSizeOrFraction)
- _height: WhenTW TWSizeOrFraction -> WhenTW (WithTransition TWSizeOrFraction)

BoxSizingConstraint:
- _widthC: WhenTW DimensionConstraint -> WhenTW (WithTransition DimensionConstraint)
- _heightC: WhenTW DimensionConstraint -> WhenTW (WithTransition DimensionConstraint)

SizingBand:
- Remove local renderWithTransitionTW definition
- Use centralized version from Classh.WithTransition

This enables smooth transitions for width, height, min/max constraints
across responsive breakpoints and pseudo-classes.
Update RingConfig to support per-value transitions:

- _ringWidth: WhenTW RingWidth -> WhenTW (WithTransition RingWidth)
- _ringColor: WhenTW Color -> WhenTW (WithTransition Color)
- _ringOpacity: WhenTW Int -> WhenTW (WithTransition Int)

Remove local renderWithTransitionTW definition, use centralized version
from Classh.WithTransition module.

Enables smooth transitions for focus rings with proper transition property
inference (Transition_All for width, Transition_Colors for color,
Transition_Opacity for opacity).
…ility

Update all setter operators to use AutoWrap typeclass:

- (.~~): Single value setter now auto-wraps plain values in WithTransition
- (.|~): List-based setter now auto-wraps plain values in WithTransition
- (.~+): Append setter now auto-wraps plain values in WithTransition
- (.~^): New explicit transition setter for [(TWCondition, WithTransition a)]

This enables backwards compatibility, allowing existing code like:
  bgColor .~~ purple
to work seamlessly with new WithTransition types, while also supporting:
  bgColor .~~ (purple `withTransition` Duration_300)

The AutoWrap typeclass automatically wraps bare values when needed.
Update all shorthand setter type signatures to match new WithTransition
types:

Border shortcuts:
- br_*, bw_*, bc_*: Now use WhenTW (WithTransition X)

Sizing shortcuts:
- w, h, width', height': WhenTW (WithTransition TWSizeOrFraction)
- maxW, minW, maxH, minH: WhenTW (WithTransition DimensionConstraint)

Spacing shortcuts:
- mt, mb, ml, mr, mx, my, m: WhenTW (WithTransition TWSize)
- pt, pb, pl, pr, px, py, p: WhenTW (WithTransition TWSize)

All shortcuts now support both plain values (auto-wrapped) and explicit
transitions via the AutoWrap typeclass.
Add Classh.WithTransition to exposed-modules in ClasshSS.cabal.

Also add documentation comment to WhenTW module explaining that
WithTransition rendering helpers are defined in a separate module
to avoid circular dependencies.
Add TransitionTest.hs demonstrating various transition usage patterns:

- Test 1: Backwards compatibility with plain values (no transitions)
- Test 2: Using (.~^) operator with noTransition and withTransition
- Test 3: Builder pattern with chaining (withTransition, withTiming, withDelay)
- Test 4: All-at-once style with withTransitionAll

Tests cover responsive breakpoints (sm), pseudo-classes (hover, focus),
and various transition configurations (duration, timing, delay).
The AutoWrap typeclass is no longer needed as we've replaced it with
a more robust approach using SetConstant, SetResponsive, and AddResponsive
typeclasses that properly handle type inference.
Replace AutoWrap with SetConstant, SetResponsive, and AddResponsive
typeclasses that use type families (UnwrapType) to enable proper type
inference from lens types.

This allows expressions like `h .~~ pct 100` to work without type
annotations - the compiler infers that pct should return TWSizeOrFraction
based on the height lens type.

Key changes:
- Add SetConstant typeclass for (.~~) operator
- Add SetResponsive typeclass for (.|~) operator
- Add AddResponsive typeclass for (.|+) operator
- Use UnwrapType family to extract unwrapped types
- For WithTransition fields, automatically wrap values with noTransition
- For plain fields, use values directly
- Remove global _transition field from BoxConfig
- Update transition rendering to use arbitrary value syntax: [transition:property_duration_timing_delay]
- Add transitionPropertyToCSSName and transitionTimingToCSSName helpers
- Fix timing function conversion (in-out vs inout)
- Add functional dependency to SetSides class for better type inference
- Change from INCOHERENT to OVERLAPPING/OVERLAPPABLE pragmas in Setters

All transitions are now per-attribute using the WithTransition wrapper type,
generating Tailwind arbitrary values like:
hover:[transition:background-color,border-color,color,fill,stroke_300ms_in-out_0ms]
- Add TransitionTest.hs with 4 transition pattern tests
- Add ComprehensiveTest.hs with 11 property tests covering all ClasshSS features
- Add GenerateHTMLTest.hs with visual HTML generation for browser testing
- Add 10+ unique transition configurations across 6 responsive breakpoints
- Include tests for: durations (75ms-1000ms), timing functions (linear/ease-in/ease-out/ease-in-out), delays (0ms-1000ms)
- Generate test-output.html with rainbow spectrum (Red→Orange→Yellow→Green→Blue→Purple) for easy visual verification
- Automatically opens generated HTML in Chrome for manual testing

All tests pass (15/15 total) and verify the arbitrary transition syntax works correctly.
The google-chrome-stable executable doesn't exist on all systems.
Now the test just generates the HTML file and prompts the user to open it manually.
Add comprehensive transform support to BoxConfig with all Tailwind v3 transform properties:

Transform properties added:
- Rotate: standard values (0°, 1°, 2°, 3°, 6°, 12°, 45°, 90°, 180°) + custom
- Scale: standard values (0, 50, 75, 90, 95, 100, 105, 110, 125, 150) + custom
- Translate: X/Y axes with TWSize values, fractions, px, full, and custom CSS sizes
- Skew: X/Y axes with standard values (0°, 1°, 2°, 3°, 6°, 12°) + custom
- Transform Origin: all 9 standard positions (center, corners, edges) + custom

All transforms support smooth transitions via withTransition, allowing animated
transform changes on hover, focus, and other states.

Changes:
- Add TransformConfig with all transform properties as fields
- Add transform field to BoxConfig
- Create comprehensive test suite (TransformTest.hs) with 15 tests
- Fix name collision with Control.Lens.transform by hiding it
- Fix variable shadowing in Classh.hs (transform -> mutation)
- Add -Wall -Werror to test suites for stricter compile-time checks
- Clean up unused imports in test files
- Update README with layout philosophy (no flexbox by design)

All tests pass (15/15 transform tests, plus existing test suites).
- Rewrite README for clarity
- Add EXAMPLE.md with usage patterns
- Add MIGRATION_FROM_TAILWIND.md guide
- Add GradientColor type (SolidColor | GradientColor)
- Add GradientDirection, ColorStop, StopPosition types
- Add helper functions: solidColor, linearGradient, linearGradientVia, etc.
- Support stop positions (from-10%, via-30%, to-90%)
- Fix responsive/state prefix application for multi-class gradients
- Add gradient-test suite (13 tests)

BREAKING CHANGE: bgColor now requires GradientColor type.
Use solidColor wrapper for simple colors:
  bgColor .~~ solidColor (Blue C500)
- Wrap all bgColor values with solidColor helper
- All test suites passing (transition, generate-html, comprehensive, gradient)
Add support for colors with embedded opacity using Tailwind's
/opacity syntax (e.g., bg-blue-500/50, bg-[#1e40af]/87).

- Add ColorWithOpacity data type with color and opacity fields
- Add withOpacity helper function
- Add ShowTW instance rendering color/opacity format
- Add explicit module exports
Extend gradient API with opacity support for both solid colors
and gradient color stops.

Solid colors with opacity:
- Add SolidColorWithOpacity constructor to GradientColor
- Add solidColorOpacity helper for bg-[#hex]/opacity syntax

Gradient color stops with opacity:
- Add _stop_opacity field to ColorStop
- Add stopWithOpacity and stopAtWithOpacity helpers
- Update renderStop to include /opacity in output

This enables patterns like:
  bgColor .~~ solidColorOpacity (hex "4E366C") 87
  linearGradientPos To_BR (stopAtWithOpacity (hex "281C40") 90 0) ...
- Change _cwo_opacity from Int to Maybe Int (Nothing = fully opaque)
- Add 'color' smart constructor for Color -> ColorWithOpacity
- Update ShowTW instance to render opacity with Tailwind /n syntax
- This enables consistent opacity support across all color-using APIs
- Remove redundant SolidColorWithOpacity constructor from GradientColor
- SolidColor now takes ColorWithOpacity directly
- Simplify ColorStop to use ColorWithOpacity instead of separate opacity field
- Add solidColorOpacity and stopWithOpacity helper functions
- Update renderBgColorRaw for simplified GradientColor type
- Update BorderColorConfig fields to use ColorWithOpacity
- Update SetSides instance for border color
- Update RingConfig ringColor to use ColorWithOpacity
- Update TextConfigTW text_color to use ColorWithOpacity
- Update TextDecorationConfigTW textDec_color to use ColorWithOpacity
- Update Shorthand bc* lenses for new type signatures
- Add testSolidColorOpacity: solid color with /87 opacity
- Add testStopWithOpacity: gradient stop with opacity
- Add testStopAtWithOpacity: positioned stop with opacity
- Add testGradientMixedOpacity: mixed opacity and non-opacity stops
- Wrap bare Color values with 'color' helper in ComprehensiveTest
- Wrap bare Color values with 'color' helper in GenerateHTMLTest
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