Exported source
dock = SingleValueFactory("dock", "Base dock component") # Base dock component
dock_label = SingleValueFactory("dock-label", "Text label for Dock Item") # Dock labeltest_dock_basic_examples ()
Test basic dock utilities.
def test_dock_basic_examples():
"""Test basic dock utilities."""
# Basic dock
assert str(dock) == "dock"
assert str(dock_label) == "dock-label"
# Dock with modifiers
assert str(dock.hover) == "hover:dock"
assert str(dock.md) == "md:dock"
assert str(dock.dark) == "dark:dock"
# Run the tests
test_dock_basic_examples()test_dock_modifiers_examples ()
Test dock modifier utilities.
test_dock_sizes_examples ()
Test dock size variants.
def test_dock_sizes_examples():
"""Test dock size variants."""
assert str(dock_sizes.xs) == "dock-xs"
assert str(dock_sizes.sm) == "dock-sm"
assert str(dock_sizes.md) == "dock-md"
assert str(dock_sizes.lg) == "dock-lg"
assert str(dock_sizes.xl) == "dock-xl"
# With responsive modifiers
assert str(dock_sizes.xs.sm) == "sm:dock-xs"
assert str(dock_sizes.lg.md) == "md:dock-lg"
# Run the tests
test_dock_sizes_examples()test_dock_basic_fasthtml_examples ()
Test basic dock example from daisyUI v5 documentation.
def test_dock_basic_fasthtml_examples():
"""Test basic dock example from daisyUI v5 documentation."""
from fasthtml.common import Div, Button, Span
from fasthtml.svg import Svg, G, Polyline, Path, Line, Rect, Circle
from cjm_fasthtml_tailwind.utilities.sizing import size_util
from cjm_fasthtml_tailwind.utilities.svg import fill, stroke
# Create reusable home icon SVG
home_icon = Svg(
G(
Polyline(
points="1 11 12 2 23 11",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Line(
x1="12", y1="22", x2="12", y2="18",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
# Create inbox icon SVG
inbox_icon = Svg(
G(
Polyline(
points="3 14 9 14 9 17 15 17 15 14 21 14",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Rect(
x="3", y="3", width="18", height="18",
rx="2", ry="2",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
# Create settings icon SVG
settings_icon = Svg(
G(
Circle(
cx="12", cy="12", r="3",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
# Basic dock with labels
basic_dock = Div(
Button(
home_icon,
Span("Home", cls=str(dock_label))
),
Button(
inbox_icon,
Span("Inbox", cls=str(dock_label)),
cls=str(dock_modifiers.active)
),
Button(
settings_icon,
Span("Settings", cls=str(dock_label))
),
cls=str(dock)
)
# Verify structure
assert basic_dock.tag == "div"
assert basic_dock.attrs['class'] == "dock"
# Verify buttons
assert len(basic_dock.children) == 3
# First button (Home)
home_btn = basic_dock.children[0]
assert home_btn.tag == "button"
assert home_btn.children[0].tag == "svg" # Icon
assert home_btn.children[1].tag == "span" # Label
assert home_btn.children[1].attrs['class'] == "dock-label"
assert home_btn.children[1].children[0] == "Home"
# Second button (Inbox - active)
inbox_btn = basic_dock.children[1]
assert inbox_btn.tag == "button"
assert inbox_btn.attrs['class'] == "dock-active"
assert inbox_btn.children[0].tag == "svg" # Icon
assert inbox_btn.children[1].tag == "span" # Label
assert inbox_btn.children[1].attrs['class'] == "dock-label"
assert inbox_btn.children[1].children[0] == "Inbox"
# Third button (Settings)
settings_btn = basic_dock.children[2]
assert settings_btn.tag == "button"
assert settings_btn.children[0].tag == "svg" # Icon
assert settings_btn.children[1].tag == "span" # Label
assert settings_btn.children[1].attrs['class'] == "dock-label"
assert settings_btn.children[1].children[0] == "Settings"
return basic_dock
# Run the tests
test_dock_basic_fasthtml_examples()<div class="dock">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg><span class="dock-label">Home</span></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg><span class="dock-label">Inbox</span></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg><span class="dock-label">Settings</span></button></div>test_dock_sizes_fasthtml_examples ()
Test dock size variations from daisyUI v5 documentation.
def test_dock_sizes_fasthtml_examples():
"""Test dock size variations from daisyUI v5 documentation."""
from fasthtml.common import Div, Button, Span
from fasthtml.svg import Svg, G, Polyline, Path, Line, Rect, Circle
from cjm_fasthtml_tailwind.utilities.sizing import size_util
from cjm_fasthtml_tailwind.utilities.svg import fill, stroke
# Create reusable icons (same as in basic example)
home_icon = Svg(
G(
Polyline(
points="1 11 12 2 23 11",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Line(
x1="12", y1="22", x2="12", y2="18",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
inbox_icon = Svg(
G(
Polyline(
points="3 14 9 14 9 17 15 17 15 14 21 14",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Rect(
x="3", y="3", width="18", height="18",
rx="2", ry="2",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
settings_icon = Svg(
G(
Circle(
cx="12", cy="12", r="3",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
# Dock Extra Small size (no labels)
dock_xs = Div(
Button(home_icon),
Button(inbox_icon, cls=str(dock_modifiers.active)),
Button(settings_icon),
cls=combine_classes(dock, dock_sizes.xs)
)
assert "dock" in dock_xs.attrs['class']
assert "dock-xs" in dock_xs.attrs['class']
assert len(dock_xs.children) == 3
# XS size has no labels
assert len(dock_xs.children[0].children) == 1 # Only icon
# Dock Small size (no labels)
dock_sm = Div(
Button(home_icon),
Button(inbox_icon, cls=str(dock_modifiers.active)),
Button(settings_icon),
cls=combine_classes(dock, dock_sizes.sm)
)
assert "dock" in dock_sm.attrs['class']
assert "dock-sm" in dock_sm.attrs['class']
assert len(dock_sm.children) == 3
# SM size has no labels
assert len(dock_sm.children[0].children) == 1 # Only icon
# Dock Medium size (with labels)
dock_md = Div(
Button(
home_icon,
Span("Home", cls=str(dock_label))
),
Button(
inbox_icon,
Span("Inbox", cls=str(dock_label)),
cls=str(dock_modifiers.active)
),
Button(
settings_icon,
Span("Settings", cls=str(dock_label))
),
cls=combine_classes(dock, dock_sizes.md)
)
assert "dock" in dock_md.attrs['class']
assert "dock-md" in dock_md.attrs['class']
assert len(dock_md.children) == 3
# MD size has labels
assert len(dock_md.children[0].children) == 2 # Icon and label
assert dock_md.children[0].children[1].attrs['class'] == "dock-label"
# Dock Large size (with labels)
dock_lg = Div(
Button(
home_icon,
Span("Home", cls=str(dock_label))
),
Button(
inbox_icon,
Span("Inbox", cls=str(dock_label)),
cls=str(dock_modifiers.active)
),
Button(
settings_icon,
Span("Settings", cls=str(dock_label))
),
cls=combine_classes(dock, dock_sizes.lg)
)
assert "dock" in dock_lg.attrs['class']
assert "dock-lg" in dock_lg.attrs['class']
assert len(dock_lg.children) == 3
# LG size has labels
assert len(dock_lg.children[0].children) == 2 # Icon and label
# Dock Extra Large size (with labels)
dock_xl = Div(
Button(
home_icon,
Span("Home", cls=str(dock_label))
),
Button(
inbox_icon,
Span("Inbox", cls=str(dock_label)),
cls=str(dock_modifiers.active)
),
Button(
settings_icon,
Span("Settings", cls=str(dock_label))
),
cls=combine_classes(dock, dock_sizes.xl)
)
assert "dock" in dock_xl.attrs['class']
assert "dock-xl" in dock_xl.attrs['class']
assert len(dock_xl.children) == 3
# XL size has labels
assert len(dock_xl.children[0].children) == 2 # Icon and label
# Return all dock sizes in a container
return Div(
dock_xs,
dock_sm,
dock_md,
dock_lg,
dock_xl
)
# Run the tests
test_dock_sizes_fasthtml_examples()<div>
<div class="dock dock-xs">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg></button> </div>
<div class="dock dock-sm">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg></button> </div>
<div class="dock dock-md">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg><span class="dock-label">Home</span></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg><span class="dock-label">Inbox</span></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg><span class="dock-label">Settings</span></button> </div>
<div class="dock dock-lg">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg><span class="dock-label">Home</span></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg><span class="dock-label">Inbox</span></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg><span class="dock-label">Settings</span></button> </div>
<div class="dock dock-xl">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg><span class="dock-label">Home</span></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg><span class="dock-label">Inbox</span></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg><span class="dock-label">Settings</span></button> </div>
</div>test_dock_custom_colors_fasthtml_examples ()
Test dock with custom colors from daisyUI v5 documentation.
def test_dock_custom_colors_fasthtml_examples():
"""Test dock with custom colors from daisyUI v5 documentation."""
from fasthtml.common import Div, Button, Span
from fasthtml.svg import Svg, G, Polyline, Path, Line, Rect, Circle
from cjm_fasthtml_tailwind.utilities.sizing import size_util
from cjm_fasthtml_tailwind.utilities.svg import fill, stroke
from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, text_dui
# Create reusable icons (same as in basic example)
home_icon = Svg(
G(
Polyline(
points="1 11 12 2 23 11",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Line(
x1="12", y1="22", x2="12", y2="18",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
inbox_icon = Svg(
G(
Polyline(
points="3 14 9 14 9 17 15 17 15 14 21 14",
fill="none",
stroke="currentColor",
stroke_miterlimit="10",
stroke_width="2"
),
Rect(
x="3", y="3", width="18", height="18",
rx="2", ry="2",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
settings_icon = Svg(
G(
Circle(
cx="12", cy="12", r="3",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
Path(
d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z",
fill="none",
stroke="currentColor",
stroke_linecap="square",
stroke_miterlimit="10",
stroke_width="2"
),
fill="currentColor",
stroke_linejoin="miter",
stroke_linecap="butt"
),
cls=str(size_util("1.2em")),
xmlns="http://www.w3.org/2000/svg",
viewBox="0 0 24 24"
)
# Dock with custom neutral background color
custom_color_dock = Div(
Button(
home_icon,
Span("Home", cls=str(dock_label))
),
Button(
inbox_icon,
Span("Inbox", cls=str(dock_label)),
cls=str(dock_modifiers.active)
),
Button(
settings_icon,
Span("Settings", cls=str(dock_label))
),
cls=combine_classes(dock, bg_dui.neutral, text_dui.neutral_content)
)
# Verify structure
assert custom_color_dock.tag == "div"
assert "dock" in custom_color_dock.attrs['class']
assert "bg-neutral" in custom_color_dock.attrs['class']
assert "text-neutral-content" in custom_color_dock.attrs['class']
# Verify buttons
assert len(custom_color_dock.children) == 3
# First button (Home)
home_btn = custom_color_dock.children[0]
assert home_btn.tag == "button"
assert home_btn.children[0].tag == "svg" # Icon
assert home_btn.children[1].tag == "span" # Label
assert home_btn.children[1].attrs['class'] == "dock-label"
assert home_btn.children[1].children[0] == "Home"
# Second button (Inbox - active)
inbox_btn = custom_color_dock.children[1]
assert inbox_btn.tag == "button"
assert inbox_btn.attrs['class'] == "dock-active"
assert inbox_btn.children[0].tag == "svg" # Icon
assert inbox_btn.children[1].tag == "span" # Label
assert inbox_btn.children[1].attrs['class'] == "dock-label"
assert inbox_btn.children[1].children[0] == "Inbox"
# Third button (Settings)
settings_btn = custom_color_dock.children[2]
assert settings_btn.tag == "button"
assert settings_btn.children[0].tag == "svg" # Icon
assert settings_btn.children[1].tag == "span" # Label
assert settings_btn.children[1].attrs['class'] == "dock-label"
assert settings_btn.children[1].children[0] == "Settings"
return custom_color_dock
# Run the tests
test_dock_custom_colors_fasthtml_examples()<div class="dock bg-neutral text-neutral-content">
<button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="1 11 12 2 23 11" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><path d="m5,13v7c0,1.105.895,2,2,2h10c1.105,0,2-.895,2-2v-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path><line x1="12" y1="22" x2="12" y2="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="square" stroke-miterlimit="10"></line></g></svg><span class="dock-label">Home</span></button><button class="dock-active"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><polyline points="3 14 9 14 9 17 15 17 15 14 21 14" fill="none" stroke="currentColor" stroke-width="2" stroke-miterlimit="10"></polyline><rect width="18" height="18" x="3" y="3" fill="none" stroke="currentColor" stroke-width="2" rx="2" ry="2" stroke-linecap="square" stroke-miterlimit="10"></rect></g></svg><span class="dock-label">Inbox</span></button><button><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="size-[1.2em]"><g fill="currentColor" stroke-linejoin="miter" stroke-linecap="butt"><circle r="3" cx="12" cy="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></circle><path d="m22,13.25v-2.5l-2.318-.966c-.167-.581-.395-1.135-.682-1.654l.954-2.318-1.768-1.768-2.318.954c-.518-.287-1.073-.515-1.654-.682l-.966-2.318h-2.5l-.966,2.318c-.581.167-1.135.395-1.654.682l-2.318-.954-1.768,1.768.954,2.318c-.287.518-.515,1.073-.682,1.654l-2.318.966v2.5l2.318.966c.167.581.395,1.135.682,1.654l-.954,2.318,1.768,1.768,2.318-.954c.518.287,1.073.515,1.654.682l.966,2.318h2.5l.966-2.318c.581-.167,1.135-.395,1.654-.682l2.318.954,1.768-1.768-.954-2.318c.287-.518.515-1.073.682-1.654l2.318-.966Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-miterlimit="10"></path></g></svg><span class="dock-label">Settings</span></button></div>