interactivity

Interactivity utilities for Tailwind CSS

Accent Color

Utilities for controlling the accented color of form controls (like checkboxes, radio buttons, and range sliders):


test_interactivity_accent_examples


def test_interactivity_accent_examples(
    
):

Test accent color utilities.

Exported source
accent = ColoredFactory("accent", "Accent color utilities for form controls like checkboxes, radio buttons, and range sliders") # The accent color factory
Exported source
def test_interactivity_accent_examples():
    """Test accent color utilities."""
    
    # Test all 22 color families
    assert str(accent.red._500) == "accent-red-500"
    assert str(accent.orange._500) == "accent-orange-500"
    assert str(accent.amber._500) == "accent-amber-500"
    assert str(accent.yellow._500) == "accent-yellow-500"
    assert str(accent.lime._500) == "accent-lime-500"
    assert str(accent.green._500) == "accent-green-500"
    assert str(accent.emerald._500) == "accent-emerald-500"
    assert str(accent.teal._500) == "accent-teal-500"
    assert str(accent.cyan._500) == "accent-cyan-500"
    assert str(accent.sky._500) == "accent-sky-500"
    assert str(accent.blue._500) == "accent-blue-500"
    assert str(accent.indigo._500) == "accent-indigo-500"
    assert str(accent.violet._500) == "accent-violet-500"
    assert str(accent.purple._500) == "accent-purple-500"
    assert str(accent.fuchsia._500) == "accent-fuchsia-500"
    assert str(accent.pink._500) == "accent-pink-500"
    assert str(accent.rose._500) == "accent-rose-500"
    assert str(accent.slate._500) == "accent-slate-500"
    assert str(accent.gray._500) == "accent-gray-500"
    assert str(accent.zinc._500) == "accent-zinc-500"
    assert str(accent.neutral._500) == "accent-neutral-500"
    assert str(accent.stone._500) == "accent-stone-500"
    
    # Special colors
    assert str(accent.inherit) == "accent-inherit"
    assert str(accent.current) == "accent-current"
    assert str(accent.transparent) == "accent-transparent"
    assert str(accent.black) == "accent-black"
    assert str(accent.white) == "accent-white"
    
    # Arbitrary values
    assert str(accent("#ff0000")) == "accent-[#ff0000]"
    assert str(accent("--custom-accent")) == "accent-(--custom-accent)"

# Run the tests
test_interactivity_accent_examples()

Appearance

Utilities for suppressing native form control styling:


test_interactivity_appearance_examples


def test_interactivity_appearance_examples(
    
):

Test appearance utilities.

Exported source
appearance = SimpleFactory(
    {
        "none": "appearance-none",
        "auto": "appearance-auto"
    },
    "Appearance utilities for suppressing or restoring native form control styling"
) # Appearance factory
Exported source
def test_interactivity_appearance_examples():
    """Test appearance utilities."""
    assert str(appearance.none) == "appearance-none"
    assert str(appearance.auto) == "appearance-auto"

# Run the tests
test_interactivity_appearance_examples()

Caret Color

Utilities for controlling the color of the text input cursor:


test_interactivity_caret_examples


def test_interactivity_caret_examples(
    
):

Test caret color utilities.

