Pathogen View Components is a focused library of Rails ViewComponents and Stimulus controllers designed for accessible, internationalized, and consistent UI across Pathogen and IRIDA Next applications. It provides a small, opinionated design system: sensible defaults, strong accessibility primitives, and the hooks you need to extend behavior without fighting the framework.
This repository is the extracted, standalone home for the Pathogen UI layer. It ships as a Rails engine with assets, helpers, and importmap pins ready to integrate into modern Rails applications.
- Accessible by default: ARIA patterns, focus management, and SR-friendly utilities.
- Component-first API: ViewComponents with slots and options that scale with your app.
- Stimulus-ready: Built-in controllers for tabs and tooltips.
- Tokenized styling: CSS variables and layers so host apps can override safely.
- Engine-powered: Helpers, locales, and assets wired through the Rails engine.
For developing this repository:
- Ruby 3.3+
- Rails 8.1+
view_component>= 4.0, < 5.0rails_icons>= 1.4.0
JavaScript dependencies (importmap or package manager):
@hotwired/stimulus^3.0.0@hotwired/turbo-rails^8.0.0 (peer dependency)uuid^13.0.0@floating-ui/dom^1.7.5flowbite^3.1.2 (temporary dependency for tooltips)
Add this line to your application's Gemfile:
gem 'pathogen_view_components'Then install:
bundle installPathogen components are under the Pathogen namespace and follow the ViewComponent render pattern.
<%= render Pathogen::DataGridComponent.new(rows: @rows, caption: "Samples") do |grid| %>
<% grid.with_column("ID", key: :id, width: 120) %>
<% grid.with_column("Name", key: :name, width: 240) %>
<% end %>Custom cell rendering:
<%= render Pathogen::DataGridComponent.new(rows: @rows) do |grid| %>
<% grid.with_column("Name") { |row| tag.strong(row[:name]) } %>
<% end %>Sticky columns:
<%= render Pathogen::DataGridComponent.new(rows: @rows, sticky_columns: 1) do |grid| %>
<% grid.with_column("ID", key: :id, width: 120) %>
<% grid.with_column("Name", key: :name, width: 240) %>
<% end %><%= render Pathogen::TabsComponent.new(label: "Sample Tabs") do |tabs| %>
<% tabs.with_tab("Overview", id: "overview") do %>
<p>Overview content</p>
<% end %>
<% tabs.with_tab("Details", id: "details") do %>
<p>Details content</p>
<% end %>
<% end %><%= render Pathogen::TooltipComponent.new(text: "More details") do %>
<%= render Pathogen::ButtonComponent.new(text: "Hover me") %>
<% end %>The engine ships pathogen_view_components.css, built on layered CSS tokens. In most Rails setups, the engine will precompile this file. Ensure your application includes the stylesheet via your asset pipeline or build tooling.
Translations live under config/locales in the engine. Rails automatically loads these locales when the engine is mounted, so you can provide app-level overrides in your own config/locales files as needed.
Pathogen provides a small set of Stimulus controllers for interactive components.
The engine registers importmap pins from config/importmap.rb automatically. After boot, you should see entries for pathogen_view_components and its controllers in /rails/importmap.
Register Pathogen controllers in your Stimulus index before any lazy-loading call:
import { application } from "controllers/application";
import { registerPathogenControllers } from "pathogen_view_components";
registerPathogenControllers(application);pathogen--tabs: WAI-ARIA compliant tabs with keyboard navigation and URL hash syncingpathogen--tooltip: Lightweight tooltip behavior (Flowbite-backed)pathogen--data-grid: ARIA grid keyboard navigation with roving tabindex and interactive-cell focus delegation
Set up the development environment:
bin/setupUse bin/setup --skip-demo if you only want the library dependencies and hooks without preparing the Lookbook demo app.
Run tests:
bin/test # Ruby component tests
pnpm test # JavaScript controller tests (requires pnpm install)Git hooks are managed with lefthook. The pre-commit hook runs bundle exec i18n-tasks health, formats staged JavaScript, JSON, Markdown, CSS, and YAML with Prettier, auto-fixes staged JavaScript with ESLint, runs RuboCop autocorrections on staged Ruby files, and re-stages any changes.
Before merging keyboard navigation changes, manually verify with a screen reader:
- macOS: VoiceOver + Safari (
Cmd+F5to toggle VO) - Windows: NVDA + Firefox (free at nvaccess.org)
Key behaviors to spot-check:
- Arrow key navigation announces cell content and grid position (e.g., "row 2 of 3, column 1 of 2")
EnterorF2enters widget mode and announces the focused interactive elementEscapeexits widget mode and returns announcement to the cellCtrl+Home/Ctrl+Endannounces first/last cell
A Lookbook instance at demo/ lets you browse and interact with all components in the browser without a full host application.
cd demo
bundle install
bin/devOpen http://localhost:3001/lookbook. Component previews live in test/components/previews/pathogen/ and are shared between the test suite and Lookbook.
Bug reports and pull requests are welcome. Please include tests for behavioral changes and note any accessibility impacts.
The gem is available as open source under the terms of the MIT License.