diff --git a/docs/app/news/+layout-demos-dark-mode.bugfix.md b/docs/app/news/+layout-demos-dark-mode.bugfix.md new file mode 100644 index 00000000000..6de8b59073d --- /dev/null +++ b/docs/app/news/+layout-demos-dark-mode.bugfix.md @@ -0,0 +1 @@ +Fix unreadable light-on-light text in the stack, box, spacer and aspect ratio layout demos when the docs are viewed in dark mode. diff --git a/docs/app/tests/test_layout_demo_contrast.py b/docs/app/tests/test_layout_demo_contrast.py new file mode 100644 index 00000000000..9538b3d98be --- /dev/null +++ b/docs/app/tests/test_layout_demo_contrast.py @@ -0,0 +1,59 @@ +"""Regression coverage for fixed-color layout demos staying readable in dark mode.""" + +import re +from pathlib import Path + +import pytest + +DOCS = Path(__file__).resolve().parents[2] + +# Named CSS backgrounds do not adapt to the theme, so a box using one must pin +# its own text color instead of inheriting the theme's foreground. +FIXED_BACKGROUND = re.compile(r'(?:bg|background_color)="[a-z]+"') + + +def enclosing_call(source: str, index: int) -> str: + """Return the argument text of the component call that contains ``index``. + + Args: + source: The document source. + index: An offset inside the call's argument list. + + Returns: + The text between the call's opening and closing parentheses. + """ + depth = 0 + start = index + while start > 0: + start -= 1 + if source[start] == ")": + depth += 1 + elif source[start] == "(": + if depth == 0: + break + depth -= 1 + depth = 0 + end = start + while end < len(source): + end += 1 + if source[end] == "(": + depth += 1 + elif source[end] == ")": + if depth == 0: + break + depth -= 1 + return source[start + 1 : end] + + +@pytest.mark.parametrize( + "doc", + ["layout/stack.md", "layout/box.md", "layout/spacer.md", "layout/aspect_ratio.md"], +) +def test_fixed_color_boxes_pin_a_text_color(doc): + """Every component with a fixed CSS background also sets an explicit text color.""" + source = (DOCS / "library" / doc).read_text() + for match in FIXED_BACKGROUND.finditer(source): + call = enclosing_call(source, match.start()) + assert re.search(r'\bcolor="', call), ( + f"{doc}: {match.group(0)} has no explicit text color in {call.strip()!r}" + ) diff --git a/docs/library/layout/aspect_ratio.md b/docs/library/layout/aspect_ratio.md index 3dd943ef63e..11ac9d07446 100644 --- a/docs/library/layout/aspect_ratio.md +++ b/docs/library/layout/aspect_ratio.md @@ -23,6 +23,7 @@ rx.grid( rx.box( "Widescreen 16:9", background_color="papayawhip", + color="black", width="100%", height="100%", ), @@ -32,6 +33,7 @@ rx.grid( rx.box( "Letterbox 4:3", background_color="orange", + color="black", width="100%", height="100%", ), @@ -41,6 +43,7 @@ rx.grid( rx.box( "Square 1:1", background_color="green", + color="white", width="100%", height="100%", ), @@ -50,6 +53,7 @@ rx.grid( rx.box( "Portrait 5:7", background_color="lime", + color="black", width="100%", height="100%", ), diff --git a/docs/library/layout/box.md b/docs/library/layout/box.md index 14f16aceca2..ccf927f2574 100644 --- a/docs/library/layout/box.md +++ b/docs/library/layout/box.md @@ -20,6 +20,7 @@ rx.box( rx.box( "CSS color", background_color="yellow", + color="black", border_radius="2px", width="20%", margin="4px", @@ -28,6 +29,7 @@ rx.box( rx.box( "CSS color", background_color="orange", + color="black", border_radius="5px", width="40%", margin="8px", diff --git a/docs/library/layout/spacer.md b/docs/library/layout/spacer.md index 0d9d1b01723..f316cebcf9d 100644 --- a/docs/library/layout/spacer.md +++ b/docs/library/layout/spacer.md @@ -13,11 +13,11 @@ Creates an adjustable, empty space that can be used to tune the spacing between ```python demo rx.flex( - rx.center(rx.text("Example"), bg="lightblue"), + rx.center(rx.text("Example"), bg="lightblue", color="black"), rx.spacer(), - rx.center(rx.text("Example"), bg="lightgreen"), + rx.center(rx.text("Example"), bg="lightgreen", color="black"), rx.spacer(), - rx.center(rx.text("Example"), bg="salmon"), + rx.center(rx.text("Example"), bg="salmon", color="black"), width="100%", ) ``` diff --git a/docs/library/layout/stack.md b/docs/library/layout/stack.md index 423ccc1802e..fc21f44cb58 100644 --- a/docs/library/layout/stack.md +++ b/docs/library/layout/stack.md @@ -56,18 +56,21 @@ rx.flex( rx.box( "Example", bg="orange", + color="black", border_radius="3px", width="20%", ), rx.box( "Example", bg="lightblue", + color="black", border_radius="3px", width="30%", ), rx.box( "Example", bg="lightgreen", + color="black", border_radius="3px", width="50%", ), @@ -78,18 +81,21 @@ rx.flex( rx.box( "Example", bg="orange", + color="black", border_radius="3px", width="20%", ), rx.box( "Example", bg="lightblue", + color="black", border_radius="3px", width="30%", ), rx.box( "Example", bg="lightgreen", + color="black", border_radius="3px", width="50%", ), @@ -104,28 +110,32 @@ rx.flex( ```python demo rx.hstack( - rx.box("Example", bg="red", border_radius="3px", width="10%"), + rx.box("Example", bg="red", color="black", border_radius="3px", width="10%"), rx.box( "Example", bg="orange", + color="black", border_radius="3px", width="10%", ), rx.box( "Example", bg="yellow", + color="black", border_radius="3px", width="10%", ), rx.box( "Example", bg="lightblue", + color="black", border_radius="3px", width="10%", ), rx.box( "Example", bg="lightgreen", + color="black", border_radius="3px", width="60%", ), @@ -137,28 +147,32 @@ rx.hstack( ```python demo rx.vstack( - rx.box("Example", bg="red", border_radius="3px", width="20%"), + rx.box("Example", bg="red", color="black", border_radius="3px", width="20%"), rx.box( "Example", bg="orange", + color="black", border_radius="3px", width="40%", ), rx.box( "Example", bg="yellow", + color="black", border_radius="3px", width="60%", ), rx.box( "Example", bg="lightblue", + color="black", border_radius="3px", width="80%", ), rx.box( "Example", bg="lightgreen", + color="black", border_radius="3px", width="100%", ),