Exported source
caret = ColoredFactory("caret", "Caret color utilities for controlling the color of the text input cursor") # The caret color factory
Exported source
def test_interactivity_caret_examples():
    """Test caret color utilities."""
    
    # Test all 22 color families
    assert str(caret.red._500) == "caret-red-500"
    assert str(caret.orange._500) == "caret-orange-500"
    assert str(caret.amber._500) == "caret-amber-500"
    assert str(caret.yellow._500) == "caret-yellow-500"
    assert str(caret.lime._500) == "caret-lime-500"
    assert str(caret.green._500) == "caret-green-500"
    assert str(caret.emerald._500) == "caret-emerald-500"
    assert str(caret.teal._500) == "caret-teal-500"
    assert str(caret.cyan._500) == "caret-cyan-500"
    assert str(caret.sky._500) == "caret-sky-500"
    assert str(caret.blue._500) == "caret-blue-500"
    assert str(caret.indigo._500) == "caret-indigo-500"
    assert str(caret.violet._500) == "caret-violet-500"
    assert str(caret.purple._500) == "caret-purple-500"
    assert str(caret.fuchsia._500) == "caret-fuchsia-500"
    assert str(caret.pink._500) == "caret-pink-500"
    assert str(caret.rose._500) == "caret-rose-500"
    assert str(caret.slate._500) == "caret-slate-500"
    assert str(caret.gray._500) == "caret-gray-500"
    assert str(caret.zinc._500) == "caret-zinc-500"
    assert str(caret.neutral._500) == "caret-neutral-500"
    assert str(caret.stone._500) == "caret-stone-500"
    
    # Special colors
    assert str(caret.inherit) == "caret-inherit"
    assert str(caret.current) == "caret-current"
    assert str(caret.transparent) == "caret-transparent"
    assert str(caret.black) == "caret-black"
    assert str(caret.white) == "caret-white"
    
    # Arbitrary values
    assert str(caret("#ff0000")) == "caret-[#ff0000]"
    assert str(caret("--custom-caret")) == "caret-(--custom-caret)"

# Run the tests
test_interactivity_caret_examples()

Color Scheme

Utilities for controlling the color scheme of an element:


test_interactivity_scheme_examples


def test_interactivity_scheme_examples(
    
):

Test color scheme utilities.

Exported source
scheme = SimpleFactory(
    {
        "normal": "scheme-normal",
        "dark": "scheme-dark",
        "light": "scheme-light",
        "light_dark": "scheme-light-dark",
        "only_dark": "scheme-only-dark",
        "only_light": "scheme-only-light"
    },
    "Color scheme utilities for controlling the preferred color scheme of an element"
) # Color scheme factory
Exported source
def test_interactivity_scheme_examples():
    """Test color scheme utilities."""
    assert str(scheme.normal) == "scheme-normal"
    assert str(scheme.dark) == "scheme-dark"
    assert str(scheme.light) == "scheme-light"
    assert str(scheme.light_dark) == "scheme-light-dark"
    assert str(scheme.only_dark) == "scheme-only-dark"
    assert str(scheme.only_light) == "scheme-only-light"

# Run the tests
test_interactivity_scheme_examples()

Cursor

Utilities for controlling the cursor style when hovering over an element:


CursorFactory


def CursorFactory(
    values_dict:Optional=None, # Dictionary mapping attribute names to CSS values
    doc:Optional=None, # Optional documentation string
):

Factory for cursor utilities with arbitrary value support.


test_interactivity_cursor_examples


def test_interactivity_cursor_examples(
    
):

Test cursor utilities.

Exported source
cursor = CursorFactory(
    {
        "auto": "cursor-auto",
        "default": "cursor-default",
        "pointer": "cursor-pointer",
        "wait": "cursor-wait",
        "text": "cursor-text",
        "move": "cursor-move",
        "help": "cursor-help",
        "not-allowed": "cursor-not-allowed",
        "none": "cursor-none",
        "context-menu": "cursor-context-menu",
        "progress": "cursor-progress",
        "cell": "cursor-cell",
        "crosshair": "cursor-crosshair",
        "vertical-text": "cursor-vertical-text",
        "alias": "cursor-alias",
        "copy": "cursor-copy",
        "no-drop": "cursor-no-drop",
        "grab": "cursor-grab",
        "grabbing": "cursor-grabbing",
        "all-scroll": "cursor-all-scroll",
        "col-resize": "cursor-col-resize",
        "row-resize": "cursor-row-resize",
        "n-resize": "cursor-n-resize",
        "e-resize": "cursor-e-resize",
        "s-resize": "cursor-s-resize",
        "w-resize": "cursor-w-resize",
        "ne-resize": "cursor-ne-resize",
        "nw-resize": "cursor-nw-resize",
        "se-resize": "cursor-se-resize",
        "sw-resize": "cursor-sw-resize",
        "ew-resize": "cursor-ew-resize",
        "ns-resize": "cursor-ns-resize",
        "nesw-resize": "cursor-nesw-resize",
        "nwse-resize": "cursor-nwse-resize",
        "zoom-in": "cursor-zoom-in",
        "zoom-out": "cursor-zoom-out"
    },
    "Cursor utilities for controlling the cursor style when hovering over an element"
) # Cursor factory
Exported source
def test_interactivity_cursor_examples():
    """Test cursor utilities."""
    # Common cursors
    assert str(cursor.auto) == "cursor-auto"
    assert str(cursor.default) == "cursor-default"
    assert str(cursor.pointer) == "cursor-pointer"
    assert str(cursor.wait) == "cursor-wait"
    assert str(cursor.text) == "cursor-text"
    assert str(cursor.move) == "cursor-move"
    assert str(cursor.help) == "cursor-help"
    assert str(cursor.not_allowed) == "cursor-not-allowed"
    
    # Resize cursors
    assert str(cursor.n_resize) == "cursor-n-resize"
    assert str(cursor.ne_resize) == "cursor-ne-resize"
    assert str(cursor.col_resize) == "cursor-col-resize"
    assert str(cursor.row_resize) == "cursor-row-resize"
    
    # Special cursors
    assert str(cursor.grab) == "cursor-grab"
    assert str(cursor.grabbing) == "cursor-grabbing"
    assert str(cursor.zoom_in) == "cursor-zoom-in"
    assert str(cursor.zoom_out) == "cursor-zoom-out"
    
    # Custom properties and arbitrary values
    assert cursor("--custom-cursor") == "cursor-(--custom-cursor)"
    assert cursor("url(cursor.png), auto") == "cursor-[url(cursor.png), auto]"

