Exported source
fill_none = SingleValueFactory("fill-none", "Remove fill from an element") # Remove fillThe fill utility controls the fill color of SVG elements. It supports all Tailwind color families and shades, as well as special color values.
Apply fill colors using the standard color palette:
Test fill color utilities with various color values.
def test_svg_fill_examples():
"""Test fill color utilities with various color values."""
# Test standard colors
assert str(fill.red._500) == "fill-red-500"
assert str(fill.blue._300) == "fill-blue-300"
assert str(fill.green._700) == "fill-green-700"
assert str(fill.purple._400) == "fill-purple-400"
# Test all 22 color families
assert str(fill.red._500) == "fill-red-500"
assert str(fill.orange._500) == "fill-orange-500"
assert str(fill.amber._500) == "fill-amber-500"
assert str(fill.yellow._500) == "fill-yellow-500"
assert str(fill.lime._500) == "fill-lime-500"
assert str(fill.green._500) == "fill-green-500"
assert str(fill.emerald._500) == "fill-emerald-500"
assert str(fill.teal._500) == "fill-teal-500"
assert str(fill.cyan._500) == "fill-cyan-500"
assert str(fill.sky._500) == "fill-sky-500"
assert str(fill.blue._500) == "fill-blue-500"
assert str(fill.indigo._500) == "fill-indigo-500"
assert str(fill.violet._500) == "fill-violet-500"
assert str(fill.purple._500) == "fill-purple-500"
assert str(fill.fuchsia._500) == "fill-fuchsia-500"
assert str(fill.pink._500) == "fill-pink-500"
assert str(fill.rose._500) == "fill-rose-500"
assert str(fill.slate._500) == "fill-slate-500"
assert str(fill.gray._500) == "fill-gray-500"
assert str(fill.zinc._500) == "fill-zinc-500"
assert str(fill.neutral._500) == "fill-neutral-500"
assert str(fill.stone._500) == "fill-stone-500"
# Test special colors
assert str(fill_none) == "fill-none"
assert str(fill.inherit) == "fill-inherit"
assert str(fill.current) == "fill-current"
assert str(fill.transparent) == "fill-transparent"
assert str(fill.black) == "fill-black"
assert str(fill.white) == "fill-white"
# Run the tests
test_svg_fill_examples()Control the opacity of fill colors:
Test fill colors with opacity modifiers.
def test_svg_fill_opacity_examples():
"""Test fill colors with opacity modifiers."""
# Standard opacity values
assert str(fill.red._500.opacity(50)) == "fill-red-500/50"
assert str(fill.blue._300.opacity(75)) == "fill-blue-300/75"
assert str(fill.black.opacity(10)) == "fill-black/10"
# Arbitrary opacity values
assert str(fill.green._600.opacity("[0.87]")) == "fill-green-600/[0.87]"
assert str(fill.purple._400.opacity("(--my-opacity)")) == "fill-purple-400/(--my-opacity)"
# Run the tests
test_svg_fill_opacity_examples()Use custom colors when needed:
Test fill utilities with arbitrary and custom values.
def test_svg_fill_arbitrary_examples():
"""Test fill utilities with arbitrary and custom values."""
# Arbitrary color values
assert str(fill("#ff0000")) == "fill-[#ff0000]"
assert str(fill("rgb(255, 0, 0)")) == "fill-[rgb(255, 0, 0)]"
assert str(fill("hsl(0, 100%, 50%)")) == "fill-[hsl(0, 100%, 50%)]"
# CSS custom properties
assert str(fill("--custom-fill")) == "fill-(--custom-fill)"
assert str(fill("--theme-primary")) == "fill-(--theme-primary)"
# Run the tests
test_svg_fill_arbitrary_examples()The stroke utility controls the stroke color of SVG elements. It supports the same color system as fill.
Apply stroke colors using the standard color palette:
Test stroke color utilities with various color values.
def test_svg_stroke_examples():
"""Test stroke color utilities with various color values."""
# Test standard colors
assert str(stroke.red._500) == "stroke-red-500"
assert str(stroke.blue._300) == "stroke-blue-300"
assert str(stroke.green._700) == "stroke-green-700"
assert str(stroke.purple._400) == "stroke-purple-400"
# Test all 22 color families
assert str(stroke.red._500) == "stroke-red-500"
assert str(stroke.orange._500) == "stroke-orange-500"
assert str(stroke.amber._500) == "stroke-amber-500"
assert str(stroke.yellow._500) == "stroke-yellow-500"
assert str(stroke.lime._500) == "stroke-lime-500"
assert str(stroke.green._500) == "stroke-green-500"
assert str(stroke.emerald._500) == "stroke-emerald-500"
assert str(stroke.teal._500) == "stroke-teal-500"
assert str(stroke.cyan._500) == "stroke-cyan-500"
assert str(stroke.sky._500) == "stroke-sky-500"
assert str(stroke.blue._500) == "stroke-blue-500"
assert str(stroke.indigo._500) == "stroke-indigo-500"
assert str(stroke.violet._500) == "stroke-violet-500"
assert str(stroke.purple._500) == "stroke-purple-500"
assert str(stroke.fuchsia._500) == "stroke-fuchsia-500"
assert str(stroke.pink._500) == "stroke-pink-500"
assert str(stroke.rose._500) == "stroke-rose-500"
assert str(stroke.slate._500) == "stroke-slate-500"
assert str(stroke.gray._500) == "stroke-gray-500"
assert str(stroke.zinc._500) == "stroke-zinc-500"
assert str(stroke.neutral._500) == "stroke-neutral-500"
assert str(stroke.stone._500) == "stroke-stone-500"
# Test special colors
assert str(stroke_none) == "stroke-none"
assert str(stroke.inherit) == "stroke-inherit"
assert str(stroke.current) == "stroke-current"
assert str(stroke.transparent) == "stroke-transparent"
assert str(stroke.black) == "stroke-black"
assert str(stroke.white) == "stroke-white"
# Run the tests
test_svg_stroke_examples()Control the opacity of stroke colors:
Test stroke colors with opacity modifiers.
def test_svg_stroke_opacity_examples():
"""Test stroke colors with opacity modifiers."""
# Standard opacity values
assert str(stroke.red._500.opacity(50)) == "stroke-red-500/50"
assert str(stroke.blue._300.opacity(75)) == "stroke-blue-300/75"
assert str(stroke.black.opacity(10)) == "stroke-black/10"
# Arbitrary opacity values
assert str(stroke.green._600.opacity("[0.87]")) == "stroke-green-600/[0.87]"
assert str(stroke.purple._400.opacity("(--my-opacity)")) == "stroke-purple-400/(--my-opacity)"
# Run the tests
test_svg_stroke_opacity_examples()The stroke-width utility controls the width of SVG strokes. It supports numeric values from 0-2 by default.
Factory for stroke-width utilities with restricted numeric scale (0-2).
Apply stroke width values:
Test stroke width utilities with various values.
def test_svg_stroke_width_examples():
"""Test stroke width utilities with various values."""
# Test default numeric values (0-2)
assert str(stroke_width(0)) == "stroke-0"
assert str(stroke_width(1)) == "stroke-1"
assert str(stroke_width(2)) == "stroke-2"
# Test attribute access
assert str(stroke_width._0) == "stroke-0"
assert str(stroke_width._1) == "stroke-1"
assert str(stroke_width._2) == "stroke-2"
# Test values outside default range (treated as arbitrary)
assert str(stroke_width(3)) == "stroke-[3]"
assert str(stroke_width(0.5)) == "stroke-[0.5]"
assert str(stroke_width(1.5)) == "stroke-[1.5]"
assert str(stroke_width._4) == "stroke-[4]"
# Run the tests
test_svg_stroke_width_examples()Use custom stroke width values:
Test stroke width utilities with arbitrary and custom values.
def test_svg_stroke_width_arbitrary_examples():
"""Test stroke width utilities with arbitrary and custom values."""
# Arbitrary numeric values
assert str(stroke_width("0.25")) == "stroke-[0.25]"
assert str(stroke_width("10px")) == "stroke-[10px]"
assert str(stroke_width("2rem")) == "stroke-[2rem]"
# CSS custom properties
assert str(stroke_width("--stroke-thin")) == "stroke-(--stroke-thin)"
assert str(stroke_width("--stroke-thick")) == "stroke-(--stroke-thick)"
# Run the tests
test_svg_stroke_width_arbitrary_examples()Let’s see how to use these SVG utilities in real FastHTML components:
Test SVG utilities in practical FastHTML component examples.
def test_svg_fasthtml_examples():
"""Test SVG utilities in practical FastHTML component examples."""
from fasthtml.common import Div
from fasthtml.svg import Svg, Circle, Rect, G, Path
from cjm_fasthtml_tailwind.utilities.sizing import w, h
from cjm_fasthtml_tailwind.utilities.layout import display_tw
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, grid_display
# Icon with fill color
icon = Svg(
Path(
d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z",
cls=str(fill.current)
),
viewBox="0 0 24 24",
cls=combine_classes(w(6), h(6), fill_none)
)
assert "fill-current" in icon.children[0].attrs['class']
assert "fill-none" in icon.attrs['class']
# Circle with stroke
circle_svg = Svg(
Circle(
cx="50", cy="50", r="40",
cls=combine_classes(
fill.transparent,
stroke.blue._500,
stroke_width(2)
)
),
viewBox="0 0 100 100",
cls=combine_classes(w(24), h(24))
)
circle_attrs = circle_svg.children[0].attrs['class']
assert "fill-transparent" in circle_attrs
assert "stroke-blue-500" in circle_attrs
assert "stroke-2" in circle_attrs
# Complex SVG with multiple elements
complex_svg = Svg(
G(
Rect(
x="10", y="10", width="80", height="80",
cls=combine_classes(
fill.red._200,
stroke.red._600,
stroke_width(1)
)
),
Circle(
cx="50", cy="50", r="20",
cls=combine_classes(
fill.blue._400.opacity(75),
stroke.blue._700,
stroke_width(2)
)
)
),
viewBox="0 0 100 100",
cls=combine_classes(w(32), h(32))
)
rect_attrs = complex_svg.children[0].children[0].attrs['class']
circle_attrs = complex_svg.children[0].children[1].attrs['class']
assert "fill-red-200" in rect_attrs
assert "stroke-red-600" in rect_attrs
assert "stroke-1" in rect_attrs
assert "fill-blue-400/75" in circle_attrs
assert "stroke-blue-700" in circle_attrs
assert "stroke-2" in circle_attrs
# Return all examples in a grid layout
return Div(
icon,
circle_svg,
complex_svg,
cls=combine_classes(grid_display, gap(5))
)
# Run the tests
test_svg_fasthtml_examples()Create reusable icon components:
Test creating reusable SVG icon components.
def test_svg_icon_fasthtml_examples():
"""Test creating reusable SVG icon components."""
from fasthtml.common import Div
from fasthtml.svg import Svg, Path
from cjm_fasthtml_tailwind.utilities.sizing import w, h
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import items, justify, gap, grid_display, flex_display
from cjm_fasthtml_tailwind.utilities.layout import display_tw
# Helper function to create an icon
def Icon(path_d: str, size: int = 6, color_cls: str = ""):
"""Create a reusable icon component."""
return Svg(
Path(d=path_d, cls=str(fill.current)),
viewBox="0 0 24 24",
cls=combine_classes(
w(size), h(size),
fill_none,
stroke.current,
stroke_width(2),
color_cls
)
)
# Home icon
home_icon = Icon(
"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6",
size=8,
color_cls="text-blue-500"
)
assert "w-8 h-8" in home_icon.attrs['class']
assert "fill-none" in home_icon.attrs['class']
assert "stroke-current" in home_icon.attrs['class']
assert "stroke-2" in home_icon.attrs['class']
assert "text-blue-500" in home_icon.attrs['class']
# Check icon with custom colors
check_icon = Div(
Svg(
Path(
d="M5 13l4 4L19 7",
cls=combine_classes(
fill_none,
stroke.green._500,
stroke_width(2)
)
),
viewBox="0 0 24 24",
cls=combine_classes(w(5), h(5))
),
cls=combine_classes(flex_display.inline, items.center, justify.center)
)
path_attrs = check_icon.children[0].children[0].attrs['class']
assert "fill-none" in path_attrs
assert "stroke-green-500" in path_attrs
assert "stroke-2" in path_attrs
# Return all examples in a grid layout
return Div(
home_icon,
check_icon,
cls=combine_classes(grid_display, gap(5))
)
# Run the tests
test_svg_icon_fasthtml_examples()Create a circular progress indicator:
Test creating a progress ring component.
def test_svg_progress_ring_fasthtml_examples():
"""Test creating a progress ring component."""
from fasthtml.common import Div
from fasthtml.svg import Svg, Circle
from cjm_fasthtml_tailwind.utilities.sizing import w, h
from cjm_fasthtml_tailwind.utilities.layout import display_tw, position
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, grid_display, flex_display
# Progress ring component
def ProgressRing(percentage: int, size: int = 120):
"""Create a circular progress indicator."""
radius = 45
circumference = 2 * 3.14159 * radius
stroke_dashoffset = circumference - (percentage / 100) * circumference
return Div(
Svg(
# Background circle
Circle(
cx=str(size // 2),
cy=str(size // 2),
r=str(radius),
cls=combine_classes(
fill_none,
stroke.gray._200,
stroke_width(8)
)
),
# Progress circle
Circle(
cx=str(size // 2),
cy=str(size // 2),
r=str(radius),
cls=combine_classes(
fill_none,
stroke.blue._500,
stroke_width(8)
),
style=f"stroke-dasharray: {circumference}; stroke-dashoffset: {stroke_dashoffset}; transform: rotate(-90deg); transform-origin: center;",
),
viewBox=f"0 0 {size} {size}",
cls=combine_classes(w(32), h(32))
),
cls=combine_classes(position.relative, flex_display.inline)
)
# Test 75% progress
progress_75 = ProgressRing(75)
svg = progress_75.children[0]
bg_circle = svg.children[0]
progress_circle = svg.children[1]
assert "fill-none" in bg_circle.attrs['class']
assert "stroke-gray-200" in bg_circle.attrs['class']
assert "stroke-[8]" in bg_circle.attrs['class']
assert "fill-none" in progress_circle.attrs['class']
assert "stroke-blue-500" in progress_circle.attrs['class']
assert "stroke-[8]" in progress_circle.attrs['class']
assert "stroke-dasharray" in progress_circle.attrs['style']
# Create different progress examples
progress_25 = ProgressRing(25)
progress_50 = ProgressRing(50)
progress_100 = ProgressRing(100)
# Return all examples in a grid layout
return Div(
progress_25,
progress_50,
progress_75,
progress_100,
cls=combine_classes(grid_display, gap(5))
)
# Run the tests
test_svg_progress_ring_fasthtml_examples()Test edge cases and special SVG-specific values:
Test edge cases and special values for SVG utilities.
Convenient functions for common SVG patterns:
def svg_icon_classes(
fill_color:Union=None, # Fill color class or utility
stroke_color:Union=None, # Stroke color class or utility
width:Union=2, # Stroke width value
size:int=6, # Icon size (numeric value for w and h)
extra_classes:str='', # Additional classes to include
)->str: # Combined class string for SVG icon
Generate common SVG icon classes.
Test SVG helper functions.