# Create a test app with custom JavaScript
from cjm_fasthtml_tailwind.core.base import combine_classes
from cjm_fasthtml_tailwind.utilities.backgrounds import bg_linear
from cjm_fasthtml_tailwind.utilities.layout import display_tw
from cjm_fasthtml_tailwind.utilities.effects import shadow
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import flex, justify, items, flex_display
from cjm_fasthtml_tailwind.utilities.sizing import container
from cjm_fasthtml_tailwind.utilities.spacing import m, p
from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color
from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui
from cjm_fasthtml_daisyui.utilities.semantic_gradients import from_dui, to_dui
from cjm_fasthtml_daisyui.components.data_display.card import card, card_title
from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors, btn_sizes
from cjm_fasthtml_daisyui.components.feedback.alert import alert, alert_colors
from cjm_fasthtml_daisyui.core.resources import create_js_script
# Create inline custom JavaScript that adds interactivity
custom_js_inline = Script("""
// Custom JavaScript to add click counter functionality
document.addEventListener('DOMContentLoaded', function() {
let clickCount = 0;
const counterElement = document.getElementById('click-counter');
const resetButton = document.getElementById('reset-counter');
// Add click listener to all buttons with 'count-click' class
document.querySelectorAll('.count-click').forEach(button => {
button.addEventListener('click', function() {
clickCount++;
if (counterElement) {
counterElement.textContent = clickCount;
// Add visual feedback
counterElement.classList.add('text-primary', 'font-bold');
setTimeout(() => {
counterElement.classList.remove('text-primary');
}, 300);
}
});
});
// Reset counter functionality
if (resetButton) {
resetButton.addEventListener('click', function() {
clickCount = 0;
if (counterElement) {
counterElement.textContent = clickCount;
}
});
}
// Log to console to verify script is loaded
console.log('Custom JavaScript loaded successfully!');
});
""")
# Create a custom external JavaScript reference (example using a CDN library)
# In this case, we'll use confetti for visual effects
confetti_js = create_js_script(
src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js",
defer=True
)
# Create app with custom JavaScript
app, rt = create_test_app(
theme=DaisyUITheme.CUPCAKE,
custom_js=[confetti_js, custom_js_inline],
)
# Create a test page that uses the custom JavaScript
@rt
def index():
return create_test_page(
"Custom JavaScript Test",
Div(
# Info card
Div(
H2("JavaScript Integration", cls=str(card_title)),
P("This example demonstrates custom JavaScript support in test apps."),
P("Click the buttons below to see the click counter in action!"),
Div(
"Total clicks: ",
Span("0", id="click-counter", cls=combine_classes(font_size._2xl, font_weight.bold)),
cls=combine_classes(font_size.lg, m.t(4))
),
cls=combine_classes(card, bg_dui.base_200, shadow.xl, p(6), m.b(4))
),
# Interactive buttons
Div(
H3("Click Counter Demo", cls=combine_classes(font_size.xl, font_weight.bold, m.b(4))),
Div(
Button("Click Me!", cls=combine_classes(btn, btn_colors.primary, "count-click")),
Button("Me Too!", cls=combine_classes(btn, btn_colors.secondary, "count-click")),
Button("And Me!", cls=combine_classes(btn, btn_colors.accent, "count-click")),
Button("Reset Counter", id="reset-counter", cls=combine_classes(btn, btn_colors.neutral)),
cls=combine_classes(space.x(2))
),
cls=combine_classes(m.b(6))
),
# Confetti button
Div(
H3("Visual Effects Demo", cls=combine_classes(font_size.xl, font_weight.bold, m.b(4))),
P("Using an external JavaScript library (canvas-confetti):"),
Button(
"🎉 Celebrate!",
cls=combine_classes(btn, btn_sizes.lg, btn_colors.primary),
onclick="confetti({particleCount: 100, spread: 70, origin: { y: 0.6 }})"
),
cls=combine_classes(m.b(6))
),
# Console message
Div(
P("💡 Open your browser's developer console to see the custom JavaScript log message."),
cls=combine_classes(alert, alert_colors.info, m.t(4))
)
)
)
# Start the server
server = start_test_server(app, port=8000)
HTMX()