# Run the tests
test_interactivity_cursor_examples()

Field Sizing

Utilities for controlling the sizing of form controls:


test_interactivity_field_sizing_examples


def test_interactivity_field_sizing_examples(
    
):

Test field sizing utilities.

Exported source
field_sizing = SimpleFactory(
    {
        "fixed": "field-sizing-fixed",
        "content": "field-sizing-content"
    },
    "Field sizing utilities for controlling how form controls are sized"
) # Field sizing factory
Exported source
def test_interactivity_field_sizing_examples():
    """Test field sizing utilities."""
    assert str(field_sizing.fixed) == "field-sizing-fixed"
    assert str(field_sizing.content) == "field-sizing-content"

# Run the tests
test_interactivity_field_sizing_examples()

Pointer Events

Utilities for controlling whether an element responds to pointer events:


test_interactivity_pointer_events_examples


def test_interactivity_pointer_events_examples(
    
):

Test pointer events utilities.

Exported source
pointer_events = SimpleFactory(
    {
        "auto": "pointer-events-auto",
        "none": "pointer-events-none"
    },
    "Pointer events utilities for controlling whether an element responds to pointer events"
) # Pointer events factory
Exported source
def test_interactivity_pointer_events_examples():
    """Test pointer events utilities."""
    assert str(pointer_events.auto) == "pointer-events-auto"
    assert str(pointer_events.none) == "pointer-events-none"

# Run the tests
test_interactivity_pointer_events_examples()

Resize

Utilities for controlling how an element can be resized:


test_interactivity_resize_examples


def test_interactivity_resize_examples(
    
):

Test resize utilities.

Exported source
resize = SimpleFactory(
    {
        "none": "resize-none",
        "both": "resize",
        "y": "resize-y",
        "x": "resize-x"
    },
    "Resize utilities for controlling how an element can be resized"
) # Resize factory
Exported source
def test_interactivity_resize_examples():
    """Test resize utilities."""
    assert str(resize.none) == "resize-none"
    assert str(resize.both) == "resize"
    assert str(resize.y) == "resize-y"
    assert str(resize.x) == "resize-x"

# Run the tests
test_interactivity_resize_examples()

Scroll Behavior

Utilities for controlling the scroll behavior of an element:


test_interactivity_scroll_behavior_examples


def test_interactivity_scroll_behavior_examples(
    
):

Test scroll behavior utilities.

Exported source
scroll = SimpleFactory(
    {
        "auto": "scroll-auto",
        "smooth": "scroll-smooth"
    },
    "Scroll behavior utilities for controlling smooth scrolling"
) # Scroll behavior factory
Exported source
def test_interactivity_scroll_behavior_examples():
    """Test scroll behavior utilities."""
    assert str(scroll.auto) == "scroll-auto"
    assert str(scroll.smooth) == "scroll-smooth"

