Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Style specificity #5

Merged
merged 2 commits into from
Jun 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ styles:
font: title3
```

Styles will be applied in order of specificity, so the more specific a style is (more selectors), the later it will be applied.

Each style may also have a `styles` array that is an array of other inherited styles, who's properties will also be applied.

### Setting a Style
Expand Down
6 changes: 6 additions & 0 deletions Stylist/Style.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ public class Style: Equatable {
return getSuperView(view: superview, component: component)
}
}

var specificityIndex: Int {
return components.reduce(0) { index, component in
index + (component.classType != nil ? 1 : 0) + (component.style != nil ? 1 : 0)
}
}
}

struct SelectorComponent: Equatable {
Expand Down
4 changes: 3 additions & 1 deletion Stylist/Stylist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public class Stylist {
fileWatcher = FileWatcher.Remote(url: url)
}

var hasLoaded = false
let stylist = self
do {
try fileWatcher.start { result in
Expand All @@ -154,7 +155,8 @@ public class Stylist {
do {
let theme = try Theme(data: data)
self.themes[url.path] = theme
stylist.apply(theme: theme, animateChanges: animateChanges)
stylist.apply(theme: theme, animateChanges: animateChanges && hasLoaded)
hasLoaded = true
} catch let error as ThemeError {
parsingError(error)
} catch {
Expand Down
4 changes: 2 additions & 2 deletions Stylist/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public struct Theme: Equatable {

public init(variables: [String: Any] = [:], styles: [Style] = []) {
self.variables = variables
self.styles = styles
self.styles = styles.sorted { $0.specificityIndex < $1.specificityIndex }
}

public static func == (lhs: Theme, rhs: Theme) -> Bool {
Expand Down Expand Up @@ -111,7 +111,7 @@ extension Theme {
styles.append(style)
}
}
self.styles = styles
self.styles = styles.sorted { $0.specificityIndex < $1.specificityIndex }
self.variables = variables
}
}
17 changes: 17 additions & 0 deletions Tests/StylistTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,23 @@ class StylistTests: XCTestCase {
XCTAssertEqual(customView.customProperty, "hello")
}

func testStyleSpecificity() throws {
let theme = Theme(styles: [
try Style(selector: "UIButton.primary", properties: [
StylePropertyValue(name: "backgroundColor", value: "blue")
]),
try Style(selector: "primary", properties: [
StylePropertyValue(name: "backgroundColor", value: "red")
])
])

let view = UIButton()
view.style = "primary"
Stylist.shared.apply(theme: theme)

XCTAssertEqual(view.backgroundColor, .blue)
}

//TODO: test loading files

//TODO: test watching files
Expand Down
10 changes: 10 additions & 0 deletions Tests/ThemeDecodingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,15 @@ class ThemeDecodingTests: XCTestCase {
try themeString(style: "Module.Invalid", property: "color: red")
}
}

func testStyleSpecificityIndex() throws {
let styles = [
try Style(selector: "UIView.custom primary", properties: []),
try Style(selector: "UIView primary", properties: []),
try Style(selector: "UIView", properties: []),
]
let theme = Theme(variables: [:], styles: styles)
XCTAssertEqual(theme.styles, styles.reversed())
}

}