From 9318c8d5f17aa04991311cc84c8497b167031704 Mon Sep 17 00:00:00 2001 From: Stuart George Date: Sun, 26 May 2024 19:58:08 +0100 Subject: [PATCH] add text decoration and underline offset --- CHANGELOG.md | 10 +++ props/text_decoration_line.go | 14 +++ props/text_decoration_style.go | 15 ++++ style.go | 151 +++++++++++++++++---------------- style_test.go | 76 +++++++++++++++++ 5 files changed, 193 insertions(+), 73 deletions(-) create mode 100644 props/text_decoration_line.go create mode 100644 props/text_decoration_style.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a94218..73ccfa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. +### v0.0.7 + +Added new props: + +- text-decoration-color +- text-decoration-line +- text-decoration-style +- text-decoration-thickness +- text-underline-offset + ### v0.0.6 Added new props: diff --git a/props/text_decoration_line.go b/props/text_decoration_line.go new file mode 100644 index 0000000..3e567bd --- /dev/null +++ b/props/text_decoration_line.go @@ -0,0 +1,14 @@ +package props + +type TextDecorationLine string + +const ( + TextDecorationLineNone TextDecorationLine = "none" + TextDecorationLineUnderline TextDecorationLine = "underline" + TextDecorationLineOverline TextDecorationLine = "overline" + TextDecorationLineLineThrough TextDecorationLine = "line-through" +) + +func (t TextDecorationLine) String() string { + return string(t) +} diff --git a/props/text_decoration_style.go b/props/text_decoration_style.go new file mode 100644 index 0000000..88bbc09 --- /dev/null +++ b/props/text_decoration_style.go @@ -0,0 +1,15 @@ +package props + +type TextDecorationStyle string + +const ( + TextDecorationStyleSolid TextDecorationStyle = "solid" + TextDecorationStyleDouble TextDecorationStyle = "double" + TextDecorationStyleDotted TextDecorationStyle = "dotted" + TextDecorationStyleDashed TextDecorationStyle = "dashed" + TextDecorationStyleWavy TextDecorationStyle = "wavy" +) + +func (t TextDecorationStyle) String() string { + return string(t) +} diff --git a/style.go b/style.go index 96bbcc9..c34181e 100644 --- a/style.go +++ b/style.go @@ -10,79 +10,84 @@ import ( type ( // Props represents the standard CSS properties that can be applied to a CSS rule. Props struct { - AlignItems props.AlignItems `css:"align-items"` - Appearance props.Appearance `css:"appearance"` - BackgroundColor props.Color `css:"background-color"` - BackgroundImage props.BackgroundImage `css:"background-image"` - BackgroundPosition props.BackgroundPosition `css:"background-position"` - BackgroundRepeat props.BackgroundRepeat `css:"background-repeat"` - BackgroundSize props.BackgroundSize `css:"background-size"` - BorderColor props.Color `css:"border-color"` - Border props.Border `css:"border"` - BorderBottom props.Border `css:"border-bottom"` - BorderBottomLeftRadius props.Unit `css:"border-bottom-left-radius"` - BorderBottomRightRadius props.Unit `css:"border-bottom-right-radius"` - BorderLeft props.Border `css:"border-left"` - BorderRadius props.Unit `css:"border-radius"` - BorderRight props.Border `css:"border-right"` - BorderStyle props.BorderStyle `css:"border-style"` - BorderTop props.Border `css:"border-top"` - BorderTopLeftRadius props.Unit `css:"border-top-left-radius"` - BorderTopRightRadius props.Unit `css:"border-top-right-radius"` - BorderWidth props.Unit `css:"border-width"` - Bottom props.Unit `css:"bottom"` - BoxSizing props.BoxSizing `css:"box-sizing"` - CaptionSide props.CaptionSide `css:"caption-side"` - Color props.Color `css:"color"` - ColumnGap props.Unit `css:"column-gap"` - Cursor props.Cursor `css:"cursor"` - Display props.Display `css:"display"` - FlexBasis props.Unit `css:"flex-basis"` - FlexDirection props.FlexDirection `css:"flex-direction"` - FlexGrow props.Unit `css:"flex-grow"` - FlexShrink props.Unit `css:"flex-shrink"` - FlexWrap props.FlexWrap `css:"flex-wrap"` - Float props.Float `css:"float"` - FontSize props.Unit `css:"font-size"` - FontStyle props.FontStyle `css:"font-style"` - FontWeight props.FontWeight `css:"font-weight"` - Gap props.Unit `css:"gap"` - Height props.Unit `css:"height"` - JustifyContent props.JustifyContent `css:"justify-content"` - JustifyItems props.JustifyItems `css:"justify-items"` - JustifySelf props.JustifySelf `css:"justify-self"` - Left props.Unit `css:"left"` - LineHeight props.Unit `css:"line-height"` - ListStylePosition props.ListStylePosition `css:"list-style-position"` - ListStyleType props.ListStyleType `css:"list-style-type"` - Margin props.Unit `css:"margin"` - MarginBottom props.Unit `css:"margin-bottom"` - MarginLeft props.Unit `css:"margin-left"` - MarginRight props.Unit `css:"margin-right"` - MarginTop props.Unit `css:"margin-top"` - MaxWidth props.Unit `css:"max-width"` - MinWidth props.Unit `css:"min-width"` - Opacity props.Unit `css:"opacity"` - Overflow props.Overflow `css:"overflow"` - OverflowX props.Overflow `css:"overflow-x"` - OverflowY props.Overflow `css:"overflow-y"` - Padding props.Unit `css:"padding"` - PaddingBottom props.Unit `css:"padding-bottom"` - PaddingLeft props.Unit `css:"padding-left"` - PaddingRight props.Unit `css:"padding-right"` - PaddingTop props.Unit `css:"padding-top"` - Position props.Position `css:"position"` - PrintColorAdjust props.PrintColorAdjust `css:"print-color-adjust"` - Right props.Unit `css:"right"` - RowGap props.Unit `css:"row-gap"` - TextAlign props.TextAlign `css:"text-align"` - TextOverflow props.TextOverflow `css:"text-overflow"` - Top props.Unit `css:"top"` - VerticalAlign props.VerticalAlign `css:"vertical-align"` - WhiteSpace props.WhiteSpace `css:"white-space"` - Width props.Unit `css:"width"` - Visibility props.Visibility `css:"visibility"` - ZIndex props.Unit `css:"z-index"` + AlignItems props.AlignItems `css:"align-items"` + Appearance props.Appearance `css:"appearance"` + BackgroundColor props.Color `css:"background-color"` + BackgroundImage props.BackgroundImage `css:"background-image"` + BackgroundPosition props.BackgroundPosition `css:"background-position"` + BackgroundRepeat props.BackgroundRepeat `css:"background-repeat"` + BackgroundSize props.BackgroundSize `css:"background-size"` + BorderColor props.Color `css:"border-color"` + Border props.Border `css:"border"` + BorderBottom props.Border `css:"border-bottom"` + BorderBottomLeftRadius props.Unit `css:"border-bottom-left-radius"` + BorderBottomRightRadius props.Unit `css:"border-bottom-right-radius"` + BorderLeft props.Border `css:"border-left"` + BorderRadius props.Unit `css:"border-radius"` + BorderRight props.Border `css:"border-right"` + BorderStyle props.BorderStyle `css:"border-style"` + BorderTop props.Border `css:"border-top"` + BorderTopLeftRadius props.Unit `css:"border-top-left-radius"` + BorderTopRightRadius props.Unit `css:"border-top-right-radius"` + BorderWidth props.Unit `css:"border-width"` + Bottom props.Unit `css:"bottom"` + BoxSizing props.BoxSizing `css:"box-sizing"` + CaptionSide props.CaptionSide `css:"caption-side"` + Color props.Color `css:"color"` + ColumnGap props.Unit `css:"column-gap"` + Cursor props.Cursor `css:"cursor"` + Display props.Display `css:"display"` + FlexBasis props.Unit `css:"flex-basis"` + FlexDirection props.FlexDirection `css:"flex-direction"` + FlexGrow props.Unit `css:"flex-grow"` + FlexShrink props.Unit `css:"flex-shrink"` + FlexWrap props.FlexWrap `css:"flex-wrap"` + Float props.Float `css:"float"` + FontSize props.Unit `css:"font-size"` + FontStyle props.FontStyle `css:"font-style"` + FontWeight props.FontWeight `css:"font-weight"` + Gap props.Unit `css:"gap"` + Height props.Unit `css:"height"` + JustifyContent props.JustifyContent `css:"justify-content"` + JustifyItems props.JustifyItems `css:"justify-items"` + JustifySelf props.JustifySelf `css:"justify-self"` + Left props.Unit `css:"left"` + LineHeight props.Unit `css:"line-height"` + ListStylePosition props.ListStylePosition `css:"list-style-position"` + ListStyleType props.ListStyleType `css:"list-style-type"` + Margin props.Unit `css:"margin"` + MarginBottom props.Unit `css:"margin-bottom"` + MarginLeft props.Unit `css:"margin-left"` + MarginRight props.Unit `css:"margin-right"` + MarginTop props.Unit `css:"margin-top"` + MaxWidth props.Unit `css:"max-width"` + MinWidth props.Unit `css:"min-width"` + Opacity props.Unit `css:"opacity"` + Overflow props.Overflow `css:"overflow"` + OverflowX props.Overflow `css:"overflow-x"` + OverflowY props.Overflow `css:"overflow-y"` + Padding props.Unit `css:"padding"` + PaddingBottom props.Unit `css:"padding-bottom"` + PaddingLeft props.Unit `css:"padding-left"` + PaddingRight props.Unit `css:"padding-right"` + PaddingTop props.Unit `css:"padding-top"` + Position props.Position `css:"position"` + PrintColorAdjust props.PrintColorAdjust `css:"print-color-adjust"` + Right props.Unit `css:"right"` + RowGap props.Unit `css:"row-gap"` + TextAlign props.TextAlign `css:"text-align"` + TextDecorationColor props.Color `css:"text-decoration-color"` + TextDecorationLine props.TextDecorationLine `css:"text-decoration-line"` + TextDecorationStyle props.TextDecorationStyle `css:"text-decoration-style"` + TextDecorationThickness props.Unit `css:"text-decoration-thickness"` + TextOverflow props.TextOverflow `css:"text-overflow"` + TextUnderlineOffset props.Unit `css:"text-underline-offset"` + Top props.Unit `css:"top"` + VerticalAlign props.VerticalAlign `css:"vertical-align"` + WhiteSpace props.WhiteSpace `css:"white-space"` + Width props.Unit `css:"width"` + Visibility props.Visibility `css:"visibility"` + ZIndex props.Unit `css:"z-index"` } // CustomProp represents an additional CSS property that is not covered by the Props struct. CustomProp struct { diff --git a/style_test.go b/style_test.go index 12387db..653ad6c 100644 --- a/style_test.go +++ b/style_test.go @@ -1173,6 +1173,82 @@ func TestStyle_TextAlign(t *testing.T) { } } +func TestStyle_TextDecorationColor(t *testing.T) { + testCases := map[props.Color]string{ + props.ColorRGBA(0, 0, 0, 255): "rgba(0,0,0,1.00)", + props.ColorRGBA(255, 255, 255, 230): "rgba(255,255,255,0.90)", + props.ColorRGBA(255, 255, 255, 255).Alpha(230): "rgba(255,255,255,0.90)", + props.ColorCurrentColor(): "currentColor", + } + + for prop, expected := range testCases { + st := &Style{Selector: ".test", Props: Props{TextDecorationColor: prop}} + css := fmt.Sprintf(".test{text-decoration-color:%s;}", expected) + runTest(t, st, css) + } +} + +func TestStyle_TextDecorationLine(t *testing.T) { + testCases := map[props.TextDecorationLine]string{ + props.TextDecorationLineNone: "none", + props.TextDecorationLineUnderline: "underline", + props.TextDecorationLineOverline: "overline", + props.TextDecorationLineLineThrough: "line-through", + props.TextDecorationLine("initial"): "initial", + } + + for prop, expected := range testCases { + st := &Style{Selector: ".test", Props: Props{TextDecorationLine: prop}} + css := fmt.Sprintf(".test{text-decoration-line:%s;}", expected) + runTest(t, st, css) + } +} + +func TestStyle_TextDecorationStyle(t *testing.T) { + testCases := map[props.TextDecorationStyle]string{ + props.TextDecorationStyleSolid: "solid", + props.TextDecorationStyleDouble: "double", + props.TextDecorationStyleDotted: "dotted", + props.TextDecorationStyleDashed: "dashed", + props.TextDecorationStyleWavy: "wavy", + props.TextDecorationStyle("initial"): "initial", + } + + for prop, expected := range testCases { + st := &Style{Selector: ".test", Props: Props{TextDecorationStyle: prop}} + css := fmt.Sprintf(".test{text-decoration-style:%s;}", expected) + runTest(t, st, css) + } +} + +func TestStyle_TextDecorationThickness(t *testing.T) { + testCases := map[props.Unit]string{ + props.UnitPx(1): "1px", + props.UnitAuto(): "auto", + props.UnitRaw("from-font"): "from-font", + props.UnitInherit(): "inherit", + } + + for prop, expected := range testCases { + st := &Style{Selector: ".test", Props: Props{TextDecorationThickness: prop}} + css := fmt.Sprintf(".test{text-decoration-thickness:%s;}", expected) + runTest(t, st, css) + } +} + +func TestStyle_TextUnderlineOffset(t *testing.T) { + testCases := map[props.Unit]string{ + props.UnitPx(1): "1px", + props.UnitAuto(): "auto", + } + + for prop, expected := range testCases { + st := &Style{Selector: ".test", Props: Props{TextUnderlineOffset: prop}} + css := fmt.Sprintf(".test{text-underline-offset:%s;}", expected) + runTest(t, st, css) + } +} + func TestStyle_TextOverflow(t *testing.T) { testCases := map[props.TextOverflow]string{ props.TextOverflowClip: "clip",