# Run the tests
test_interactivity_scroll_behavior_examples()

Scroll Margin

Utilities for controlling the scroll offset around items in a snap container:


test_interactivity_scroll_margin_examples


def test_interactivity_scroll_margin_examples(
    
):

Test scroll margin utilities.

Exported source
scroll_m = DirectionalScaledFactory("scroll-m", SPACING_CONFIG, "Scroll margin utilities for controlling scroll offset margins") # The scroll margin factory

# Additional directional scroll margin utilities for logical properties
scroll_ms = ScaledFactory("scroll-ms", SPACING_CONFIG, "Scroll margin inline-start utilities")  # scroll-margin-inline-start
scroll_me = ScaledFactory("scroll-me", SPACING_CONFIG, "Scroll margin inline-end utilities")  # scroll-margin-inline-end
Exported source
def test_interactivity_scroll_margin_examples():
    """Test scroll margin utilities."""
    # All sides
    assert str(scroll_m(4)) == "scroll-m-4"
    assert str(scroll_m(0)) == "scroll-m-0"
    assert str(scroll_m.px) == "scroll-m-px"
    
    # Directional
    assert str(scroll_m.t(4)) == "scroll-mt-4"
    assert str(scroll_m.r(4)) == "scroll-mr-4"
    assert str(scroll_m.b(4)) == "scroll-mb-4"
    assert str(scroll_m.l(4)) == "scroll-ml-4"
    assert str(scroll_m.x(8)) == "scroll-mx-8"
    assert str(scroll_m.y(8)) == "scroll-my-8"
    
    # Negative values
    assert str(scroll_m.negative(4)) == "-scroll-m-4"
    assert str(scroll_m.t.negative(2)) == "-scroll-mt-2"
    
    # Logical properties
    assert str(scroll_ms(4)) == "scroll-ms-4"
    assert str(scroll_me(4)) == "scroll-me-4"
    assert str(scroll_ms.negative(2)) == "-scroll-ms-2"
    
    # Arbitrary values
    assert str(scroll_m("10px")) == "scroll-m-[10px]"
    assert str(scroll_m("--custom-margin")) == "scroll-m-(--custom-margin)"

# Run the tests
test_interactivity_scroll_margin_examples()

Scroll Padding

Utilities for controlling an element’s scroll offset within a snap container:


test_interactivity_scroll_padding_examples


def test_interactivity_scroll_padding_examples(
    
):

Test scroll padding utilities.

Exported source
scroll_p = DirectionalScaledFactory("scroll-p", SPACING_CONFIG, "Scroll padding utilities for controlling scroll offset padding") # The scroll padding factory

# Additional directional scroll padding utilities for logical properties
scroll_ps = ScaledFactory("scroll-ps", SPACING_CONFIG, "Scroll padding inline-start utilities")  # scroll-padding-inline-start
scroll_pe = ScaledFactory("scroll-pe", SPACING_CONFIG, "Scroll padding inline-end utilities")  # scroll-padding-inline-end
Exported source
def test_interactivity_scroll_padding_examples():
    """Test scroll padding utilities."""
    # All sides
    assert str(scroll_p(4)) == "scroll-p-4"
    assert str(scroll_p(0)) == "scroll-p-0"
    assert str(scroll_p.px) == "scroll-p-px"
    
    # Directional
    assert str(scroll_p.t(4)) == "scroll-pt-4"
    assert str(scroll_p.r(4)) == "scroll-pr-4"
    assert str(scroll_p.b(4)) == "scroll-pb-4"
    assert str(scroll_p.l(4)) == "scroll-pl-4"
    assert str(scroll_p.x(8)) == "scroll-px-8"
    assert str(scroll_p.y(8)) == "scroll-py-8"
    
    # Negative values
    assert str(scroll_p.negative(4)) == "-scroll-p-4"
    assert str(scroll_p.t.negative(2)) == "-scroll-pt-2"
    
    # Logical properties
    assert str(scroll_ps(4)) == "scroll-ps-4"
    assert str(scroll_pe(4)) == "scroll-pe-4"
    assert str(scroll_ps.negative(2)) == "-scroll-ps-2"
    
    # Arbitrary values
    assert str(scroll_p("10px")) == "scroll-p-[10px]"
    assert str(scroll_p("--custom-padding")) == "scroll-p-(--custom-padding)"

