Forms & UI
Overview
SpeedPy uses django-crispy-forms with the crispy-tailwind template pack for consistent, Tailwind-styled forms.
Configuration
CRISPY_TEMPLATE_PACK = "tailwind"
CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind"
Writing Forms
Every form should use a FormHelper with a Layout defined in __init__:
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field, HTML, Div
from crispy_tailwind.layout import Submit, Collapse
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Field('name'),
Field('description'),
Div(
Div(Field('category'), css_class='w-1/2 pr-2'),
Div(Field('priority'), css_class='w-1/2 pl-2'),
css_class='flex'
),
)
Rendering Forms in Templates
{% load crispy_forms_tags %}
{% crispy form %}
Collapsible Sections
Use Collapse from crispy_tailwind.layout for groups of fields that should be hidden by default:
from crispy_tailwind.layout import Collapse
Layout(
Field('name'),
Collapse(
"Advanced Settings",
Field('timeout'),
Field('retries'),
),
)
Submit Buttons
Use the Tailwind Submit with custom CSS classes:
from crispy_tailwind.layout import Submit
Submit(
"submit",
"Save",
css_class="py-2 px-4 text-sm font-medium text-white bg-blue-600 rounded-lg cursor-pointer",
)
Frontend Libraries
SpeedPy includes several frontend libraries:
Versoly UI
A UI component library served as a static file:
STATICFILES_DIRS = [
...
("versolyui", BASE_DIR / "node_modules" / "versoly-ui" / "dist"),
]
Floating UI
For tooltips, popovers, and dropdown positioning:
STATICFILES_DIRS = [
...
("floating-core", BASE_DIR / "node_modules" / "@floating-ui" / "core" / "dist"),
("floating-ui", BASE_DIR / "node_modules" / "@floating-ui" / "dom" / "dist"),
]
Alpine.js
Alpine.js is available for lightweight interactivity in templates.
Dark Mode
Tailwind dark mode is configured with the class strategy:
module.exports = {
darkMode: 'class',
...
}
Toggle dark mode by adding or removing the dark class on the <html> element.