From b3292fd47e450732e97024b7d4996fa3507d1edc Mon Sep 17 00:00:00 2001 From: coyaSONG <66289470+coyaSONG@users.noreply.github.com> Date: Wed, 15 Jul 2026 03:06:42 +0900 Subject: [PATCH 1/2] svg: respect reduced motion for animated connections --- .../d2sketch/testdata/animated/sketch.exp.svg | 6 +++++ .../testdata/animated_dark/sketch.exp.svg | 6 +++++ d2renderers/d2svg/d2svg.go | 6 +++++ d2renderers/d2svg/d2svg_test.go | 24 +++++++++++++++++++ .../testdata/animated/dark_theme.exp.svg | 6 +++++ .../stable/animated/dagre/sketch.exp.svg | 6 +++++ .../stable/animated/elk/sketch.exp.svg | 6 +++++ .../dagre/sketch.exp.svg | 6 +++++ .../elk/sketch.exp.svg | 6 +++++ .../dagre/sketch.exp.svg | 6 +++++ .../elk/sketch.exp.svg | 6 +++++ .../txtar/md-tables/dagre/sketch.exp.svg | 6 +++++ .../txtar/md-tables/elk/sketch.exp.svg | 6 +++++ .../dagre/sketch.exp.svg | 6 +++++ .../elk/sketch.exp.svg | 6 +++++ 15 files changed, 108 insertions(+) diff --git a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg index abb47d6069..53346e2747 100644 --- a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg @@ -12,6 +12,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .d2-1719270827 .text-bold { font-family: "d2-1719270827-font-bold"; } diff --git a/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg index e31831e5be..99f67ad365 100644 --- a/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg @@ -12,6 +12,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .d2-1408075173 .text-bold { font-family: "d2-1408075173-font-bold"; } diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 4001a853bd..a2197980f8 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -2519,6 +2519,12 @@ func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fon stroke-dashoffset: 0; } } + +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} `, ) diff --git a/d2renderers/d2svg/d2svg_test.go b/d2renderers/d2svg/d2svg_test.go index 2d99dfe321..6de5a3d631 100644 --- a/d2renderers/d2svg/d2svg_test.go +++ b/d2renderers/d2svg/d2svg_test.go @@ -1,11 +1,35 @@ package d2svg import ( + "bytes" + "strings" "testing" + "oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/d2target" ) +func TestEmbedFontsReducedMotion(t *testing.T) { + var buf bytes.Buffer + fontFamily := d2fonts.SourceSansPro + monoFontFamily := d2fonts.SourceCodePro + EmbedFonts(&buf, "diagram", ``, &fontFamily, &monoFontFamily, "") + + css := buf.String() + if !strings.Contains(css, "@media (prefers-reduced-motion: reduce)") { + t.Fatal("animated connections should honor the reduced-motion preference") + } + if !strings.Contains(css, "animation: none !important;") { + t.Fatal("reduced-motion rule should override the inline connection animation") + } + + buf.Reset() + EmbedFonts(&buf, "diagram", ``, &fontFamily, &monoFontFamily, "") + if strings.Contains(buf.String(), "prefers-reduced-motion") { + t.Fatal("static diagrams should not include the reduced-motion rule") + } +} + func TestSortObjects(t *testing.T) { allObjects := []DiagramObject{ // same zIndex and level, should keep in this order diff --git a/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg index 88c18100bf..63fe459aa9 100644 --- a/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg @@ -12,6 +12,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .d2-4155204744 .text-bold { font-family: "d2-4155204744-font-bold"; } diff --git a/e2etests/testdata/stable/animated/dagre/sketch.exp.svg b/e2etests/testdata/stable/animated/dagre/sketch.exp.svg index f801d2fb8c..bef3a661ed 100644 --- a/e2etests/testdata/stable/animated/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/animated/dagre/sketch.exp.svg @@ -5,6 +5,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .d2-2154070564 .text-bold { font-family: "d2-2154070564-font-bold"; } diff --git a/e2etests/testdata/stable/animated/elk/sketch.exp.svg b/e2etests/testdata/stable/animated/elk/sketch.exp.svg index dcfe9b1067..3a9ccfb1c1 100644 --- a/e2etests/testdata/stable/animated/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/animated/elk/sketch.exp.svg @@ -5,6 +5,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .d2-4012398488 .text-bold { font-family: "d2-4012398488-font-bold"; } diff --git a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg index e846117d2f..a02bcd0c6f 100644 --- a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg @@ -12,6 +12,12 @@ } } +@media (prefers-reduced-motion: reduce) { + .animated-connection { + animation: none !important; + } +} + .appendix-icon { filter: drop-shadow(0px 0px 32px rgba(31, 36, 58, 0.1)); }]]>