# Run the tests
test_interactivity_scroll_padding_examples()

Scroll Snap Utilities

Utilities for controlling scroll snap behavior:

Scroll Snap Align

Control the scroll snap alignment of an element:

Exported source
snap_align = SimpleFactory(
    {
        "start": "snap-start",
        "end": "snap-end",
        "center": "snap-center",
        "none": "snap-align-none"
    },
    "Scroll snap align utilities for controlling snap position alignment"
) # Snap align factory

Scroll Snap Stop

Control whether you can skip past possible snap positions:

Exported source
snap_stop = SimpleFactory(
    {
        "normal": "snap-normal",
        "always": "snap-always"
    },
    "Scroll snap stop utilities for controlling snap stop behavior"
) # Snap stop factory

Scroll Snap Type

Control how strictly snap points are enforced in a snap container:


test_interactivity_scroll_snap_examples


def test_interactivity_scroll_snap_examples(
    
):

Test scroll snap utilities.

Exported source
snap = SimpleFactory(
    {
        "none": "snap-none",
        "x": "snap-x",
        "y": "snap-y",
        "both": "snap-both",
        "mandatory": "snap-mandatory",
        "proximity": "snap-proximity"
    },
    "Scroll snap type utilities for controlling snap container behavior"
) # Snap type factory
Exported source
def test_interactivity_scroll_snap_examples():
    """Test scroll snap utilities."""
    # Snap align
    assert str(snap_align.start) == "snap-start"
    assert str(snap_align.end) == "snap-end"
    assert str(snap_align.center) == "snap-center"
    assert str(snap_align.none) == "snap-align-none"
    
    # Snap stop
    assert str(snap_stop.normal) == "snap-normal"
    assert str(snap_stop.always) == "snap-always"
    
    # Snap type
    assert str(snap.none) == "snap-none"
    assert str(snap.x) == "snap-x"
    assert str(snap.y) == "snap-y"
    assert str(snap.both) == "snap-both"
    assert str(snap.mandatory) == "snap-mandatory"
    assert str(snap.proximity) == "snap-proximity"

# Run the tests
test_interactivity_scroll_snap_examples()

Touch Action

Utilities for controlling how an element can be scrolled and zoomed on touchscreens:


test_interactivity_touch_action_examples


def test_interactivity_touch_action_examples(
    
):

Test touch action utilities.

Exported source
touch = SimpleFactory(
    {
        "auto": "touch-auto",
        "none": "touch-none",
        "pan-x": "touch-pan-x",
        "pan-left": "touch-pan-left",
        "pan-right": "touch-pan-right",
        "pan-y": "touch-pan-y",
        "pan-up": "touch-pan-up",
        "pan-down": "touch-pan-down",
        "pinch-zoom": "touch-pinch-zoom",
        "manipulation": "touch-manipulation"
    },
    "Touch action utilities for controlling touch gestures on touch devices"
) # Touch action factory
Exported source
def test_interactivity_touch_action_examples():
    """Test touch action utilities."""
    assert str(touch.auto) == "touch-auto"
    assert str(touch.none) == "touch-none"
    assert str(touch.pan_x) == "touch-pan-x"
    assert str(touch.pan_left) == "touch-pan-left"
    assert str(touch.pan_right) == "touch-pan-right"
    assert str(touch.pan_y) == "touch-pan-y"
    assert str(touch.pan_up) == "touch-pan-up"
    assert str(touch.pan_down) == "touch-pan-down"
    assert str(touch.pinch_zoom) == "touch-pinch-zoom"
    assert str(touch.manipulation) == "touch-manipulation"

# Run the tests
test_interactivity_touch_action_examples()

User Select

Utilities for controlling whether the user can select text in an element:


test_interactivity_user_select_examples


def test_interactivity_user_select_examples(
    
):

Test user select utilities.

