feat(data_table): Hotwire-first DataTable component family#457
Open
djalmaaraujo wants to merge 81 commits intomainfrom
Open
feat(data_table): Hotwire-first DataTable component family#457djalmaaraujo wants to merge 81 commits intomainfrom
djalmaaraujo wants to merge 81 commits intomainfrom
Conversation
9 tasks
1e88333 to
7833312
Compare
Adds the brainstorm-approved design document for the DataTable component family. Covers components, Stimulus controllers, Turbo wiring, pagination adapter pattern, configurable query params, icon strategy, test scope, and six documentation examples.
TDD, incremental commits per task. Enforces subagent model (claude-sonnet-4-6, low effort) for all implementation steps.
Adds /vendor/bundle to .gitignore (local BUNDLE_PATH install). Fixes plan's dx helper node path to 25.8.2 and records baseline test count.
Reused from Cirdes's branch (commit 36a61e8) verbatim for demo fixture parity.
Normalizes page/per_page/total_count inputs; total_pages >= 1. Places adapter in app/components/ruby_ui/data_table_pagination/ (Option A) and excludes that directory from the Zeitwerk collapse glob so that RubyUI::DataTablePagination resolves as a proper module namespace.
After Task 6 landed, file paths for adapters are data_table_pagination/* (not data_table/pagination/*) to produce RubyUI::DataTablePagination::X without collapse issues. Patches Tasks 7/8 paths.
Duck-typed wrapper — does not add pagy gem as a dependency.
Duck-typed wrapper — no gem dependency added.
Renders <turbo-frame> wrapping a <form> with the ruby-ui--data-table Stimulus controller. Form supports form-first bulk actions via button formaction.
respond_to? check replaces bare rescue so unexpected errors surface instead of being swallowed. New test guards against silent token drop.
Reverts raw <input> to RubyUI::Input for styling + behavior parity with Cirdes's reference. Tests use simpler regexes that tolerate Input's data-action attribute.
Wraps TableHead with sort link. Uses lucide-rails file-based icons (chevron-up/chevron-down/chevrons-up-down). Configurable param names.
Native <input name=ids[] value=ID> so bulk actions submit via <form> without custom fetch. Default aria-label="Select row N".
Reuses DropdownMenu + Button. Own Stimulus controller for column visibility toggle.
Frees the DataTablePagination namespace for the component class.
Base Pagination has mx-auto w-full justify-center (sensible default elsewhere). DataTablePagination overrides with mx-0 w-auto justify-end so it sits flush on the right inside DataTablePaginationBar.
7833312 to
ab6b111
Compare
ab6b111 to
8abdf6f
Compare
cirdes
approved these changes
Apr 26, 2026
Contributor
cirdes
left a comment
There was a problem hiding this comment.
The PR looks amazing, let's merge it!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WhatsApp.Video.2026-04-24.at.17.06.57.mp4
Adds a server-first DataTable inspired by shadcn's composition, powered entirely by Turbo Frames and Stimulus — no external JS table library.
app/components/ruby_ui/data_table/<input name="ids[]">, bulk submit buttons use HTML5form=+formaction=/docs/data_table/docs/data_table_demoKey decisions
Table,Checkbox,NativeSelect,Pagination,DropdownMenu,Input,Button,Badge,lucide-railsprimitives — row + select-all checkboxes renderRubyUI::Checkboxinternally; per-page select rendersRubyUI::NativeSelect.name:,sort_param:,direction_param:,page_param:).window: N) + adapter pattern (pagy:/kaminari:/with: custom_adapter).debounce:,falsedisables).DataTable.Video
Video walkthrough:
Test plan
bin/rails testgreenbundle exec standardrbclean/docs/data_table— all 6 examples + pagination adapters section render/docs/data_table_demo: debounced search filters (focus survives swap), sort cycles, per-page switches, numbered pagination navigates, select-all works (indeterminate state), bulk Delete/Export submit, column toggle hides/shows, row expand reveals detail with arrow rotation, row actions dropdown opens