From 93c512d0204877472382d9f88b03a80996b2c427 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Sat, 11 Nov 2023 21:10:20 -0800 Subject: [PATCH 01/12] Add utilities for percent, px, vw, vh, em, rem --- styles/utils.go | 34 ++++++++++++++++++++++++++++++++++ styles/utils_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/styles/utils.go b/styles/utils.go index 21cc81d..6890539 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -1,5 +1,9 @@ package styles +import ( + "fmt" +) + // Merge combines multiple styles.Props maps into one, with later styles overriding earlier ones. func Merge(styleMaps ...Props) Props { mergedStyles := Props{} @@ -10,3 +14,33 @@ func Merge(styleMaps ...Props) Props { } return mergedStyles } + +// Percent returns a string representation of the given integer as a percentage. +func Percent(value int) string { + return fmt.Sprintf("%d%%", value) +} + +// Pixels returns a string representation of the given integer as a pixel value. +func Pixels(value int) string { + return fmt.Sprintf("%dpx", value) +} + +// ViewportHeight returns a string representation of the given integer as a viewport height value. +func ViewportHeight(value int) string { + return fmt.Sprintf("%dvh", value) +} + +// ViewportWidth returns a string representation of the given integer as a viewport width value. +func ViewportWidth(value int) string { + return fmt.Sprintf("%dvw", value) +} + +// Em returns a string representation of the given float as an em value. +func Em(value float64) string { + return fmt.Sprintf("%.2fem", value) +} + +// Rem returns a string representation of the given float as a rem value. +func Rem(value float64) string { + return fmt.Sprintf("%.2frem", value) +} diff --git a/styles/utils_test.go b/styles/utils_test.go index fda399f..f19ec35 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -54,3 +54,45 @@ func TestMergeThreeStyles(t *testing.T) { assert.Equal(t, expectedStyle, mergedStyle) } + +func TestPercent(t *testing.T) { + assert.Equal(t, "100%", Percent(100)) + assert.Equal(t, "0%", Percent(0)) + assert.Equal(t, "50%", Percent(50)) + assert.Equal(t, "25%", Percent(25)) +} + +func TestPixels(t *testing.T) { + assert.Equal(t, "100px", Pixels(100)) + assert.Equal(t, "0px", Pixels(0)) + assert.Equal(t, "50px", Pixels(50)) + assert.Equal(t, "25px", Pixels(25)) +} + +func TestViewportHeight(t *testing.T) { + assert.Equal(t, "100vh", ViewportHeight(100)) + assert.Equal(t, "0vh", ViewportHeight(0)) + assert.Equal(t, "50vh", ViewportHeight(50)) + assert.Equal(t, "25vh", ViewportHeight(25)) +} + +func TestViewportWidth(t *testing.T) { + assert.Equal(t, "100vw", ViewportWidth(100)) + assert.Equal(t, "0vw", ViewportWidth(0)) + assert.Equal(t, "50vw", ViewportWidth(50)) + assert.Equal(t, "25vw", ViewportWidth(25)) +} + +func TestEm(t *testing.T) { + assert.Equal(t, "100.00em", Em(100)) + assert.Equal(t, "0.00em", Em(0)) + assert.Equal(t, "50.00em", Em(50)) + assert.Equal(t, "25.00em", Em(25)) +} + +func TestRem(t *testing.T) { + assert.Equal(t, "100.00rem", Rem(100)) + assert.Equal(t, "0.00rem", Rem(0)) + assert.Equal(t, "50.00rem", Rem(50)) + assert.Equal(t, "25.00rem", Rem(25)) +} From 6bf223ee561f5533ed85606e8a8ce6b174e99e84 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Sun, 12 Nov 2023 06:50:39 -0800 Subject: [PATCH 02/12] Use strconv instead --- styles/utils.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/styles/utils.go b/styles/utils.go index 6890539..7ce8a00 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -1,7 +1,7 @@ package styles import ( - "fmt" + "strconv" ) // Merge combines multiple styles.Props maps into one, with later styles overriding earlier ones. @@ -17,30 +17,30 @@ func Merge(styleMaps ...Props) Props { // Percent returns a string representation of the given integer as a percentage. func Percent(value int) string { - return fmt.Sprintf("%d%%", value) + return strconv.Itoa(value) + "%" } // Pixels returns a string representation of the given integer as a pixel value. func Pixels(value int) string { - return fmt.Sprintf("%dpx", value) + return strconv.Itoa(value) + "px" } // ViewportHeight returns a string representation of the given integer as a viewport height value. func ViewportHeight(value int) string { - return fmt.Sprintf("%dvh", value) + return strconv.Itoa(value) + "vh" } // ViewportWidth returns a string representation of the given integer as a viewport width value. func ViewportWidth(value int) string { - return fmt.Sprintf("%dvw", value) + return strconv.Itoa(value) + "vw" } // Em returns a string representation of the given float as an em value. func Em(value float64) string { - return fmt.Sprintf("%.2fem", value) + return strconv.FormatFloat(value, 'f', 2, 64) + "em" } // Rem returns a string representation of the given float as a rem value. func Rem(value float64) string { - return fmt.Sprintf("%.2frem", value) + return strconv.FormatFloat(value, 'f', 2, 64) + "rem" } From 3e2c9194cb0c14efd8887b898ec3044d794ef109 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 14 Nov 2023 20:05:41 -0800 Subject: [PATCH 03/12] Add RGB and RGBA utilities --- styles/utils.go | 49 +++++++++++++++++++++++++++++++++++--------- styles/utils_test.go | 42 ++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/styles/utils.go b/styles/utils.go index 7ce8a00..e3786cb 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -2,6 +2,7 @@ package styles import ( "strconv" + "strings" ) // Merge combines multiple styles.Props maps into one, with later styles overriding earlier ones. @@ -15,6 +16,11 @@ func Merge(styleMaps ...Props) Props { return mergedStyles } +// Em returns a string representation of the given float as an em value. +func Em(value float64) string { + return strconv.FormatFloat(value, 'f', 2, 64) + "em" +} + // Percent returns a string representation of the given integer as a percentage. func Percent(value int) string { return strconv.Itoa(value) + "%" @@ -25,6 +31,39 @@ func Pixels(value int) string { return strconv.Itoa(value) + "px" } +// Rem returns a string representation of the given float as a rem value. +func Rem(value float64) string { + return strconv.FormatFloat(value, 'f', 2, 64) + "rem" +} + +// RGB returns a string representation of the given RGB values as a CSS RGB value. +func RGB(r, g, b int) string { + var builder strings.Builder + builder.WriteString("rgb(") + builder.WriteString(strconv.Itoa(r)) + builder.WriteString(",") + builder.WriteString(strconv.Itoa(g)) + builder.WriteString(",") + builder.WriteString(strconv.Itoa(b)) + builder.WriteString(")") + return builder.String() +} + +// RGBA returns a string representation of the given RGBA values as a CSS RGBA value. +func RGBA(r, g, b, a int) string { + var builder strings.Builder + builder.WriteString("rgba(") + builder.WriteString(strconv.Itoa(r)) + builder.WriteString(",") + builder.WriteString(strconv.Itoa(g)) + builder.WriteString(",") + builder.WriteString(strconv.Itoa(b)) + builder.WriteString(",") + builder.WriteString(strconv.Itoa(a)) + builder.WriteString(")") + return builder.String() +} + // ViewportHeight returns a string representation of the given integer as a viewport height value. func ViewportHeight(value int) string { return strconv.Itoa(value) + "vh" @@ -34,13 +73,3 @@ func ViewportHeight(value int) string { func ViewportWidth(value int) string { return strconv.Itoa(value) + "vw" } - -// Em returns a string representation of the given float as an em value. -func Em(value float64) string { - return strconv.FormatFloat(value, 'f', 2, 64) + "em" -} - -// Rem returns a string representation of the given float as a rem value. -func Rem(value float64) string { - return strconv.FormatFloat(value, 'f', 2, 64) + "rem" -} diff --git a/styles/utils_test.go b/styles/utils_test.go index f19ec35..e005135 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -55,6 +55,20 @@ func TestMergeThreeStyles(t *testing.T) { assert.Equal(t, expectedStyle, mergedStyle) } +func TestEm(t *testing.T) { + assert.Equal(t, "100.00em", Em(100)) + assert.Equal(t, "0.00em", Em(0)) + assert.Equal(t, "50.00em", Em(50)) + assert.Equal(t, "25.00em", Em(25)) +} + +func TestRem(t *testing.T) { + assert.Equal(t, "100.00rem", Rem(100)) + assert.Equal(t, "0.00rem", Rem(0)) + assert.Equal(t, "50.00rem", Rem(50)) + assert.Equal(t, "25.00rem", Rem(25)) +} + func TestPercent(t *testing.T) { assert.Equal(t, "100%", Percent(100)) assert.Equal(t, "0%", Percent(0)) @@ -69,6 +83,20 @@ func TestPixels(t *testing.T) { assert.Equal(t, "25px", Pixels(25)) } +func TestRGB(t *testing.T) { + assert.Equal(t, "rgb(100,100,100)", RGB(100, 100, 100)) + assert.Equal(t, "rgb(0,0,0)", RGB(0, 0, 0)) + assert.Equal(t, "rgb(50,50,50)", RGB(50, 50, 50)) + assert.Equal(t, "rgb(25,25,25)", RGB(25, 25, 25)) +} + +func TestRGBA(t *testing.T) { + assert.Equal(t, "rgba(100,100,100,100)", RGBA(100, 100, 100, 100)) + assert.Equal(t, "rgba(0,0,0,0)", RGBA(0, 0, 0, 0)) + assert.Equal(t, "rgba(50,50,50,50)", RGBA(50, 50, 50, 50)) + assert.Equal(t, "rgba(25,25,25,25)", RGBA(25, 25, 25, 25)) +} + func TestViewportHeight(t *testing.T) { assert.Equal(t, "100vh", ViewportHeight(100)) assert.Equal(t, "0vh", ViewportHeight(0)) @@ -82,17 +110,3 @@ func TestViewportWidth(t *testing.T) { assert.Equal(t, "50vw", ViewportWidth(50)) assert.Equal(t, "25vw", ViewportWidth(25)) } - -func TestEm(t *testing.T) { - assert.Equal(t, "100.00em", Em(100)) - assert.Equal(t, "0.00em", Em(0)) - assert.Equal(t, "50.00em", Em(50)) - assert.Equal(t, "25.00em", Em(25)) -} - -func TestRem(t *testing.T) { - assert.Equal(t, "100.00rem", Rem(100)) - assert.Equal(t, "0.00rem", Rem(0)) - assert.Equal(t, "50.00rem", Rem(50)) - assert.Equal(t, "25.00rem", Rem(25)) -} From b17058823a6d48fe0ef9e4399a87a2b9f9110231 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 14 Nov 2023 20:08:20 -0800 Subject: [PATCH 04/12] Add URL style utility --- styles/utils.go | 9 +++++++++ styles/utils_test.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/styles/utils.go b/styles/utils.go index e3786cb..b5e69e1 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -64,6 +64,15 @@ func RGBA(r, g, b, a int) string { return builder.String() } +// URL returns a string representation of the given string as a CSS URL value. +func URL(url string) string { + var builder strings.Builder + builder.WriteString("url('") + builder.WriteString(url) + builder.WriteString("')") + return builder.String() +} + // ViewportHeight returns a string representation of the given integer as a viewport height value. func ViewportHeight(value int) string { return strconv.Itoa(value) + "vh" diff --git a/styles/utils_test.go b/styles/utils_test.go index e005135..ce7a683 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -97,6 +97,10 @@ func TestRGBA(t *testing.T) { assert.Equal(t, "rgba(25,25,25,25)", RGBA(25, 25, 25, 25)) } +func TestURL(t *testing.T) { + assert.Equal(t, "url('https://example.com')", URL("https://example.com")) +} + func TestViewportHeight(t *testing.T) { assert.Equal(t, "100vh", ViewportHeight(100)) assert.Equal(t, "0vh", ViewportHeight(0)) From 88777ab52927ddeac5812cbeaff2becb90d1978b Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 15 Nov 2023 06:22:39 -0800 Subject: [PATCH 05/12] Add var utility --- styles/utils.go | 9 +++++++++ styles/utils_test.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/styles/utils.go b/styles/utils.go index b5e69e1..42525f4 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -73,6 +73,15 @@ func URL(url string) string { return builder.String() } +// Var returns a string representation of the given string as a CSS var value. +func Var(name string) string { + var builder strings.Builder + builder.WriteString("var(--") + builder.WriteString(name) + builder.WriteString(")") + return builder.String() +} + // ViewportHeight returns a string representation of the given integer as a viewport height value. func ViewportHeight(value int) string { return strconv.Itoa(value) + "vh" diff --git a/styles/utils_test.go b/styles/utils_test.go index ce7a683..41db11d 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -101,6 +101,10 @@ func TestURL(t *testing.T) { assert.Equal(t, "url('https://example.com')", URL("https://example.com")) } +func TestVar(t *testing.T) { + assert.Equal(t, "var(--primary-color)", Var("primary-color")) +} + func TestViewportHeight(t *testing.T) { assert.Equal(t, "100vh", ViewportHeight(100)) assert.Equal(t, "0vh", ViewportHeight(0)) From d9fa9150f5680be83a3d94cc09b8054f4ded0c00 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 15 Nov 2023 06:46:55 -0800 Subject: [PATCH 06/12] Zero pixels returns 0 --- styles/utils.go | 3 +++ styles/utils_test.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/styles/utils.go b/styles/utils.go index 42525f4..aeb9848 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -28,6 +28,9 @@ func Percent(value int) string { // Pixels returns a string representation of the given integer as a pixel value. func Pixels(value int) string { + if value == 0 { + return "0" + } return strconv.Itoa(value) + "px" } diff --git a/styles/utils_test.go b/styles/utils_test.go index 41db11d..53d1fb3 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -78,7 +78,7 @@ func TestPercent(t *testing.T) { func TestPixels(t *testing.T) { assert.Equal(t, "100px", Pixels(100)) - assert.Equal(t, "0px", Pixels(0)) + assert.Equal(t, "0", Pixels(0)) assert.Equal(t, "50px", Pixels(50)) assert.Equal(t, "25px", Pixels(25)) } From bde3dec1ddde3548f30b3c757d220f2ae396be6d Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Sat, 9 Mar 2024 13:41:31 -0800 Subject: [PATCH 07/12] Add Float and Int methods --- styles/utils.go | 11 +++++++++++ styles/utils_test.go | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/styles/utils.go b/styles/utils.go index aeb9848..a54b9d6 100644 --- a/styles/utils.go +++ b/styles/utils.go @@ -1,6 +1,7 @@ package styles import ( + "fmt" "strconv" "strings" ) @@ -21,6 +22,16 @@ func Em(value float64) string { return strconv.FormatFloat(value, 'f', 2, 64) + "em" } +// Float returns a string representation of the float with 2 decimal places +func Float(value float64) string { + return fmt.Sprintf("%.2f", value) +} + +// Int returns a string representation of the int +func Int(value int) string { + return strconv.Itoa(value) +} + // Percent returns a string representation of the given integer as a percentage. func Percent(value int) string { return strconv.Itoa(value) + "%" diff --git a/styles/utils_test.go b/styles/utils_test.go index 53d1fb3..ae1523e 100644 --- a/styles/utils_test.go +++ b/styles/utils_test.go @@ -62,6 +62,23 @@ func TestEm(t *testing.T) { assert.Equal(t, "25.00em", Em(25)) } +func TestFloat(t *testing.T) { + assert.Equal(t, "100.00", Float(100)) + assert.Equal(t, "0.00", Float(0)) + assert.Equal(t, "50.00", Float(50)) + assert.Equal(t, "25.00", Float(25)) + + // Longer float + assert.Equal(t, "100.12", Float(100.123456)) +} + +func TestInt(t *testing.T) { + assert.Equal(t, "100", Int(100)) + assert.Equal(t, "0", Int(0)) + assert.Equal(t, "50", Int(50)) + assert.Equal(t, "25", Int(25)) +} + func TestRem(t *testing.T) { assert.Equal(t, "100.00rem", Rem(100)) assert.Equal(t, "0.00rem", Rem(0)) From bc20c047c38a920aeb0c5c602c10268d210f4e52 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 15 Mar 2024 05:03:09 -0700 Subject: [PATCH 08/12] Add CSS value functions to styles readme --- styles/README.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/styles/README.md b/styles/README.md index 7069fa3..9f5c941 100644 --- a/styles/README.md +++ b/styles/README.md @@ -8,8 +8,9 @@ The `styles` subpackage within `elem-go` offers enhanced functionality for CSS s - [Usage](#usage) - [Styling Elements with `styles.Props`](#styling-elements-with-stylesprops) - [Features](#features) - - [`Merge` Function](#merge-function) - [`Style` and `CSS` Functions](#style-and-css-functions) + - [`Merge` Function](#merge-function) + - [Type-Safe CSS Values](#type-safe-css-values) ## Introduction @@ -112,4 +113,98 @@ styleTag := elem.Style(nil, elem.CSS(cssContent)) // Incorporating the