Skip to content

Conversation

@ianjosephwilson
Copy link
Contributor

@ianjosephwilson ianjosephwilson commented Dec 26, 2025

Refine attribute resolution to allow for merging of class and style attrs and smooth out a few edge cases.

Summary

  • Accumulate class values together internally as a dict[str, bool] and output to a str() or None to omit when empty.
  • Accumulate style values together internally as a dict[str, str|None] and output to a str() or None to omit when empty.
  • Expand aria and data as before but do not omit None or False during intermediary expansion.

Major Changes

  • class changes
    • Merge from left to right except when not forced to merge, ie. pass through singleton literal class.
    • If merging is active then always split str() values into a list of classes.
    • Don't allow sequences within sequences, ie. ['btn', ['btn-primary']]
    • Retain False values from dict form to allow classes previously merged to be "toggled" off.
    • Move class handling into processor.py, drop classnames() helper.
  • style changes
    • Merge from left to right except when not forced to merge, ie. pass through singleton literal style.
    • If merging is active then always extract str() values into property name / value dictionary.
    • Retain properties with None value from dict form to allow styles previously merged to be "toggled" off.
  • aria / data changes
    • Do not omit attributes with values of None or False right away so that they may override prior values.
    • Ignore if None to allow for def Comp(img_data=None) type pass-through optional arguments

Types

Just for a quick understanding of how this could look these would be for the non-literal values:

type ClassValueItem = None | bool | str | dict[str, bool]
type ClassValue = ClassValueItem | Sequence[ClassValueItem]
type StyleValue = None | str | dict[str, str | None]
type AriaValue = None | dict[str, object]
type DataValue = None | dict[str, object]

# For example
classes: ClassValue = ["btn", {"btn-primary": True}]
button_t = t'<button class="theme-holiday" class={classes}>Save</button>'
assert str(html(button_t)) == '<button class="theme-holiday btn btn-primary">Save</button>'

@pauleveritt
Copy link
Contributor

Good timing, I'm talking to @koxudaxi about how to extract the rules into a spec for an LSP. If you feel confident these changes are final, I will jot them down.

@ianjosephwilson
Copy link
Contributor Author

Not quite confident yet, I think we'd need to merge them and then try them out a bit and see if they are annoying to use. I'm not sure what format would be best overall since there are multiple things all intermingled together to get to the end result.

@pauleveritt
Copy link
Contributor

@ianjosephwilson Looks like a policy I should get into the specification stuff I was doing for @koxudaxi ... if you can jot some thoughts down in a reply about styles or other attribute edge cases, I'll capture them.

@pauleveritt pauleveritt closed this Jan 2, 2026
@pauleveritt pauleveritt reopened this Jan 2, 2026
@pauleveritt
Copy link
Contributor

Apologies, clicked as my cursor travelled over the Close with comment button

@ianjosephwilson
Copy link
Contributor Author

@pauleveritt Do you mean the rules for how to validate a t-string used by tdom ?

@pauleveritt
Copy link
Contributor

@ianjosephwilson Sorry I though I mentioned in a discussion. @koxudaxi is reviving his PyCharm extension which teaches the IDE the tdom syntax. In particular, autocomplete and validation of props.

As part of that, I did some stuff to decipher the tdom "spec" into a JSON file he could use as the rules.

@ianjosephwilson ianjosephwilson marked this pull request as ready for review January 5, 2026 20:20
@ianjosephwilson
Copy link
Contributor Author

@davepeck Later this week when you get a chance I think this is a strong contender for merging but look it over. I'm going to put another note in the related issue. I just had it drafted because it was stacked on top of the other small PR you merged earlier.

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.

2 participants