Skip to content

Commit

Permalink
Merge pull request #148 from whisk/main
Browse files Browse the repository at this point in the history
Added support for ::before and ::after CSS pseudo elements
  • Loading branch information
chasefleming authored Sep 17, 2024
2 parents 2df274d + 9dc1c7c commit 274ffa4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions styles/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,8 @@ const (
// Animations pseudo-classes
PseudoPlaying = ":playing"
PseudoPaused = ":paused"

// Content pseudo-elements
PseudoBefore = "::before"
PseudoAfter = "::after"
)
20 changes: 20 additions & 0 deletions styles/stylemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Keyframes map[string]Props
type CompositeStyle struct {
Default Props
PseudoClasses map[string]Props
PseudoElements map[string]Props
MediaQueries map[string]Props
}

Expand Down Expand Up @@ -123,6 +124,17 @@ func (sm *StyleManager) GenerateCSS() string {
builder.WriteString("} ")
}

for pseudoElement, style := range composite.PseudoElements {
// Ensure pseudoElement starts with a double colon
formattedPseudoElement := fmt.Sprintf("%s%s", className, ensureDoubleLeadingColon(pseudoElement))
keys := sortedKeys(style)
builder.WriteString(fmt.Sprintf(".%s { ", formattedPseudoElement))
for _, prop := range keys {
builder.WriteString(fmt.Sprintf("%s: %s; ", prop, style[prop]))
}
builder.WriteString("} ")
}

for mediaQuery, style := range composite.MediaQueries {
// Ensure mediaQuery is correctly prefixed
formattedMediaQuery := ensureMediaPrefix(mediaQuery)
Expand All @@ -146,6 +158,14 @@ func ensureLeadingColon(pseudoClass string) string {
return ":" + pseudoClass
}

// ensureDoubleLeadingColon ensures that the pseudoElement starts with a double colon.
func ensureDoubleLeadingColon(pseudoElement string) string {
if strings.HasPrefix(pseudoElement, "::") {
return pseudoElement
}
return "::" + pseudoElement
}

// ensureMediaPrefix ensures that the mediaQuery starts with "@media".
func ensureMediaPrefix(mediaQuery string) string {
if !strings.HasPrefix(mediaQuery, "@media") {
Expand Down
6 changes: 6 additions & 0 deletions styles/stylemanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ func TestGenerateCSS(t *testing.T) {
PseudoClasses: map[string]Props{
"hover": Props{"color": "blue"},
},
PseudoElements: map[string]Props{
"before": Props{"content": "'[x] '"},
},
MediaQueries: map[string]Props{
"@media (min-width: 768px)": Props{"color": "green", "background": "yellow"},
"@media (min-width: 1024px)": Props{"color": "purple", "background": "orange"},
Expand All @@ -128,6 +131,9 @@ func TestGenerateCSS(t *testing.T) {
assert.Contains(t, css, fmt.Sprintf(".%s { color: pink; }", compositeClassName), "CSS should contain the composite default")
assert.Contains(t, css, fmt.Sprintf(".%s:hover { color: blue; }", compositeClassName), "CSS should contain the composite hover")

// Assertion for the usage of pseudo elements.
assert.Contains(t, css, fmt.Sprintf(".%s::before { content: '[x] '; }", compositeClassName), "CSS should contain the composite before")

// Assertions for media queries.
assert.Contains(t, css, fmt.Sprintf("@media (min-width: 768px) { .%s { background: yellow; color: green; } }", compositeClassName), "CSS should contain the first media query")
assert.Contains(t, css, fmt.Sprintf("@media (min-width: 1024px) { .%s { background: orange; color: purple; } }", compositeClassName), "CSS should contain the second media query")
Expand Down

0 comments on commit 274ffa4

Please sign in to comment.