Exported source
select = SimpleFactory(
    {
        "none": "select-none",
        "text": "select-text",
        "all": "select-all",
        "auto": "select-auto"
    },
    "User select utilities for controlling text selection behavior"
) # User select factory
Exported source
def test_interactivity_user_select_examples():
    """Test user select utilities."""
    assert str(select.none) == "select-none"
    assert str(select.text) == "select-text"
    assert str(select.all) == "select-all"
    assert str(select.auto) == "select-auto"

# Run the tests
test_interactivity_user_select_examples()

Will Change

Utilities for optimizing upcoming animations of elements that are expected to change:


WillChangeFactory


def WillChangeFactory(
    values_dict:Optional=None, # Dictionary mapping attribute names to CSS values
    doc:Optional=None, # Optional documentation string
):

Factory for will-change utilities with arbitrary value support.


test_interactivity_will_change_examples


def test_interactivity_will_change_examples(
    
):

Test will-change utilities.

Exported source
will_change = WillChangeFactory(
    {
        "auto": "will-change-auto",
        "scroll": "will-change-scroll",
        "contents": "will-change-contents",
        "transform": "will-change-transform"
    },
    "Will-change utilities for optimizing animations by hinting browsers about expected changes"
) # Will-change factory
Exported source
def test_interactivity_will_change_examples():
    """Test will-change utilities."""
    # Standard values
    assert str(will_change.auto) == "will-change-auto"
    assert str(will_change.scroll) == "will-change-scroll"
    assert str(will_change.contents) == "will-change-contents"
    assert str(will_change.transform) == "will-change-transform"
    
    # Custom properties and arbitrary values
    assert will_change("--custom-property") == "will-change---custom-property"
    assert will_change("opacity, transform") == "will-change-[opacity, transform]"
    assert will_change("left, top") == "will-change-[left, top]"

# Run the tests
test_interactivity_will_change_examples()

Practical Examples

Let’s see how to use these interactivity utilities in real FastHTML components:


test_interactivity_form_fasthtml_examples


def test_interactivity_form_fasthtml_examples(
    
):

Test interactivity utilities in form components.

Exported source
def test_interactivity_form_fasthtml_examples():
    """Test interactivity utilities in form components."""
    from fasthtml.common import Input, Textarea, Button, Div, Label
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    from cjm_fasthtml_tailwind.utilities.spacing import p
    from cjm_fasthtml_tailwind.utilities.borders import border, rounded
    from cjm_fasthtml_tailwind.utilities.backgrounds import bg
    from cjm_fasthtml_tailwind.utilities.typography import font_size, text_color
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, grid_display
    
    # Custom styled checkbox with accent color
    checkbox = Input(
        type="checkbox",
        cls=combine_classes(
            accent.blue._500,
            cursor.pointer,
            w(4),
            h(4)
        )
    )
    assert "accent-blue-500" in checkbox.attrs['class']
    assert "cursor-pointer" in checkbox.attrs['class']
    
    # Text input with custom caret color
    text_input = Input(
        type="text",
        placeholder="Type here...",
        cls=combine_classes(
            caret.red._500,
            appearance.none,
            p.x(4),
            p.y(2),
            border(),
            rounded.full
        )
    )
    assert "caret-red-500" in text_input.attrs['class']
    assert "appearance-none" in text_input.attrs['class']
    
    # Resizable textarea
    textarea = Textarea(
        placeholder="Enter your message...",
        cls=combine_classes(
            resize.y,
            field_sizing.content,
            p(3),
            border(),
            rounded.full
        )
    )
    assert "resize-y" in textarea.attrs['class']
    assert "field-sizing-content" in textarea.attrs['class']
    
    # Interactive button with hover states
    button = Button(
        "Click me",
        cls=combine_classes(
            cursor.pointer,
            select.none,
            pointer_events.auto,
            bg.blue._500,
            text_color.white,
            p.x(4),
            p.y(2),
            rounded.full,
            bg.blue._600.hover
        )
    )
    assert "cursor-pointer" in button.attrs['class']
    assert "select-none" in button.attrs['class']
    
    # Return all examples in a grid layout
    return Div(
        checkbox,
        text_input,
        textarea,
        button,
        cls=combine_classes(grid_display, gap(5))
    )

# Run the tests
test_interactivity_form_fasthtml_examples()
test_func = test_interactivity_form_fasthtml_examples
app, rt = create_test_app()

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

