Skip to content

Commit

Permalink
Change ComponentModifiers style from property to function
Browse files Browse the repository at this point in the history
For example, what used to be:

```
ComponentStyle(...) {
  active = Modifier.color(Colors.Red)
}
```

is now

```
ComponentStyle(...) {
  active {
    Modifier.color(Colors.Red)
  }
}
```

On the surface of it, these feels needlessly verbose, but it future-proofs
us to more complex selectors in the future, such as:

```
ComponentStyle(...) {
  nthChild(4) {
    Modifier.color(Colors.Green)
  }
}
```

This also has the added bonus of communicating that setting modifiers is a
one-way operation. You can set, but you can't get.
  • Loading branch information
bitspittle committed Dec 1, 2021
1 parent 1e7615c commit 732b5b2
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 208 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,23 @@ object Buttons {
val ButtonStyle = ComponentStyle("silk-button") {
val buttonColors = SilkTheme.palettes[colorMode].button

base = Modifier.background(buttonColors.default).clip(Rect(4.px)).styleModifier {
// No selecting text within buttons
userSelect(UserSelect.None)
property("role", "button")
base {
Modifier.background(buttonColors.default).clip(Rect(4.px)).styleModifier {
// No selecting text within buttons
userSelect(UserSelect.None)
property("role", "button")
}
}
hover = Modifier.background(buttonColors.hover).styleModifier {
cursor(Cursor.Pointer)

hover {
Modifier.background(buttonColors.hover).styleModifier {
cursor(Cursor.Pointer)
}
}

active {
Modifier.background(buttonColors.pressed)
}
active = Modifier.background(buttonColors.pressed)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import org.jetbrains.compose.web.dom.Div
private const val MAX_COLUMN_COUNT = 4

val SimpleGridStyle = ComponentStyle("silk-simple-grid") {
base = Modifier.styleModifier {
display(DisplayStyle.Grid)
base {
Modifier.styleModifier {
display(DisplayStyle.Grid)
}
}
}

Expand All @@ -34,9 +36,9 @@ private val SimpleGridColumnVariants: Map<Breakpoint?, Map<Int, ComponentVariant
}
numColumns to SimpleGridStyle.addVariant("$name-$numColumns") {
if (breakpoint == null) {
base = gridModifier
base { gridModifier }
} else {
breakpoints[breakpoint] = gridModifier
breakpoint { gridModifier }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ import org.jetbrains.compose.web.css.ms

val SurfaceStyle = ComponentStyle("silk-surface") {
val palette = SilkTheme.palettes[colorMode]
base = Modifier
.background(palette.background)
.color(palette.color)
.styleModifier {
// Toggling color mode looks much more engaging if it animates instead of being instant
transitionProperty("background-color", "color")
transitionDuration(200.ms)
}
base {
Modifier
.background(palette.background)
.color(palette.color)
.styleModifier {
// Toggling color mode looks much more engaging if it animates instead of being instant
transitionProperty("background-color", "color")
transitionDuration(200.ms)
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,25 @@ import org.jetbrains.compose.web.dom.A
import org.jetbrains.compose.web.dom.Text

val LinkStyle = ComponentStyle("silk-link") {
base = Modifier.styleModifier { textDecorationLine(TextDecorationLine.None) }

link = Modifier.color(SilkTheme.palettes[colorMode].link.default)
visited = Modifier.color(SilkTheme.palettes[colorMode].link.visited)
base {
Modifier.styleModifier { textDecorationLine(TextDecorationLine.None) }
}

hover = Modifier.styleModifier { textDecorationLine(TextDecorationLine.Underline) }
link {
Modifier.color(SilkTheme.palettes[colorMode].link.default)
}
visited {
Modifier.color(SilkTheme.palettes[colorMode].link.visited)
}
hover {
Modifier.styleModifier { textDecorationLine(TextDecorationLine.Underline) }
}
}

val UndecoratedLinkVariant = LinkStyle.addVariant("undecorated") {
hover = Modifier.styleModifier { textDecorationLine(TextDecorationLine.None) }
hover {
Modifier.styleModifier { textDecorationLine(TextDecorationLine.None) }
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,76 +46,70 @@ private class ComparableStyleBuilder : StyleBuilder {
* a component style can use it if relevant.
*/
class ComponentModifiers(val colorMode: ColorMode) {
/** Base styles for this component, will always be applied first. */
var base: Modifier? = null
internal var base: Modifier? = null

internal val pseudoClasses = LinkedHashMap<String, Modifier>() // LinkedHashMap preserves insertion order

internal val pseudoElements = LinkedHashMap<String, Modifier>() // LinkedHashMap preserves insertion order

internal val breakpoints = mutableMapOf<Breakpoint, Modifier>()

/** Define base styles for this component, will always be applied first. */
fun base(createModifier: () -> Modifier) {
base = createModifier()
}

/**
* Register styles associated with pseudo classes like "hover".
*
* You can either add a pseudo class modifier to this map directly or use one of the various convenience properties
* provided which will do it for you.
*
* Pseudo classes will be applied in the order inserted. Be aware that you should use the LVHA order if using link,
* visited, hover, and/or active pseudo classes.
*
* See also: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
*/
val pseudoClasses = LinkedHashMap<String, Modifier>() // LinkedHashMap preserves insertion order
fun pseudoClass(name: String, createModifier: () -> Modifier) {
pseudoClasses[name] = createModifier()
}

/**
* Register styles associated with pseudo elements like "after".
*
* You can either add a pseudo element modifier to this map directly or use one of the various convenience properties
* provided which will do it for you.
*
* Pseudo-elements will be applied in the order inserted, and after all pseudo classes.
* Pseudo-elements will be applied in the order registered, and after all pseudo classes.
*
* See also: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
*/
val pseudoElements = LinkedHashMap<String, Modifier>() // LinkedHashMap preserves insertion order
fun pseudoElement(name: String, createModifier: () -> Modifier) {
pseudoElements[name] = createModifier()
}

/**
* Register layout styles which are dependent on the current window width.
*
* Breakpoints will be applied in order from smallest to largest, and after all pseudo classes and pseudo-elements.
*/
val breakpoints = mutableMapOf<Breakpoint, Modifier>()

/**
* An alternate way to add [pseudoClasses] entries, mostly provided for supporting extension properties.
*/
fun setPseudoClassModifier(pseudoClass: String, modifier: Modifier?) {
if (modifier != null) {
pseudoClasses[pseudoClass] = modifier
}
else {
pseudoClasses.remove(pseudoClass)
}
}

/**
* An alternate way to add [pseudoElements] entries, mostly provided for supporting extension properties.
*/
fun setPseudoElementModifier(pseudoElement: String, modifier: Modifier?) {
if (modifier != null) {
pseudoElements[pseudoElement] = modifier
}
else {
pseudoElements.remove(pseudoElement)
}
fun breakpoint(breakpoint: Breakpoint, createModifier: () -> Modifier) {
breakpoints[breakpoint] = createModifier()
}

/**
* An alternate way to add [breakpoints] entries, mostly provided for supporting extension properties.
* Convenience function for associating a modifier directly against a breakpoint enum.
*
* For example, you can call
*
* ```
* Breakpoint.MD { Modifier.color(...) }
* ```
*
* which is identical to
*
* ```
* breakpoint(Breakpoint.MD) { Modifier.color(...) }
* ```
*/
fun setBreakpointModifier(breakpoint: Breakpoint, modifier: Modifier?) {
if (modifier != null) {
breakpoints[breakpoint] = modifier
}
else {
breakpoints.remove(breakpoint)
}
operator fun Breakpoint.invoke(createModifier: () -> Modifier) {
breakpoints[this] = createModifier()
}

}

/**
Expand Down
Loading

0 comments on commit 732b5b2

Please sign in to comment.