All notable changes to djust-components will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Component Descriptor System (DEP-002): 8 descriptor-based component classes (
Accordion,Tabs,Modal,Collapsible,Sheet,Dropdown,Tooltip,Carousel) using Python's descriptor protocol on djust'sLiveComponent. Components are declared as class attributes on LiveViews with typed state (TypedStateinnerStateclass), automatic event handler registration viaMeta.event, dirty-flag render caching, dependency tracking via_component_descriptorsregistry, and a client/server tier system (Meta.tier). Gallery views refactored from mixin-based to descriptor-based. DEP-001 interactive mixins are now deprecated in favor of descriptors.
- DEP-001 interactive mixins:
AccordionMixin,TabsMixin,ModalMixin,CollapsibleMixin,SheetMixin,DropdownMixin,TooltipMixin,CarouselMixinare deprecated. Use the corresponding descriptor classes fromdjust_components.descriptorsinstead (e.g.,Accordion()as a class attribute). Mixins remain functional but will be removed in a future release.
- Per-component interactive mixins (DEP-001): 8 new mixins (
AccordionMixin,TabsMixin,ModalMixin,CollapsibleMixin,SheetMixin,DropdownMixin,TooltipMixin,CarouselMixin) providing encapsulated state management and event handlers for interactive components. Each mixin supports multiple instances viacomponent_idrouting.ComponentMixinbase class provides the instance registry pattern. Template tags (accordion,tabs,modal,dropdown,collapsible,sheet,tooltip,carousel) accept an optionalcomponent_idparameter that emitsdata-component-idondj-clickelements. RefactoredCategoryGalleryViewto use mixins instead of manual state dicts. 100 new mixin tests. - 61 missing component classes (#MISSING-CLASSES): Created Python component classes for all 61 template tags that previously lacked them: Modal, Tabs, Accordion, Dropdown, Tooltip, Popover, Collapsible, Sheet, CommandPalette, ContextMenu, Carousel, LoadingOverlay, AnnouncementBar, Callout, SplitPane, ScrollArea, StickyHeader, DescriptionList, AspectRatio, Timeline, Stepper, Rating, Gauge, TreeView, NotificationCenter, KanbanBoard, VirtualList, TableOfContents, CopyButton, EmptyState, Pagination, Avatar, Skeleton, CodeBlock, Breadcrumb, InlineEdit, DataTable, Kbd, Combobox, DatePicker, ColorPicker, MultiSelect, OtpInput, NumberStepper, TagInput, ToggleGroup, FileDropzone, RichTextEditor, SplitButton, PageHeader, Sidebar, NavMenu, AppShell, Toolbar, FilterBar, ThemeToggle, FormGroup, InputGroup, Fieldset, Fab, Icon. All classes follow the existing pattern (Component base class,
_render_custom(),html.escape()on text params,custom_classsupport). 184 new tests. - LiveView category gallery (#LV-GALLERY-LAYOUT): Added
CategoryGalleryView— a generic LiveView for browsing any component category with reactive theme switching, prev/next navigation, and interactive state management (accordion, tabs, collapsible, modal, sheet). ExtractedGalleryThemeMixinshared betweenGalleryIndexViewandCategoryGalleryView. New URL atlv/<slug>/coexists with static views during transition. - Visual regression test infrastructure (#VRT): Added GitHub Actions workflow (
.github/workflows/vrt.yml) that captures Playwright screenshots of the component gallery at 3 breakpoints (mobile/tablet/desktop) x 2 color modes (light/dark) and diffs against committed baselines. Includes local capture script (scripts/capture-vrt-baselines.sh) and strategy documentation (docs/VISUAL_REGRESSION.md). Workflow triggers only on PRs that modify CSS or template files.
- custom_class XSS escaping (#SEC-SWEEP): Added
html.escape()tocustom_classin_render_custom()across 63 component classes that were missing it. Previously only ~40 components escaped this user-controlled value before injecting it into CSS class attributes. 100 new tests cover the fix. - Spinner label escaping (#SEC-SWEEP): Escape
labelwithhtml.escape()in both the<span>content andaria-labelattribute of the Spinner component. Previously unescaped, enabling script injection via label text. - Toast type allowlist (#SEC-SWEEP): Toast component and ToastContainerHandler now validate
typeagainst{"info", "success", "warning", "error"}, falling back to"info"for unknown values. Prevents CSS class injection via arbitrary type strings. - Toast/ServerEventToast container position allowlist (#SEC-SWEEP):
ToastContainerNode(template tag) andServerToastContainerHandler(Rust handler) now validatepositionagainst six allowed values (top-left,top-right,top-center,bottom-left,bottom-right,bottom-center), falling back to"top-right". Prevents CSS class injection via position parameter. - AuditLog action allowlist (#SEC-SWEEP): Action values are now validated against a configurable
allowed_actionsset (default: create, read, update, delete, login, logout, export, import, approve, reject) before being used in CSS class names. Unknown actions are silently omitted from class attributes. Cell content remains HTML-escaped as before. Passallowed_actions={"custom", "values"}to extend. - Replace eval() with AST parser (#EVAL-REPLACE):
DataTableMixin._eval_expression()now uses a safe recursive-descent arithmetic parser instead ofeval(). The parser only permits numeric literals, column-name identifiers,+ - * / %, unary minus, and parentheses. Function calls, attribute access, and arbitrary Python expressions are rejected. Theeval()call with its character allowlist and empty__builtins__has been removed entirely.
The following template tags accept inner block content (between open/close tags) that is passed through unescaped by design, since the content comes from the template author, not from user input:
{% modal %}...{% endmodal %}-- modal body content{% tabs %}...{% endtabs %}-- tab panel content{% accordion %}...{% endaccordion %}-- panel content{% dropdown %}...{% enddropdown %}-- dropdown menu content{% tooltip %}...{% endtooltip %}-- tooltip body content{% card %}...{% endcard %}-- card body content{% sidebar %}...{% endsidebar %}-- sidebar navigation content Template authors are responsible for escaping any user-controlled values within these blocks using Django's standard{{ var }}auto-escaping.
- Gallery examples for all template tags: Added curated gallery examples for ~130 previously orphan template tags in
gallery/examples.py. Every registered tag now has at least one example with realistic default data, grouped by category (layout, form, overlay, feedback, data, navigation, indicator, typography, misc). Updated the orphan-tags test to exclude child-only tags (tags rendered by their parent, e.g.sidebar_item,nav_item,filter_select) from the orphan check. The gallerytest_no_orphan_tagswarning is now fully eliminated. (#GALLERY-EXAMPLES)
- Code quality — split monolithic files (#CODE-SPLIT): Split
templatetags/djust_components.py(14,483 lines) into per-category sub-modules:_charts.py(985 lines),_dev_tools.py(549 lines),_advanced.py(2,323 lines),_forms.py(1,567 lines), with shared registry in_registry.py. Main file reduced to 9,115 lines. All tags still load via{% load djust_components %}. Moved all inlineimport json/re/calendar/datetimeto module-level imports acrossrust_handlers.pyandtemplatetags/djust_components.py. Fixed indentation issues inrust_handlers.pyexposed by the cleanup. - Shared utilities (#SHARED-UTILS): Created
src/djust_components/utils.pycentralisingCURRENCY_SYMBOLS,format_cell(),interpolate_color(), andinterpolate_color_gradient()— previously duplicated acrosstemplatetags/djust_components.py,rust_handlers.py,mixins/data_table.py,components/currency_input.py, andcomponents/heatmap.py. All call sites now import fromutils.py. - Fix mutable class-level defaults in
DataTableMixin: Changed 12 mutable list/dict class attributes (e.g.table_columns,table_bulk_actions,table_footer_aggregations) from[]/{}toNone.init_table_state()resolvesNoneto fresh instances, preventing shared-mutation bugs across subclass instances. - Shared test infrastructure (
tests/conftest.py): Extracted duplicated boilerplate from all 38 test files into a single conftest — djust module stubs,djust.decoratorsstub, and Djangosettings.configure()now run once via pytest's conftest mechanism. (#TEST-INFRA) - Dynamic gallery discovery test:
test_discover_component_classesnow asserts againstcomponents.__all__instead of a hardcoded set, so it no longer breaks when new component classes are added. - Fixed pre-existing test bug: component class tests (
test_expandable_text_class,test_truncated_list_class, etc.) now pass because the shared stub includesComponent.render().
- v2.0 Final Batch — Remaining Components: 12 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Map Picker (
{% map_picker lat=lat lng=lng pick_event="set_location" %}) — Click-to-pick location on a Leaflet/OSM map with marker. Usesdj-hook="MapPicker". Supportslat,lng,pick_event,zoom,height,class. Also available as Python classMapPicker(lat=..., lng=..., pick_event=...). (#76b) - Prompt Template Editor (
{% prompt_editor template=t variables=v event="save_prompt" %}) — Template editing with{{variable}}highlighting, variable chips, and live preview. Supportstemplate,variables,event,placeholder,rows,class. Also available as Python classPromptEditor(template=..., variables=...). (#158) - Voice Input Button (
{% voice_input event="transcribe" lang="en-US" %}) — Mic button with recording pulse animation using Web Speech API. Usesdj-hook="VoiceInput". Supportsevent,lang,continuous,class. Also available as Python classVoiceInput(event=..., lang=...). (#164) - Cron Expression Input (
{% cron_input name="schedule" value="0 9 * * 1-5" event="set_schedule" %}) — Visual cron builder with five labeled fields and preview. Supportsname,value,event,class. Also available as Python classCronInput(name=..., value=...). (#145) - Error Page (
{% error_page code=404 title="Not Found" %}) — Styled error page with large code display, title, message, and action button. Supportscode,title,message,action_url,action_label,class. Also available as Python classErrorPage(code=404, title=...). (#136) - Image Upload Preview (
{% image_upload_preview name="photos" max=5 event="upload" %}) — Multi-image upload drop zone with thumbnail previews. Usesdj-hook="ImageUploadPreview". Supportsname,max,event,accept,previews,class. Also available as Python classImageUploadPreview(name=..., max=5). (#137) - Number Animation (
{% animated_number value=revenue prefix="$" duration=800 %}) — Animated counting number with prefix/suffix and thousands separator. Usesdj-hook="AnimatedNumber". Supportsvalue,prefix,suffix,duration,decimals,separator,class. Also available as Python classAnimatedNumber(value=..., prefix=...). (#141) - Ribbon Badge (
{% ribbon text="Popular" variant="primary" position="top-right" %}) — Corner ribbon overlay badge with variant colors and four corner positions. Supportstext,variant(primary/success/warning/danger),position(top-left/top-right/bottom-left/bottom-right),class. Also available as Python classRibbon(text=..., variant=...). (#151) - Breadcrumb Dropdown (
{% breadcrumb_dropdown items=items %}) — Breadcrumb navigation with overflow collapse into ellipsis dropdown menu. Supportsitems(list of label/url dicts),max_visible,separator,class. Also available as Python classBreadcrumbDropdown(items=...). (#115) - Data Card Grid (
{% data_card_grid items=items columns=3 %}) — Filterable responsive card grid with category filter bar, images, and click events. Supportsitems,columns,filter_key,event,class. Also available as Python classDataCardGrid(items=..., columns=3). (#92) - Agent Step Card (
{% agent_step tool="search_db" status="complete" %}Found 12 results{% endagent_step %}) — AI agent tool-use step card with status icons (pending/running/complete/error), tool name, duration, and content. Supportstool,status,duration,class. Also available as Python classAgentStep(tool=..., status=...). (#154) - QR Code (
{% qr_code data="https://example.com" size="md" %}) — Pure SVG QR code with finder patterns, configurable size (sm/md/lg), and custom colors. Supportsdata,size,fg_color,bg_color,class. Also available as Python classQRCode(data=..., size=...). (#157)
- Map Picker (
- v2.0 Batch 5 — Collaboration Suite: 5 new djust-native real-time components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Cursors Overlay (
{% cursors users=online_users %}) — Google Docs-style cursor overlay showing other users' cursor positions in real-time with colored SVG arrows and name labels. Usesdj-hook="CursorsOverlay". Designed to pair with PresenceMixin. Supportsusers(list of name/color/x/y dicts),class. Also available as Python classCursorsOverlay(users=...). (#77) - Live Indicator (
{% live_indicator user=editing_user field="title" %}) — Per-field "Alice is typing..." indicator with animated bouncing dots, optional avatar, and configurable action text.role="status"witharia-live="polite". Supportsuser,field,action,active,class. Also available as Python classLiveIndicator(user=..., field=...). (#78) - Collaborative Selection (
{% collab_selection users=users %}) — Highlights text/cells other users have selected with colored backgrounds, underlines, and user labels. Usesdj-hook="CollabSelection". Supportsusers(list of name/color/text/start/end dicts),class. Also available as Python classCollabSelection(users=...). (#79) - Activity Feed (
{% activity_feed events=events stream="activity_update" %}) — Real-time activity stream with user avatars/initials, action text, targets, timestamps, and optional WebSocket streaming viadj-hook="ActivityFeed".role="feed"withrole="article"items. Supportsevents,stream,max,class. Also available as Python classActivityFeed(events=..., stream_event=...). (#80) - Reactions (
{% reactions options=emojis counts=counts event="react" %}) — Slack-style emoji reaction buttons with live counts, active state tracking, anddj-clickevents withdj-value-emoji.role="group"witharia-pressedtoggle. Supportsoptions,counts,event,active,class. Also available as Python classReactions(options=..., counts=..., event=...). (#81)
- Cursors Overlay (
- v2.0 Batch 4 — Enterprise + Specialized Components: 7 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Calendar View (
{% calendar events=events month=month year=year %}) — Month calendar grid with event slots, day-click events, overflow "+N more" indicator, and configurable first-day-of-week.role="grid". Supportsevents,month,year,view,start_day,event,class. Also available as Python classCalendarView(events=..., month=3, year=2026). (#68) - Gantt Chart (
{% gantt_chart tasks=tasks %}) — SVG timeline bar chart for project management with task labels, progress fill, grid lines, and unit headers. Supportstasks(list of name/start/duration/color/progress dicts),title,unit_label,units,row_height,width,class. Also available as Python classGanttChart(tasks=...). (#69) - Diff Viewer (
{% diff_viewer old=old_text new=new_text %}) — Side-by-side or unified text diff with LCS-based diffing, line numbers, add/delete/equal line highlighting. Supportsold,new,mode(split/unified),title_old,title_new,show_line_numbers,class. Also available as Python classDiffViewer(old=..., new=...). (#72) - Pivot Table (
{% pivot_table data=data rows="category" cols="quarter" values="revenue" agg="sum" %}) — Configurable cross-tab pivot table with row/column/value dimensions, aggregation functions (sum/avg/count/min/max), row/column/grand totals.role="grid". Supportsdata,rows,cols,values,agg,title,show_totals,class. Also available as Python classPivotTable(data=..., rows=..., cols=..., values=...). (#119) - Org Chart (
{% org_chart nodes=nodes root=ceo_id %}) — Hierarchical tree visualization with node cards (avatar/initials, name, title), auto-root detection, vertical/horizontal direction, and click events.role="tree". Supportsnodes,root,event,direction,class. Also available as Python classOrgChart(nodes=..., root=...). (#120) - Comparison Table (
{% comparison_table plans=plans features=features %}) — SaaS pricing/feature comparison grid with plan highlighting, boolean check/cross rendering, price display, and click events.role="grid". Supportsplans,features,event,class. Also available as Python classComparisonTable(plans=..., features=...). (#101) - Masonry Grid (
{% masonry_grid items=items columns=3 %}) — Pinterest-style layout with shortest-column-first distribution, configurable columns/gap via CSS custom properties.role="list". Supportsitems,columns,gap,class. Also available as Python classMasonryGrid(items=..., columns=3). (#102)
- Calendar View (
- v2.0 Batch 3 — Developer Tools + Specialized Components: 6 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Terminal (
{% terminal output=lines %}) — Monospace terminal emulator with ANSI color support, title bar with traffic-light dots, line numbers, and streaming. Usesdj-hook="Terminal". Supportsoutput,title,stream_event,show_line_numbers,wrap,class. Also available as Python classTerminal(output=..., title=...). (#73b) - Markdown Editor (
{% markdown_editor name="content" preview=True %}) — Split-pane editor with live preview, formatting toolbar (bold, italic, code, link, heading), anddj-hook="MarkdownEditor". Supportsname,value,preview,toolbar,placeholder,rows,disabled,event,class. Also available as Python classMarkdownEditor(name=..., preview=True). (#74b) - JSON Viewer (
{% json_viewer data=json_data collapsed_depth=2 %}) — Interactive collapsible JSON tree with syntax-colored values (string, number, boolean, null), expand/collapse toggles, copy button, anddj-hook="JsonViewer". Supportsdata,collapsed_depth,root_label,copy_button,class. Also available as Python classJsonViewer(data=..., collapsed_depth=2). (#122) - Log Viewer (
{% log_viewer lines=log_lines stream_event="new_logs" %}) — Monospace streaming log display with automatic level detection (INFO/WARN/ERROR/DEBUG) and color coding, line numbers, auto-scroll, filtering, anddj-hook="LogViewer".role="log". Supportslines,stream_event,show_line_numbers,auto_scroll,filter_level,wrap,max_lines,class. Also available as Python classLogViewer(lines=..., stream_event=...). (#123) - File Tree (
{% file_tree nodes=files selected=current_file event="select_file" %}) — File browser tree with folder expand/collapse, file/folder icons, selection highlighting, anddj-hook="FileTree".role="tree"withrole="treeitem"on files. Supportsnodes,selected,event,show_icons,class. Also available as Python classFileTree(nodes=..., selected=..., event=...). (#165) - Tour / Onboarding Guide (
{% tour steps=tour_steps active=0 %}) — Product tour with overlay, spotlight target, popover with title/content, progress dots, next/prev/skip/finish navigation, anddj-hook="Tour".role="dialog". Supportssteps,active,event,show_progress,show_skip,class. Also available as Python classTour(steps=..., active=0). (#121)
- Terminal (
- v2.0 Batch 2 — Data Visualization Components: 7 new pure-SVG components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Bar Chart (
{% bar_chart data=data labels=labels %}) — Pure SVG bar chart with hover tooltips, value labels, and title. Supportsdata,labels,title,width,height,color,show_values,class. Also available as Python classBarChart(data=..., labels=...). (#94) - Line Chart (
{% line_chart series=series labels=labels %}) — SVG line/area chart with multiple series, dots, and legend. Supportsseries,labels,title,width,height,area,show_dots,show_legend,class. Also available as Python classLineChart(series=..., labels=...). (#95) - Pie / Donut Chart (
{% pie_chart segments=segments %}) — SVG pie/donut chart with percentage labels, hover tooltips, and legend. Supportssegments,title,width,height,donut,inner_radius,show_labels,show_legend,class. Also available as Python classPieChart(segments=...). (#96) - Sparkline (
{% sparkline data=values %}) — Lightweight inline SVG chart for embedding in text/tables. Line, bar, and area variants. Supportsdata,variant,width,height,color,stroke_width,class. Also available as Python classSparkline(data=..., variant="line"). (#75b) - Heatmap (
{% heatmap data=matrix x_labels=x y_labels=y %}) — Color-coded grid with interpolated colors, value labels, and axis labels. Supportsdata,x_labels,y_labels,title,color_min,color_max,cell_size,show_values,class. Also available as Python classHeatmap(data=..., x_labels=..., y_labels=...). (#97) - Treemap (
{% treemap data=data value_key="size" label_key="name" %}) — Nested rectangles for hierarchical data with auto-sized labels. Supportsdata,value_key,label_key,title,width,height,class. Also available as Python classTreemap(data=..., value_key="size", label_key="name"). (#100) - Calendar Heatmap (
{% calendar_heatmap data=activity_data year=2026 %}) — GitHub-style contribution heatmap with 5-level color scale, month/day labels, and tooltips. Supportsdata,year,title,cell_size,cell_gap,show_month_labels,show_day_labels,class. Also available as Python classCalendarHeatmap(data=..., year=2026). (#135)
- Bar Chart (
- v2.0 Batch 1 — Drag & Interactive Components: 7 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Sortable List (
{% sortable_list items=items move_event="reorder" %}) — Drag-and-drop reorderable list with handle, disabled state, anddj-hook="SortableList". Items are<li>elements withdraggableanddata-id. Supportsitems,move_event,handle,disabled,class. Also available as Python classSortableList(items=..., move_event=...). (#67b) - Sortable Grid (
{% sortable_grid items=items columns=3 move_event="reorder" %}) — 2D drag-and-drop grid layout withdj-hook="SortableGrid". Supports thumbnails, configurable columns and gap. Supportsitems,columns,move_event,gap,disabled,class. Also available as Python classSortableGrid(items=..., columns=3). (#173) - Image Cropper (
{% image_cropper src=image_url crop_event="save_crop" %}) — Drag-to-crop with optional aspect ratio lock viadj-hook="ImageCropper". Canvas with overlay, selection box, crop/reset buttons. Supportssrc,crop_event,aspect_ratio,min_width,min_height,disabled,class. Also available as Python classImageCropper(src=..., crop_event=...). (#70) - Signature Pad (
{% signature_pad name="sig" save_event="save_signature" %}) — Canvas-based signature capture withdj-hook="SignaturePad". Hidden input for form submission, clear/save buttons. Supportsname,save_event,width,height,pen_color,pen_width,disabled,class. Also available as Python classSignaturePad(name=..., save_event=...). (#71) - Resizable Panel (
{% resizable_panel direction="horizontal" %}...{% endresizable_panel %}) — Container with drag-to-resize handle viadj-hook="ResizablePanel". Horizontal/vertical directions, min/max/initial size. Handle hasrole="separator"withtabindex. Supportsdirection,min_size,max_size,initial_size,disabled,class. Also available as Python classResizablePanel(direction=..., content=...). (#114) - Image Lightbox (
{% lightbox images=gallery open=True active=0 %}) — Full-screen image viewer overlay with prev/next navigation, "N of M" counter, captions, and keyboard/close support viadj-hook="ImageLightbox". Hidden whenopen=False. Supportsimages,active,open,close_event,navigate_event,show_counter,class. Also available as Python classImageLightbox(images=..., open=True). (#99) - Dashboard Grid (
{% dashboard_grid panels=panels columns=4 %}...{% enddashboard_grid %}) — CSS Grid with draggable, resizable panels viadj-hook="DashboardGrid". Each panel has positioned header with drag handle, body, and resize corner. Supportspanels,columns,row_height,gap,move_event,resize_event,class. Also available as Python classDashboardGrid(panels=..., columns=4). (#93)
- Sortable List (
- Composition Guide (
docs/COMPOSITION_GUIDE.md) — Documents common component nesting patterns: Card + Tabs, Modal + Form, Toolbar + Data Table, Sidebar + Breadcrumb, Modal + Approval Gate, Dashboard stat cards, and toast notifications from LiveView handlers. (#COMP-GUIDE) - Server-side Helpers Module (
from djust_components.helpers import push_toast, confirm_action) — Python utilities that pair with component template tags to reduce boilerplate in LiveView event handlers.push_toast()builds a dict for{% dj_toast %},confirm_action()builds a dict for{% approval_gate %}. Input validation for type/risk/duration. (#HELPERS) - Component Presets (
{% dj_button preset="danger-confirm" %}) — Preset registry that maps short names to predefined parameter sets. Ships with built-in button presets:danger-confirm,danger-sm,primary-lg,ghost-sm,success,warning,link,loading. Custom presets viaregister_preset(). Explicit kwargs override preset values. (#PRESETS)
- v1.5 Remaining Components: 15 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Time Picker (
{% time_picker name="start_time" value="14:30" event="set_time" %}) -- Hour/minute selector with AM/PM toggle or 24h format. Supportsname,value,event,format_24h,step,disabled,label,class. Also available as Python classTimePicker(name=..., value=...). (#117) - Wizard / Multi-step Form (
{% wizard steps=steps active=current %}...{% endwizard %}) -- Form split across numbered steps with per-step validation. Step indicators with completed/active states and connector lines. Supportssteps,active,event,show_numbers,class. Also available as Python classWizard(steps=..., active=...). (#111) - Bottom Sheet (
{% bottom_sheet open=True title="Filters" %}...{% endbottom_sheet %}) -- Mobile-optimized drawer from bottom with drag handle bar and backdrop. Supportstitle,open,close_event,class. Also available as Python classBottomSheet(title=..., open=True). (#112) - Infinite Scroll (
{% infinite_scroll load_event="load_more" threshold="200px" %}...{% endinfinite_scroll %}) -- Fires event on scroll near bottom usingdj-hook="InfiniteScroll". Loading spinner and "no more items" states. Supportsload_event,threshold,loading,finished,class. Also available as Python classInfiniteScroll(load_event=...). (#113) - Countdown / Timer (
{% countdown target="2026-04-01T00:00:00" event="timer_done" %}) -- Days/hours/minutes/seconds countdown usingdj-hook="Countdown". Configurable segment visibility.role="timer". Supportstarget,event,show_days,show_seconds,labels,class. Also available as Python classCountdown(target=...). (#126) - Cookie Consent Banner (
{% cookie_consent accept_event="accept_cookies" %}{% endcookie_consent %}) -- GDPR-compliant banner with accept/reject actions, privacy policy link, and fixed top/bottom positioning.role="banner". Supportsmessage,accept_event,reject_event,accept_label,reject_label,privacy_url,show_reject,position,class. Also available as Python classCookieConsent(accept_event=...). (#127) - Form Array (
{% form_array name="items" min=1 max=10 add_event="add_row" remove_event="remove_row" %}...{% endform_array %}) -- Dynamic add/remove form rows with min/max constraints. Row inputs with remove buttons and disabled add when max reached. Supportsname,rows,min,max,add_event,remove_event,add_label,class. Also available as Python classFormArray(name=..., rows=...). (#170) - Scroll Spy (
{% scroll_spy sections=section_ids active_event="section_changed" %}) -- IntersectionObserver-based active section tracking usingdj-hook="ScrollSpy". Navigation links with active highlighting.role="navigation". Supportssections,active,active_event,offset,class. Also available as Python classScrollSpy(sections=...). (#172) - Page Alert / Banner (
{% page_alert type="success" dismissible=True %}Saved!{% endpage_alert %}) -- Full-width content-area alert with variant styling (info/success/warning/error). Optional icon and dismiss button.role="alert". Supportstype,dismissible,dismiss_event,icon,class. Also available as Python classPageAlert(message=..., type=...). (#142) - Dropdown Menu (
{% dropdown_menu label="Actions" open=True items=items %}{% enddropdown_menu %}) -- Structured menu with keyboard nav support. Supports item dicts or child{% menu_item %}/{% menu_divider %}tags. Danger/disabled item variants. ARIArole="menu"/role="menuitem"/role="separator". Supportslabel,items,open,toggle_event,align,class. Also available as Python classDropdownMenu(label=..., items=...). (#143) - Meter / Stacked Progress (
{% meter segments=usage_data total=100 %}) -- Multiple colored segments in horizontal bar with optional legend.role="meter". Supportssegments(list of value/color/label dicts),total,label,show_legend,class. Also available as Python classMeter(segments=..., total=100). (#148) - Export Dialog (
{% export_dialog formats=formats columns=export_cols event="export" open=True %}) -- Modal with format picker (radio buttons) and column selection (checkboxes). Backdrop with close. Supportsformats,columns,event,open,close_event,selected_format,title,class. Also available as Python classExportDialog(formats=..., columns=...). (#161) - Import Wizard (
{% import_wizard accepted_formats=".csv,.xlsx" model_fields=fields event="import_data" %}) -- Multi-step import flow with upload dropzone, field mapping, and preview steps. Step indicator with completed/active states. Supportsaccepted_formats,model_fields,event,step,upload_event,class. Also available as Python classImportWizard(accepted_formats=..., model_fields=...). (#162) - Audit Log Table (
{% audit_log entries=entries stream_event="new_entry" %}) -- Pre-configured data table for audit log entries. Color-coded action types (create/update/delete). Empty state. Supportsentries(list of timestamp/user/action/resource/detail dicts),stream_event,columns,class. Also available as Python classAuditLog(entries=...). (#163) - Error Boundary (
{% error_boundary fallback="Component failed to render" %}...{% enderror_boundary %}) -- Catches rendering errors and shows fallback message with optional retry button.role="alert"on error state. Supportsfallback,retry_event,class. Also available as Python classErrorBoundary(fallback=...). (#174)
- Time Picker (
- Text Display + Loading Pattern Components: 5 new components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Expandable Text (
{% expandable_text max_lines=3 %}...{% endexpandable_text %}) — Truncates long text with CSS-webkit-line-clampand provides a "Read more" / "Show less" toggle button. Supportsmax_lines,expanded,toggle_event,more_label,less_label,class. Also available as Python classExpandableText(text=..., max_lines=3). (#118) - Truncated List (
{% truncated_list items=assignees max=3 %}) — Shows first N items from a list with "+X more" overflow badge. Click expands to show all. Supports dict items (withlabel/namekey) or plain strings. Supportsitems,max,expanded,toggle_event,overflow_label,class. ARIArole="list". Also available as Python classTruncatedList(items=..., max=3). (#150) - Inline Markdown Preview (
{% markdown_textarea name="content" preview=True %}) — Textarea with Write/Preview tab toolbar. Preview mode shows rendered markdown content with hidden input preserving form value. Usesdj-hook="MarkdownTextarea"for client-side rendering. Supportsname,value,preview,toggle_event,placeholder,rows,disabled,class. Also available as Python classMarkdownTextarea(name=..., preview=True). (#169) - Skeleton Factory (
{% skeleton_for component="data_table" columns=5 rows=10 %}) — Auto-generates skeleton loading placeholders matching common component layouts. Supportsdata_table(header + body rows),card(image + text lines),list(circle + line items),text(varied-width lines). Shimmer pulse animation. Supportscomponent,columns,rows,class. ARIArole="status". Also available as Python classSkeletonFactory(component=..., columns=5, rows=10). (#144) - Content Loader / Suspense (
{% await loading_event="data_loaded" %}...{% endawait %}) — Shows placeholder content (e.g. skeleton) until server event signals ready. Three states: loading (placeholder withrole="status"), loaded (actual content with fade-in), error (alert with optional retry button). Supportsloading_event,loaded,error,error_event,class. Also available as Python classContentLoader(loading_event=..., loaded=False, placeholder=...). (#152)
- Expandable Text (
- Collaboration Components: 3 new collaboration components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Chat Bubble (
{% chat_bubble message=msg %}) — Single message bubble UI with sender avatar (image or initials fallback), timestamp, and delivery status indicator. Status variants: sending (hourglass), sent (single check), delivered (double check), read (colored double check), error (warning). Supportsmessage(dict with sender/name/text/time/avatar/status),class. User messages right-aligned, other messages left-aligned. Also available as Python classChatBubble(message=...). (#55) - Presence Avatars (
{% presence_avatars users=online_users max=5 %}) — Stacked overlapping avatar group with presence status dots. Status variants: online (green), away (yellow), busy (red), offline (gray). Supports dict users or Django user objects. Overflow "+N" count. Z-index stacking. ARIArole="group"with user count label. Pairs with djust PresenceMixin. Supportsusers,max,class. Also available as Python classPresenceAvatars(users=..., max_display=5). (#56) - Mentions / @Input (
{% mentions_input name="msg" users=users event="send" %}) — Text input with user mention dropdown triggered by @ character. Renders suggestion list with avatars and names. Usesdj-hook="MentionsInput"for client-side @ detection. Supportsname,users(list of dicts with id/name/avatar),event,placeholder,disabled,class. ARIArole="listbox"/role="option". Also available as Python classMentionsInput(name=..., users=...). (#57)
- Chat Bubble (
- AI Trust/Transparency Components: 4 new AI trust components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Approval Gate (
{% approval_gate message="Delete 47 records?" risk="high" approve_event="confirm" reject_event="cancel" %}) — Inline confirmation card for AI agent actions. Risk levels: low/medium/high/critical with color-coded borders, icons (info circle for low/medium, warning triangle for high/critical), and approve/reject buttons. Supportsmessage,risk,approve_event,reject_event,approve_label,reject_label,class. ARIArole="alert". Also available as Python classApprovalGate(...). (#155) - Source Citation (
{% source_citation index=1 title="API Docs" url=url relevance=0.92 %}) — Inline footnote marker with hover popover showing source details. Superscript[N]marker reveals popover with title, clickable URL, and relevance percentage on hover. Supportsindex,title,url,relevance(0-1 float),class. Also available as Python classSourceCitation(...). (#156) - Model Selector (
{% model_selector name="model" options=models value=current %}) — Rich select with model metadata. Each option displays name, description, context window size, and pricing tier badge (free/standard/premium/enterprise). Supportsname,options(list of dicts),value,event,placeholder,disabled,label,class. ARIArole="combobox"androle="listbox". Also available as Python classModelSelector(...). (#131) - Token Counter (
{% token_counter current=tokens max=max_tokens %}) — Compact progress display showing token usage vs limit. Color transitions: green (ok, <60%), yellow (warn, 60-85%), red (danger, >85%). Auto-generated comma-formatted label. Supportscurrent,max,label,show_label,class. ARIArole="meter". Also available as Python classTokenCounter(...). (#132)
- Approval Gate (
- AI Chat Interface Components: 4 new AI chat components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Conversation Thread (
{% conversation_thread messages=messages stream_event="new_message" %}) — Chat-style message thread with sender avatars (initial-based), timestamps, message grouping for consecutive same-sender messages, and animated streaming response indicator (bouncing dots). Supportsmessages(list of dicts with sender/name/text/time),stream_event,streaming,class. Also available as Python classConversationThread(messages=..., streaming=True). (#130) - AI Thinking Indicator (
{% thinking_indicator status="thinking" label="Analyzing data..." %}) — Animated status indicator with 4 animation modes:thinking(bouncing dots),searching(pulse),generating(cursor blink),tool_use(spinner). Returns empty string foridlestatus. Invalid statuses default tothinking. ARIArole="status". Supportsstatus,label,class. Also available as Python classThinkingIndicator(status=..., label=...). (#160) - Multimodal Input (
{% multimodal_input name="message" accept_files=True accept_voice=True event="send" %}) — Text area with optional file attachment button (paperclip icon, hidden file input), optional voice input button (microphone icon), and send button (arrow icon). Auto-resizing textarea. Supportsname,event,placeholder,accept_files,accept_voice,file_accept,disabled,class. Also available as Python classMultimodalInput(...). (#159) - Feedback Widget (
{% feedback event="rate_response" mode="thumbs" %}) — Quick feedback for AI responses with 3 modes:thumbs(up/down SVG icons),stars(1-5 star rating with fill state),emoji(5 reaction emojis). Active state highlighting. ARIArole="group". Supportsevent,mode,value,class. Also available as Python classFeedbackWidget(event=..., mode=..., value=...). (#149)
- Conversation Thread (
- Social / User-Facing Components: 3 new social components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Avatar Group (
{% avatar_group users=users max=5 %}) — Stacked overlapping avatar circles with "+N" overflow count. Supports dict users (name, avatar/src) or Django user objects. Renders initials fallback when no avatar URL. Configurablemax,size(sm/md/lg),class. Z-index stacking for proper overlap. CSS custom properties for full theming. Also available as Python classAvatarGroup(users=..., max_display=5). (#89) - Hover Card (
{% hover_card trigger="@user" %}...{% endhover_card %}) — Rich content card on hover with configurable delay-in/delay-out. GitHub-style user hovercards. Supportstrigger,position(top/bottom/left/right),delay_in(ms),delay_out(ms),class. Pure CSS show/hide withdata-delay-*attributes for JS enhancement. Also available as Python classHoverCard(trigger=..., content=...). (#91) - Notification Popover (
{% notification_popover notifications=notifs unread_count=count mark_read_event="mark_read" %}) — Bell icon with unread badge count + toggleable popover notification list. Badge shows "99+" overflow. Renders notification items with title, body, time, read state. Unread items firemark_read_eventon click. Supportstoggle_event,open,title,class. Empty state message. SVG bell icon. Also available as Python classNotificationPopover(...). (#168)
- Avatar Group (
- Toolbar & Editing Components: 3 new toolbar/editing components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Toolbar (
{% toolbar %}...{% endtoolbar %}) — Horizontal action bar with grouped buttons, separators ({% toolbar_separator %}), overflow menu ({% toolbar_overflow %}). Supportsid,size(sm/md/lg),variant(default/flat),class. Overflow menu reveals hidden actions on hover. ARIArole="toolbar"androle="separator". Responsive wrapping on mobile. (#87) - Inline Edit (
{% inline_edit value=title event="update_title" %}) — Click text to edit in-place. Display mode shows value with pencil icon on hover. Editing mode shows focused input with save on Enter/blur, cancel on Escape. Supportsvalue,event,field,type(text/number/etc.),placeholder,editing,class. Usesdj-keydown.enter,dj-blur,dj-keydown.escapedirectives. (#88) - Filter Bar (
{% filter_bar %}...{% endfilter_bar %}) — Horizontal bar composing filter controls with responsive collapse. Sub-tags:{% filter_select name="status" options=statuses %},{% filter_date_range name="dates" %},{% filter_search name="q" %}. Auto-shows "Clear filters" button when any filter has a value. Supportsid,event,clear_event,class. Select supportsoptions(list of strings or{value, label}dicts),value. Date range supportsstart,end,label. Search supportsplaceholder,value,debounce. ARIArole="search". Responsive: stacks vertically on mobile. (#166)
- Toolbar (
- App Chrome Components: 3 new layout/navigation components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Sidebar Nav (
{% sidebar %}...{% endsidebar %}) — Collapsible sidebar navigation with nested menu items ({% sidebar_item %}), section headers ({% sidebar_section %}), icons, active state highlighting, toggle event, mobile drawer with backdrop overlay. Supportsid,title,active,collapsed,toggle_event,class. Items supportlabel,href,icon,event, nested children. (#86) - Navigation Menu (
{% nav_menu %}...{% endnav_menu %}) — Top horizontal navigation bar with brand logo, dropdown sub-menus, mega-menu support (mega=True), active route highlighting, mobile hamburger collapse. Uses{% nav_item %}for menu entries with optional dropdown children and descriptions. Supportsbrand,brand_href,toggle_event,mobile_open,active,class. (#90) - App Shell (
{% app_shell %}...{% endapp_shell %}) — Complete responsive layout wrapper combining sidebar, header, and content regions. Uses{% app_sidebar %},{% app_header %},{% app_content %}sub-tags. Semantic HTML (<aside>,<header>,<main>). Supportssidebar_collapsed,class,id. Responsive: stacks vertically on mobile. (#167)
- Sidebar Nav (
- Django Integration Components: 2 new template tags bridging Django's form/model system with djust-components:
- Django Form Renderer (
{% dj_form form=form %}) — Auto-renders any Django Form or ModelForm using djust-components. Maps field types to components:CharField->dj_input,EmailField->email input,ChoiceField/ModelChoiceField->dj_select,BooleanField->dj_checkbox,Textareawidget->dj_textarea,RadioSelect->radio group,FileField->file input,PasswordInput->password input, and more. Handles non-field errors, per-field errors, help text, required markers, disabled state, hidden fields. Supportsevent_prefix,action,method,submit_label,submit_event,custom_class,show_errors. All user values escaped viaconditional_escape()(#73) - Django ModelForm Table (
{% model_table queryset=qs %}) — Auto-generates a data table from a Django QuerySet. Introspects model_metato infer columns with labels, sortable/filterable flags, and filter types. Converts QuerySet rows to table data. Supportsexclude/includefor column selection, sorting, search, pagination, row selection, loading state, filters (text/select/number), striped/compact styling,custom_class. Skips reverse relations, handles ForeignKey display viastr(), choice fields with filter options. All output escaped (#74)
- Django Form Renderer (
- Data Table Pro Phase 5 — Data Import & Computed: 5 new opt-in features for
DataTableHandler,DataTableMixin, and{% data_table %}:- CSV/JSON Import:
importable=Trueadds Import CSV/JSON toolbar buttons with file upload. Parsed rows are validated against table columns and staged for preview before confirming.import_eventfires with parsed rows. Supportsimport_formats,import_preview(preview before confirm), andhandle_import()override hook. - Computed Columns:
computed_columnslist of{key, label, expression}dicts defines virtual columns evaluated server-side. Expressions support basic arithmetic (revenue - cost,qty * price) with column references.evaluate_computed_columns()injects values into rows. Computed columns render with italic styling. - Cell Merge / Colspan: Rows with
_mergekey (configurable viacell_merge_key) specify horizontal cell merging. Format:{_merge: {col_key: colspan_int}}. Merged cells render withcolspanattribute; absorbed cells are hidden. - Column Expressions:
column_expressionsdict enables advanced per-column filter inputs. Supports> N,>= N,< N,<= N,= N,!= N,contains "text",startswith "text",endswith "text",between N and M,empty,not empty. Expression inputs render in a separate header row with debounced events. - Conditional Formatting Presets:
conditional_formattinglist of preset dicts. Three types:data_bar(percentage fill bar behind cell),color_scale(background color interpolated between 2-3 colors),icon_set(prepend icon based on threshold ranges). All types support configurablemin/maxrange.
- CSV/JSON Import:
- Data Table Pro Phase 4 — Data Presentation: 6 new opt-in features for
DataTableHandler,DataTableMixin, and{% data_table %}:- Column Type Formatters: Declare
typeon column config (number,currency,date,percentage,boolean) for automatic display formatting. Supportsdecimals,currency_symbol,true_label/false_label,date_format. Type-specific CSS classes (data-table-type-number, etc.) for alignment. - Footer Aggregation Row: Optional
footer_aggregationsdict ({col_key: "sum"|"avg"|"count"|"min"|"max"}) renders a<tfoot>row with computed values per column. - Conditional Row/Cell Styling:
row_class_map(dict or callable) applies CSS classes to<tr>based on data values.cell_classon column config (string or value-keyed dict) applies classes to<td>. - Multi-Level Column Headers:
column_groupslist of{label, columns}renders a grouped header row withcolspanspanning sub-columns. - Row Drag-and-Drop Reorder:
row_drag=Trueadds a grip handle column; firesrow_drag_eventwith{old_index, new_index}. Mixin auto-reorderstable_rows. - Copy Row/Selection:
copyable=Trueadds a Copy toolbar button; firescopy_event. Mixin generates CSV/TSV intable_copy_data.
- Column Type Formatters: Declare
-
Cascading Form Components: 3 new form components with Django template tags, Rust engine handlers, Python component classes, CSS, and tests (including XSS coverage):
- Dependent Select (
{% dependent_select name="city" parent="country" source_event="load_cities" %}) — Cascading dropdown that reloads options when parent field changes. Spinner while loading (loading). Supportsparent,source_event,options(dict/string list),value,placeholder,label,required,disabled,error,custom_class. Usesdj-changeevent anddata-parent/data-source-eventattributes for wiring (#108) - Currency Input (
{% currency_input name="price" currency="USD" min=0 %}) — Numeric input with currency symbol prefix, currency code suffix, andtype="number"with configurablestep/min/max. Built-in symbol lookup for 12 currencies (USD, EUR, GBP, JPY, etc.). Supportscurrency,value,step,min,max,placeholder,label,required,disabled,error,event,custom_class. Tabular-nums and hidden spin buttons in CSS (#109) - Form Validation Display (
{% form_errors form=form %}/{% field_error field=form.email %}) — Two tags for rendering Django form validation errors.form_errorsrenders non-field errors as a styled alert list.field_errorrenders inline per-field error messages. Both acceptcustom_class. ARIArole="alert"for accessibility (#110)
- Dependent Select (
-
Confirmation Dialog (
{% confirm_dialog message="Delete?" confirm_event="delete" %}): Reusable yes/no modal pattern wrapping existing Modal conventions. Renders only whenopen=True. Supportstitle,message,confirm_event,cancel_event,variant(default/danger),confirm_label,cancel_label,custom_class. Danger variant highlights title and confirm button in destructive color. ARIAalertdialogrole witharia-modal. Backdrop click dismisses. Template tag, Rust engine handler (ConfirmDialogHandler), CSS, and tests including XSS coverage (#75) -
Popconfirm (
{% popconfirm message="Delete this item?" confirm_event="delete" %}...{% endpopconfirm %}): Inline confirmation popover that appears next to the trigger element — less disruptive than a modal. Block tag wraps any trigger content. Auto-positioned withplacement(top/bottom/left/right). Supportsmessage,confirm_event,cancel_event,confirm_label,cancel_label,variant(default/danger),custom_class,id. Client-side toggle/dismiss via inline JS. CSS arrows for each placement direction. Template tag, Rust engine handler (PopconfirmHandler), CSS, and tests including XSS coverage (#180)
- Form Essentials (v1.5): 4 new form input components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Slider / Range (
{% slider name="price" min=0 max=100 value=50 %}) — Horizontal slider with optional dual-handle range mode (value_end), configurablestep, tick marks (show_ticks), value display output,dj-inputevent; supportslabel,disabled,custom_class(#82) - Search Input (
{% search_input name="q" placeholder="Search..." event="search" %}) — Input with search icon, clear button, loading spinner state (loading), debounceddj-inputevent (debouncems); supportslabel,value,disabled,custom_class(#83) - Password Input (
{% password_input name="pwd" %}) — Input with show/hide toggle button, optional strength meter bar (show_strength,strength0-4); supportslabel,error,required,disabled,placeholder,custom_class(#84) - Autocomplete (
{% autocomplete name="city" source_event="search_cities" %}) — Input with dropdown suggestions fetched server-side on keystroke;source_eventfor server search, debounced input,min_charsthreshold, suggestion list (dict/tuple/string), hidden value input, ARIA combobox/listbox roles; supportslabel,error,required,loading,disabled,custom_class(#85)
- Slider / Range (
- CSS @layer adoption: All component CSS (
components.css,components-classes.css) is now wrapped in@layer djust-components, giving consumers explicit control over cascade precedence when overriding styles - Animation consistency: Consolidated 17 scattered
@keyframesdeclarations into 9 shared keyframes (dj-spin,dj-pulse,dj-fade,dj-shimmer,dj-slide-in-right,dj-slide-in-up,dj-slide-out-up,dj-flash,dj-counter-roll) defined once outside the layer; all components now reference these shared animations with consistent naming - RTL support via logical properties: Replaced physical CSS properties (
padding-left/padding-right,margin-left/margin-right,border-left/border-right,text-align: left, directionalborder-radius) with CSS logical property equivalents (padding-inline-start/padding-inline-end,margin-inline-start/margin-inline-end,border-inline-start/border-inline-end,text-align: start,border-start-end-radius, etc.) across all flow-relative contexts — components now render correctly in RTL layouts without additional CSS - Hardcoded transition durations: Replaced remaining hardcoded
0.3sand0.2stransition durations in accordion and collapsible icons with design token variables (--duration-normal,--duration-fast)
-
Page Header (
{% page_header title="Products" subtitle="Manage inventory" %}{% page_header_actions %}...{% endpage_header_actions %}{% endpage_header %}): Structured page-level header with title, optional subtitle, optional description, optional breadcrumb slot (direct child content), and right-aligned action buttons area via nested{% page_header_actions %}block tag. Responsive: actions stack below title on mobile (640px breakpoint). Template tags, Rust engine handlers (PageHeaderHandler,PageHeaderActionsHandler), CSS with flexbox layout, and tests including XSS coverage (#179) -
Icon System (
{% icon name="check" size="md" set="heroicons" %}): Shared SVG icon rendering primitive with bundled Heroicons Outline set (60+ icons). Four size presets: xs (12px), sm (16px), md (20px), lg (24px). Extensible viaDJUST_COMPONENTS_ICON_SETSDjango setting for custom icon sets. Python helperrender_icon(name, size, ...)for use in Rust handlers and component classes — eliminates inline SVG paths. Template tag, Rust handler, CSS size classes, and 34 tests including XSS coverage (#178) -
Theme Toggle (
{% theme_toggle current="system" event="set_theme" %}): Light/dark/system mode switcher with sun/moon/monitor icons from the Icon System. Readsprefers-color-scheme, stores preference inlocalStorageunderdjust-themekey, appliesdata-themeattribute to<html>. Optionaldj-clickevent for server-side persistence viaeventparameter. ARIA radiogroup with labeled buttons. Client-side JS with MutationObserver for LiveView compatibility, system theme media query listener. Template tag, Rust handler, CSS (inline-flex button group with active state), JS, and 24 tests including XSS coverage (#138) -
Utility Components: 5 new utility components with Django template tags, Rust engine handlers, Python component classes, client-side JS, CSS, and tests (including XSS coverage):
- Scroll to Top (
{% scroll_to_top threshold="300px" %}) — Floating button appearing after scroll threshold, smooth-scrolls to top on click; supportsthreshold,label,custom_class; client-side only (#125) - Code Snippet (
{% code_snippet language="bash" code="pip install djust" %}) — Code block with language badge and copy-to-clipboard button; supportscode,language,custom_class; client-side JS for clipboard API (#139) - Responsive Image (
{% responsive_image src=url alt="..." aspect_ratio="16/9" lazy=True %}) — Picture element withsrcset,sizes, native lazy loading, blur-up placeholder transition; supportssrc,alt,aspect_ratio,lazy,srcset,sizes,placeholder,custom_class(#140) - Relative Time (
{% relative_time datetime=created_at auto_update=True %}) — Displays datetime as "3 hours ago" with client-side auto-update interval; supportsdatetime(string or object),auto_update,interval,custom_class(#146) - Copyable Text (
{% copyable_text %}your-api-key{% endcopyable_text %}) — Inline click-to-copy with "Copied!" tooltip feedback; supportscopied_label,custom_class; block tag with content (#153)
- Scroll to Top (
-
Component Classes: 5 new Python component classes —
ScrollToTop,CodeSnippet,ResponsiveImage,RelativeTime,CopyableText -
Client-side JS: 5 new JS modules —
scroll-to-top.js,code-snippet.js,responsive-image.js,relative-time.js,copyable-text.js; all with MutationObserver for LiveView compatibility -
CSS: Styles for scroll-to-top (fixed positioning, visibility transition), code snippet (header with language badge and copy button, monospace code block), responsive image (aspect-ratio container, blur-up placeholder transition), relative time (tabular-nums), copyable text (inline monospace with hover state and tooltip)
-
WebSocket-Powered Components: 4 new real-time components with Django template tags, Rust engine handlers, Python component classes, client-side JS, CSS, and tests (including XSS coverage):
- Streaming Text (
{% streaming_text stream_event="stream_chunk" %}) — Renders text arriving incrementally via WebSocket with typing cursor animation; supportsstream_event,text,markdown,auto_scroll,cursor,custom_class; auto-scrolls on new content; client-side JS listener fordjust:<event>events - Connection Status Bar (
{% connection_status %}) — Slim fixed-top bar showing WebSocket state: hidden when connected, yellow "Reconnecting..." when disconnected, green "Reconnected" flash on recovery; hooks into djust client.jsdjust:disconnected/djust:reconnectedlifecycle events; supportsreconnecting_text,connected_text,custom_class - Live Counter (
{% live_counter value=42 label="online" stream_event="counter_update" %}) — Animated counter updating in real-time via WebSocket push with number roll animation on change; supportsvalue,label,stream_event,size(sm/md/lg),custom_class - Server Event Toast (
{% server_toast_container position="top-right" %}+self.push_toast("Saved!", type="success")) — PythonServerEventToastMixinfor LiveViews that sends__toast__events via WebSocket; client-side JS auto-renders toast notifications with auto-dismiss, dismiss button, slide-in/out animations; supportsposition(top-right/top-left/bottom-right/bottom-left/top-center/bottom-center),max_toasts,custom_class; toast types: info/success/warning/error
- Streaming Text (
-
Component Classes: 3 new Python component classes —
StreamingText,ConnectionStatus,LiveCounter; plusServerEventToastMixinfor LiveViews -
Client-side JS: 4 new JS modules —
streaming-text.js,connection-status.js,live-counter.js,toast-container.js; all with MutationObserver for LiveView compatibility -
CSS: Styles for streaming text (cursor animation, auto-scroll container), connection status bar (reconnecting/connected states, flash animation), live counter (size variants, roll animation, tabular-nums), toast container (6 position variants, toast type colors, slide-in/out animations)
-
Rich Select (
{% rich_select name="assignee" options=opts %}): Select dropdown where each option can include icons, images, descriptions, or badges alongside the label; selected value shows the rich display; supportssearchablefilter,disabledstate,label, customevent, hidden input for form submission, ARIA roles (combobox,listbox,option); template tag, Rust handler, Python component class (RichSelect), CSS, and tests with XSS coverage -
Data Grid (
{% data_grid columns=cols rows=rows %}): Editable spreadsheet-like grid with cell-level editing, column resize, frozen left/right columns, keyboard navigation (arrow keys, Enter/F2 to edit, Tab to advance, Escape to cancel), striped/compact modes, Add Row and Delete Row actions; distinct from Data Table (grid is for editing, table is for display); template tag, Rust handler, Python component class (DataGrid), client-side JS (data-grid.js), CSS, and tests with XSS coverage -
Overlay/Feedback Components: 2 new components with Django template tags, Rust engine handlers, CSS, and tests (including XSS coverage):
- Loading Overlay (
{% loading_overlay active=is_loading %}...{% endloading_overlay %}) — Semi-transparent overlay with centered spinner that blocks interaction; supportsactive,text,spinner_size(sm/md/lg),custom_class - Announcement Bar (
{% announcement_bar type="info" dismissible=True %}...{% endannouncement_bar %}) — Full-width sticky top bar for site-wide announcements; supportstype(info/success/warning/danger),dismissible,dismiss_event,custom_class; usesdj-clickfor dismissal
- Loading Overlay (
-
Status/Progress Indicators: 4 new components with Django template tags, Rust engine handlers, component classes, CSS, and 74 tests (including XSS coverage):
- Notification Badge (
{% notification_badge count=5 %}) — Small count badge for icons/buttons with dot-only mode, max count overflow (99+), pulse animation; supportscount,max,dot,pulse,size,custom_class - Segmented Progress (
{% segmented_progress steps=steps current=2 %}) — Multi-step progress bar with labeled segments, numbered indicators, and connector lines; supports string or dict steps,current,size,custom_class - Progress Circle (
{% progress_circle value=65 size="md" %}) — SVG circular progress indicator with stroke-dasharray animation, percentage text, ARIA progressbar role; supportsvalue,size(sm/md/lg),color(primary/success/warning/danger),show_value,custom_class - Status Indicator (
{% status_indicator status="online" label="API" %}) — Colored dot with optional label and pulse animation; maps online=green, degraded=yellow, offline=red, maintenance=blue; supportsstatus,label,pulse,size,custom_class
- Notification Badge (
-
Display/Layout Primitives: 5 new components with Django template tags, CSS, and full test + XSS coverage:
- Scroll Area (
{% scroll_area %}...{% endscroll_area %}) — Custom-styled scrollbar container withmax_heightprop, CSS custom properties for thumb/track colors, and thin-scrollbar support;max_height,custom_class - Callout / Blockquote (
{% callout %}...{% endcallout %}) — Styled content block with colored left border, icon, and title; type variants (info/warning/danger/success) with auto-icons;type,title,icon,custom_class - Aspect Ratio (
{% aspect_ratio %}...{% endaspect_ratio %}) — CSSaspect-ratiocontainer for responsive media;ratio(e.g. "16/9", "4/3", "1/1"),custom_class - Description List (
{% description_list items=items %}) — Key-value display with vertical/horizontal layout modes using<dl>/<dt>/<dd>semantics;items(list of{term, detail}dicts),layout,custom_class - Sticky Header (
{% sticky_header %}...{% endsticky_header %}) —position: stickycontainer with configurable top offset, z-index, and shadow-on-scroll CSS class;offset,z_index,custom_class
- Scroll Area (
-
Button & Control Variants: 3 new components with Django template tags, Rust engine handlers, CSS, and full test + XSS coverage:
- Toggle Group (
{% toggle_group %}) — Segmented button group with single/multi select mode, icon support, size variants, ARIA pressed state; supportsname,options,value,event,mode,disabled,size - Floating Action Button (
{% fab %}) — Fixed-position FAB with optional speed-dial sub-actions, position variants (4 corners), size/variant/disabled support; supportsicon,event,position,label,size,variant,disabled,actions - Split Button (
{% split_button %}) — Primary action + dropdown for secondary actions with loading spinner, open/closed menu state, variant/size support; supportslabel,event,options,variant,size,disabled,loading,open,toggle_event
- Toggle Group (
-
Form Input Components: 7 new form-related components with Django template tags, Rust engine handlers, CSS, and 94 tests (including XSS escaping coverage):
- Multi-select (
{% multi_select %}) — Checkbox list with client-side search filtering and tag output for selected values; supportsoptions,selected,event,placeholder,disabled - OTP Input (
{% otp_input %}) — One-time-code input with individual digit boxes (4/6/custom), hidden input for form submission,inputmode="numeric"; supportsdigits,event,label,disabled - Number Stepper (
{% number_stepper %}) — +/- numeric input with min/max/step constraints; emitsdj-clickfor buttons anddj-changefor direct input; supportsvalue,min_val,max_val,step,label,disabled - Tag Input (
{% tag_input %}) — Input creating dismissible tags with hidden inputs for form submission and datalist suggestions; supportstags,suggestions,event,placeholder,label,disabled - Input Group (
{% input_group %}...{% endinput_group %}) — Block wrapper combining prefix/suffix addons with form inputs; supportssize(sm/md/lg),error - Input Addon (
{% input_addon %}...{% endinput_addon %}) — Prefix/suffix addon for use inside input groups; supportsposition(prefix/suffix) - Label (
{% dj_label %}...{% enddj_label %}) — Accessible form label withfor,required(asterisk indicator), andclasssupport - Fieldset (
{% fieldset %}...{% endfieldset %}) — Styled fieldset with legend, disabled state, and custom class support
- Multi-select (
-
Component Classes: 7 new Python component classes for programmatic use in LiveViews —
Alert(dismissible notifications with info/success/warning/danger factory methods),StatCard(KPI display with label/value/trend/icon),Tag(compact label chips with color variants and dismiss),Toast(transient notifications with success/error/warning/info factories and auto-dismiss duration),Progress(progress bars with percentage, label, ARIA, and variant support),Spinner(loading indicator with size variants and screen-reader label),Switch(toggle with.toggle()method, dj-change event, and accessible checkbox markup) -
Test Coverage Expansion: 226 new tests covering all 52 Rust handler classes in 4 batches — (1) rendering and CSS class verification for 33 previously untested handlers (CardHandler, AlertHandler, FormGroupHandler, TimelineHandler, DjButtonHandler, DjInputHandler, DjSelectHandler, DjTextareaHandler, DjCheckboxHandler, DjRadioHandler, SwitchHandler, StatCardHandler, TagChipHandler, StepperHandler, SkeletonHandler, BreadcrumbHandler, EmptyStateHandler, DividerHandler, SpinnerHandler, PaginationHandler, AvatarHandler, BadgeHandler, ProgressHandler, ToastContainerHandler, TooltipHandler, DropdownHandler, AccordionHandler, AccordionItemHandler, TabsHandler, DataTableHandler, plus 17 delegating handlers); (2) form component interaction testing verifying dj-input, dj-change, and dj-click event attribute emission across all form handlers; (3) complex component state tests for DataTable sort indicators/selection/pagination/search, Stepper active/complete states, and Breadcrumb active items; (4) edge case tests including empty/missing parameters for all handlers and XSS payload injection tests for every handler accepting user text
-
Data Table Pro Phase 3: 13 advanced features completing the P0 Data Table Pro work — row expansion with detail rows (
expandable=True,expand_event,expanded_rows); bulk actions toolbar with selected count and action buttons (bulk_actions,bulk_action_event); CSV/JSON export buttons (exportable=True,export_event,export_formats); row grouping by column value with collapse/expand and counts (group_by,group_toggle_event,collapsible_groups,collapsed_groups); custom cell renderers for badges, progress bars, and avatars (cell_templatecolumn config); keyboard navigation between cells with arrow keys, Enter to edit, Escape to cancel (keyboard_nav=True); virtual scrolling for 50+ row datasets (virtual_scroll=True,virtual_row_height,virtual_buffer); explicit server-side mode that skips client queryset pipeline (server_mode=True,refresh_table_server()); faceted filtering with value counts (facets=True,facet_counts,get_facet_counts()); state persistence to localStorage (persist_key); column pinning via per-column config (pinned="left"|"right"); print-friendly mode hiding interactive chrome (printable=True,@media printrules); column statistics footer with min/max/avg per numeric column (stats=Truecolumn config,column_stats,get_column_stats()) -
DataTableMixin Phase 3: New event handlers —
on_table_expand,on_table_bulk_action,on_table_export,on_table_group,on_table_group_toggle; override hookshandle_bulk_action(),handle_export(),refresh_table_server(); computed helpersget_facet_counts(),get_column_stats(),_group_rows(); new state:table_expanded_rows,table_collapsed_groups,table_current_group_by,table_facet_counts,table_column_stats -
Client-side JS Phase 3: Keyboard navigation (arrow keys, Enter/Escape), virtual scrolling with viewport-based row rendering, state persistence via localStorage with MutationObserver auto-save
-
CSS Phase 3: 50+ lines —
.data-table-expand-*,.data-table-bulk-*,.data-table-export-*,.data-table-group-*,.cell-renderer-badge/progress/avatar,.data-table-pinned-left/right,.data-table-stats-*,@media printrules for.data-table-printable -
Data Table Pro Phase 2: Editing and layout enhancements for the data table component — inline cell editing (
editable_columns,edit_event) with click-to-edit, Enter/Escape save/cancel; column resize via drag handles (resizable=True, client-side JS); column reorder via drag-and-drop (reorderable=True,reorder_event); frozen left/right columns with CSS sticky positioning (frozen_left,frozen_right); column visibility dropdown toggle (column_visibility=True,visibility_event); density toggle between compact/comfortable/spacious (density_toggle=True,density_event); responsive card collapse on narrow viewports (responsive_cards=True, CSS@containerwith@mediafallback); editable row mode with Edit/Save/Cancel buttons (editable_rows=True,edit_row_event,save_row_event,cancel_row_event,editing_rows) -
DataTableMixin Phase 2: New event handlers —
on_table_cell_edit,on_table_reorder,on_table_visibility,on_table_density,on_table_row_edit,on_table_row_save,on_table_row_cancel; override hookshandle_cell_edit()andhandle_row_save()for persistence; new state:table_editing_rows,table_column_order,table_visible_columns,table_current_density -
Client-side JS module:
static/djust_components/data-table.js— auto-initializing script for column resize drag handles, column reorder drag-and-drop, column visibility menu toggle, density toggle, and inline cell editing activation; uses MutationObserver for LiveView compatibility -
CSS: 60+ lines of Phase 2 data table styles —
.data-table-cell-editing,.data-table-frozen-left/right,.data-table-spacious,.data-table-resize-handle,.data-table-toolbar,.data-table-visibility-*,.data-table-density-*,.data-table-row-actions,.data-table-row-editing,.data-table-responsivewith@containerand@mediacard collapse -
Data Table Pro Phase 1: Core interactivity for the data table component — row selection with checkboxes (
selectable,selected_rows,select_event,row_key), global search with debounce (search,search_query,search_event,search_debounce), per-column text and select filters (filterable,filter_type,filter_options,filter_event), built-in pagination (paginate,page_event), loading/skeleton state (loading), empty state with customizable title/description/icon, per-columnsortableflag, columnwidth, andstriped/compactstyling variants -
DataTableMixin: New mixin class for LiveViews (
djust_components.mixins.data_table) that auto-generates sort, search, filter, select, and paginate event handlers from a model or queryset — includesinit_table_state(),refresh_table(),get_table_context(), and full queryset pipeline (_apply_table_search,_apply_table_filters,_apply_table_sort,_apply_table_pagination) -
ARIA accessibility: Data table now renders
role="grid",aria-label,aria-sorton sortable headers,aria-selectedon selectable rows,aria-busyduring loading,role="searchbox"on search input,role="status"on empty state, androle="navigation"on pagination -
CSS: 24 new data table styles —
.data-table-container,.data-table-search,.data-table-filter,.data-table-checkbox,.data-table-select-all,.data-table-header-cell,.data-table-striped,.data-table-compact,.data-table-loading,.data-table-empty,.data-table-pagination,tr[aria-selected="true"]highlight, andth[aria-sort]cursor styling -
CSS: Styles for 9 complex data/interactive components — Notification Center (bell trigger, badge, dropdown list, read/unread states, timestamps), Tree View (nested indentation, expand/collapse toggle, selected node highlight), Gauge/Donut (SVG arc with color variants and value display), Image Carousel (slides, prev/next buttons, dot indicators, caption overlay), Virtual List (scrollable viewport, item rows, load-more sentinel), Kanban Board (columns with drag-over state, draggable cards, label colors), Table of Contents (nav with active link highlighting and level indentation), Split Pane (horizontal/vertical layout, draggable resize handle), Rich Text Editor (toolbar with buttons/separators, contenteditable area, placeholder)
-
CSS: Styles for Combobox, Color Picker, Date Picker, and File Dropzone form control components — combobox with searchable dropdown and option hover/selected states, color picker with swatch grid/preview/hex input, date picker with calendar grid/nav/today/selected/range states, file dropzone with dashed border/drag-over highlight/file-count feedback
-
CSS: Styles for Popover, Sheet/Drawer, Context Menu, and Command Palette components — popover with positioned placement arrows and fade-scale transition, sheet/drawer with slide-in from left/right/bottom and backdrop overlay, context menu with absolute positioning and scale transition, command palette with modal overlay, search input, and scrollable results list
-
CSS: Styles for Kbd, Copy Button, Rating, Code Block, and Collapsible components — keyboard shortcut keys with raised-border look, star ratings with gold/muted coloring and hover effects, code blocks with header/filename/language/copy-button layout, and collapsible panels with animated icon and toggle visibility
- Virtual List: Rust handler now deserializes JSON strings for
itemswhen the Rust engine passes list-of-dicts as serialized JSON - Kanban Board: Rust handler now deserializes JSON strings for
columns(same fix as Virtual List)
- Combobox: Multi-select mode with
multiple=Trueandselectedlist — renders removable tag chips, hidden inputs for form submission, and per-option selected state - Date Picker: Date range selection with
range=True,range_start, andrange_end— adds range highlighting CSS classes and dual hidden inputs for form submission - Code Block: Syntax highlighting via highlight.js CDN lazy-loading with
highlight=True(default) and configurablethemeparameter - Component Gallery:
python manage.py component_gallerymanagement command renders every component for visual QA — auto-discovers all template tags and component classes, groups by category, supports light/dark mode toggle and responsive preview (mobile/tablet/desktop), includes--dry-runto list components without starting the server - Rust engine handlers: 40+ component tag handlers for the Rust template engine — components now work without
{% load djust_components %}when using Rust-rendered templates - Tier 1 handlers: Modal, Tabs, Accordion, Dropdown, Toast, Tooltip, Progress, Badge, Card, DataTable, Pagination, Avatar, Alert, Switch, Divider, Breadcrumb, Skeleton, StatusDot, Button, Stepper, Timeline
- Tier 2/3 handlers: CodeBlock, Combobox, Rating, CopyButton, Kbd, Gauge, NotificationCenter, TreeView, ColorPicker, Carousel, Popover, Collapsible, Sheet, CommandPalette, ContextMenu, PaletteItem, ContextMenuItem
- v1.3 handlers: DatePicker, FileDropzone, VirtualList, KanbanBoard, TableOfContents, RichTextEditor, SplitPane
- CSS: 206 lines of component styles for Tier 2/3 and v1.3 components
- Auto-registration: Components register with the Rust engine automatically via
AppConfig.ready()
- Combobox: Fixed
onmousedownevent handler preventing item selection - Switch: Fixed HTML structure to use
<span class="switch">wrapper - Divider: Fixed CSS class generation for divider variants
- TableOfContents: Fixed item rendering for nested headings
_parse_args: Fixed parsing of"1"and"0"string values being treated as booleans
- Dependencies: Removed
djust-themingas a hard dependency. The previous constraint wasdjust-theming>=0.3.0,<1.0, which required an unreleased version and blocked installation. djust-theming is now optional — install it separately if you want automatic theme adaptation.
- Rust handlers: All block handlers (
PopoverHandler,CollapsibleHandler,SheetHandler,CommandPaletteHandler,ContextMenuHandler,SplitPaneHandler) now wrap returns inmark_safe()to prevent double-escaping in the Rust engine - templatetags: All user-controlled values interpolated inside
mark_safe(f"...")strings are now wrapped withconditional_escape(), preventing XSS from attacker-controlled template tag arguments (modaltitle/close_event, tabsid/event, accordionid/event, dropdownid/label/toggle_event/variant, tooltiptext/position, cardtitle/subtitle/variant/class) - Markdown component: Replaced regex-based post-render sanitizer with
nh3(Rust-backed, allowlist-based sanitizer). Explicitly allowed tags and attributes are now enumerated; URL schemes restricted tohttp,https,mailto;javascript:,data:, andvbscript:URLs are blocked
0.3.0 - 2026-02-19
- Component Class API — Python-first alternative to template tags for programmatic use in LiveViews
Badge— status/priority badge with factory methodsBadge.status()andBadge.priority()for auto-coloringStatusDot— animated dot indicator with built-in status → variant/animation mappingsButton— action button with variants, icons, loading state, and djust event wiringCard— content container with image/header/content/footer sections and hover/click supportMarkdown— renders Markdown to sanitized HTML; strips dangerous tags andon*event attributes; wraps in<div class="dj-prose">markdown>=3.0added as a dependency (required byMarkdowncomponent)
Markdown: post-render sanitization instead of pre-escaping source text, fixing code spans containing&,<,>
0.2.0 - 2026-02-17
-
djust-theming Integration
- All components now use djust-theming CSS variables for automatic theme adaptation
- Components automatically adapt to theme preset (Default, Shadcn, Blue, Green, Purple, Orange, Rose)
- Components automatically adapt to theme mode (light/dark/system)
- Support for all 31 theme color tokens (including new info, link, code, selection colors)
-
Design Tokens
- Spacing: Uses djust-theming spacing scale (
--space-1to--space-24) - Typography: Uses djust-theming type scale (
--text-xsto--text-4xl, line heights, font weights) - Radius: Uses djust-theming radius tokens (
--radius-smto--radius-full) - Transitions: Uses djust-theming timing tokens (
--duration-fast,--duration-normal) - Shadows: Uses djust-theming shadow tokens (
--shadow-sm,--shadow-md,--shadow-lg)
- Spacing: Uses djust-theming spacing scale (
-
Complete CSS Refactor
- Replaced all hardcoded colors with theme CSS variables
- Replaced all hardcoded spacing/sizing with design tokens
- Replaced all hardcoded border radius values with design tokens
- Replaced all hardcoded transition timings with design tokens
- Replaced all hardcoded box-shadow values with design tokens
-
Dependencies
- Added
djust-theming>=1.1.0as a required dependency
- Added
- Legacy CSS Custom Properties
- Removed
--dj-primary,--dj-success,--dj-warning,--dj-danger,--dj-info - Removed
--dj-text,--dj-bg,--dj-bg-subtle,--dj-border,--dj-radius - All replaced with djust-theming variables
- Removed
If you were using custom CSS variables to style components, you need to migrate to djust-theming:
- Install djust-theming:
pip install djust-theming - Add
djust_themingtoINSTALLED_APPS - Replace component CSS include with:
{% load djust_theming %} {% theme_head %} <link rel="stylesheet" href="{% static 'djust_components/components.css' %}"> - Remove custom CSS variable overrides (components now use theme variables)
- Use djust-theming's preset system for custom themes
Breaking Change: Components no longer support custom CSS variables. Use djust-theming presets instead.
0.1.0 - 2026-02-04
- Initial release with 12 pre-built components
- Modal, Tabs, Accordion, Dropdown, Toast, Tooltip, Progress, Badge, Card, DataTable, Pagination, Avatar
- Self-contained CSS with no JavaScript dependencies
- Full djust event system integration (
dj-click,dj-input, etc.) - Customizable via CSS custom properties