test_interactivity_scroll_snap_fasthtml_examples


def test_interactivity_scroll_snap_fasthtml_examples(
    
):

Test scroll snap utilities in carousel/gallery components.

Exported source
def test_interactivity_scroll_snap_fasthtml_examples():
    """Test scroll snap utilities in carousel/gallery components."""
    from fasthtml.common import Div, Img
    from cjm_fasthtml_tailwind.utilities.layout import display_tw, overflow
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, shrink, grid_display, flex_display
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    
    # Horizontal scroll snap container
    carousel_container = Div(
        cls=combine_classes(
            snap.x,
            snap.mandatory,
            scroll.smooth,
            scroll_p.x(4),
            flex_display,
            overflow.x.auto,
            gap(4)
        )
    )
    assert "snap-x" in carousel_container.attrs['class']
    assert "snap-mandatory" in carousel_container.attrs['class']
    assert "scroll-smooth" in carousel_container.attrs['class']
    assert "scroll-px-4" in carousel_container.attrs['class']
    
    # Snap items within the container
    snap_item = Div(
        Img(src="https://img.daisyui.com/images/stock/photo-1559703248-dcaaec9fab78.webp", alt="Gallery image"),
        cls=combine_classes(
            snap_align.center,
            snap_stop.always,
            shrink._0,
            w(80)
        )
    )
    assert "snap-center" in snap_item.attrs['class']
    assert "snap-always" in snap_item.attrs['class']
    
    # Vertical scroll snap for sections
    vertical_snap = Div(
        cls=combine_classes(
            snap.y,
            snap.proximity,
            scroll_m.y(2),
            h.screen,
            overflow.y.auto
        )
    )
    assert "snap-y" in vertical_snap.attrs['class']
    assert "snap-proximity" in vertical_snap.attrs['class']
    assert "scroll-my-2" in vertical_snap.attrs['class']
    
    # Return all examples in a grid layout
    return Div(
        carousel_container,
        snap_item,
        vertical_snap,
        cls=combine_classes(grid_display, gap(5))
    )

# Run the tests
test_interactivity_scroll_snap_fasthtml_examples()
Gallery image
test_func = test_interactivity_scroll_snap_fasthtml_examples
app, rt = create_test_app()

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

test_interactivity_touch_mobile_fasthtml_examples


def test_interactivity_touch_mobile_fasthtml_examples(
    
):

Test touch and mobile interaction utilities.

Exported source
def test_interactivity_touch_mobile_fasthtml_examples():
    """Test touch and mobile interaction utilities."""
    from fasthtml.common import Div, Img, Code
    from cjm_fasthtml_tailwind.utilities.layout import position, overflow, display_tw
    from cjm_fasthtml_tailwind.utilities.spacing import p
    from cjm_fasthtml_tailwind.utilities.backgrounds import bg
    from cjm_fasthtml_tailwind.utilities.typography import font_size, text_color
    from cjm_fasthtml_tailwind.utilities.borders import rounded
    from cjm_fasthtml_tailwind.utilities.transitions_and_animation import transition
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, grid_display
    
    # Touch-enabled image viewer
    image_viewer = Div(
        Img(src="https://img.daisyui.com/images/stock/photo-1559703248-dcaaec9fab78.webp", alt="Photo"),
        cls=combine_classes(
            touch.pinch_zoom,
            cursor.zoom_in,
            select.none,
            position.relative,
            overflow.hidden
        )
    )
    assert "touch-pinch-zoom" in image_viewer.attrs['class']
    assert "cursor-zoom-in" in image_viewer.attrs['class']
    
    # Draggable element
    draggable = Div(
        "Drag me",
        cls=combine_classes(
            cursor.grab,
            cursor.grabbing.active,
            touch.none,
            select.none,
            p(4),
            bg.gray._200,
            rounded.full
        )
    )
    assert "cursor-grab" in draggable.attrs['class']
    assert "touch-none" in draggable.attrs['class']
    
    # Code block with selection
    code_block = Code(
        "console.log('Hello World');",
        cls=combine_classes(
            select.all,
            cursor.text,
            display_tw.block,
            p(3),
            bg.gray._900,
            text_color.gray._100,
            rounded.full
        )
    )
    assert "select-all" in code_block.attrs['class']
    assert "cursor-text" in code_block.attrs['class']
    
    # Touch-friendly swipe area
    swipe_area = Div(
        cls=combine_classes(
            touch.pan_x,
            will_change.transform,
            transition.transform
        )
    )
    assert "touch-pan-x" in swipe_area.attrs['class']
    assert "will-change-transform" in swipe_area.attrs['class']
    
    # Return all examples in a grid layout
    return Div(
        image_viewer,
        draggable,
        code_block,
        swipe_area,
        cls=combine_classes(grid_display, gap(5))
    )

