jongacnik / gr8

Customizable, functional css utilities
MIT License
174 stars 11 forks source link

Idiomatic hover states #21

Open s3ththompson opened 6 years ago

s3ththompson commented 6 years ago

Is the the most idiomatic way to generate rules for hover states?

var textTransformHover = {
  prop: 'text-decoration',
  vals: {
    'u-hover': 'underline',
    'o-hover': 'overline',
    'lt-hover': 'line-through',
    'n-hover': 'none'
  },
  tail: ':hover'
}

It seems like something like this might be a little cleaner...

var textTransformHover = {
  prop: 'text-transform',
  vals: [
    'uppercase',
    'lowercase',
    'capitalize',
    'none'
  ],
  tail: ':hover',
  tailSuffix: '-hover' // or tailModifier: '-hover'
}
jongacnik commented 6 years ago

I wonder if we could solve this by accepting an object as tail:

{
  prop: 'text-transform',
  vals: [
    'uppercase',
    'lowercase'
  ],
  tail: {
    '-hover': ':hover'
  }
}

The key is appended to the className, the value is appended to the entire selector. If only a string is provided, it works as-is.

💡 But... Now that I'm seeing it, this brings up an interesting option of a slight api change. Where tail is actually just embraced as a pseudo-class option:

{
  prop: 'text-transform',
  vals: [
    'uppercase',
    'lowercase'
  ],
  pseudo: ':hover'
}

With this, we could assume we'll want a modifier to the classname, so we could generate that from the selector. e.g: -h from :hover so classNames end up looking like:

.ttu-h:hover{}
.ttl-h:hover{}

And of course we'd still accept object syntax to allow custom modifier, like -hover.

This is a breaking change, but tbh I've not been totally happy with the gr8-util api, so I'm open to this conversation about what the object could look like.

s3ththompson commented 6 years ago

oh yeah, these are both pretty clean. Wouldn't you still need tail for clearfixes? in that case, pseudo could be an addition rather than a breaking change.

I think it could also be nice to be able to do something like this:

{
  prop: 'text-transform',
  vals: [
    'uppercase',
    'lowercase'
  ],
  pseudo: [ 'hover', 'active', 'focus']
}

Nit, but it seems slightly unnecessary (although maybe it reads clearer?) to include the colon on the arguments to pseudo.

And then the convention would be first dash comes from join, second dash comes from pseudoclass?

jongacnik commented 6 years ago

✨ pseudo as addition and dropping the colon are both good calls.

Yes, I think the pseudo modifiers should always be appended with a - for clarity. The join option would specifically apply to how the property and value abbreviations are joined. So you could imagine something like:

{
  prop: { fc: 'color' },
  vals: {
    red: '#f00',
    blue: '#00f'
  },
  join: '-',
  pseudo: 'hover'
}
.fc-red-h:hover { color: #f00 }
.fc-blue-h:hover { color: #00f }

Gonna try to schedule myself to make these changes to gr8-util this weekend.

jongacnik commented 6 years ago

@s3ththompson opened https://github.com/jongacnik/gr8-util/pull/2 in gr8-util for this. Maybe you can take a peek before we merge this over here

jongacnik commented 6 years ago

Adding a prefix option will make the pseudo option extra handy https://github.com/jongacnik/gr8-util/issues/3