# Run the tests
test_interactivity_touch_mobile_fasthtml_examples()
Photo
Drag me
console.log('Hello World');
test_func = test_interactivity_touch_mobile_fasthtml_examples
app, rt = create_test_app()

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

Advanced Examples

Some advanced use cases demonstrating how these utilities work together:


test_interactivity_advanced_fasthtml_examples


def test_interactivity_advanced_fasthtml_examples(
    
):

Test advanced combinations of interactivity utilities.

Exported source
def test_interactivity_advanced_fasthtml_examples():
    """Test advanced combinations of interactivity utilities."""
    from fasthtml.common import Div, Input, Form, Pre
    from cjm_fasthtml_tailwind.utilities.spacing import p, m
    from cjm_fasthtml_tailwind.utilities.backgrounds import bg
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color
    from cjm_fasthtml_tailwind.utilities.borders import rounded
    from cjm_fasthtml_tailwind.utilities.layout import position, overflow
    from cjm_fasthtml_tailwind.utilities.transforms import scale_tw, transform
    from cjm_fasthtml_tailwind.utilities.transitions_and_animation import transition, duration
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, grid_display
    
    # Dark mode form with custom styling
    dark_form = Form(
        Input(
            type="checkbox",
            cls=combine_classes(
                accent.purple._500,
                scheme.dark,
                cursor.pointer,
                m.r(2)
            )
        ),
        Input(
            type="text",
            cls=combine_classes(
                caret.purple._400,
                appearance.none,
                scheme.dark,
                bg.gray._800,
                text_color.white,
                p.x(3),
                p.y(2),
                rounded.full
            )
        ),
        cls=combine_classes(
            scheme.dark,
            p(6),
            bg.gray._900,
            rounded.lg
        )
    )
    assert "scheme-dark" in dark_form.attrs['class']
    assert "accent-purple-500" in dark_form.children[0].attrs['class']
    assert "caret-purple-400" in dark_form.children[1].attrs['class']
    
    # Interactive code editor mockup
    code_editor = Div(
        Pre(
            "def hello():\n    print('Hello, World!')",
            cls=combine_classes(
                select.text,
                cursor.text,
                caret.green._400,
                resize.both,
                scroll.auto,
                scroll_p(4),
                font_family.mono,
                bg.gray._900,
                text_color.gray._100,
                p(4),
                rounded.full,
                overflow.auto
            )
        ),
        cls=combine_classes(
            pointer_events.auto,
            position.relative
        )
    )
    assert "select-text" in code_editor.children[0].attrs['class']
    assert "cursor-text" in code_editor.children[0].attrs['class']
    assert "resize" in code_editor.children[0].attrs['class']
    assert "scroll-p-4" in code_editor.children[0].attrs['class']
    
    # Complex interactive element with animation hints
    animated_card = Div(
        "Animated Card",
        cls=combine_classes(
            cursor.pointer,
            will_change("transform, opacity"),
            touch.manipulation,
            select.none,
            transition.all,
            duration._300,
            scale_tw(105).hover
        )
    )
    assert "cursor-pointer" in animated_card.attrs['class']
    assert "will-change-[transform, opacity]" in animated_card.attrs['class']
    assert "touch-manipulation" in animated_card.attrs['class']

    # Return all examples in a grid layout
    return Div(
        dark_form,
        code_editor,
        animated_card,
        cls=combine_classes(grid_display, gap(5))
    )

# Run the tests
test_interactivity_advanced_fasthtml_examples()
def hello():
    print('Hello, World!')
Animated Card
test_func = test_interactivity_advanced_fasthtml_examples
app, rt = create_test_app()

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()