Files
sure/docs/llm-guides/ui.md
T
Juan José Mata 157daf5176 Consolidate repository instructions after auditing their history (#3409)
* Document instruction inventory and preservation decisions

Trace main history from September 2025 through September 2026, including earlier policy origins. Record preserved requirements, detailed-guide destinations, stale facts, harness boundaries and explicit policy-strength decisions before consolidating instruction sources.

* Consolidate repository instructions into shared guidance

Keep AGENTS concise and vendor neutral, move detailed conventions into shared guides, and use thin adapters with preserved Cursor scopes. Preserve the strict pre-PR checks globally and document the stronger scope, retired migration pin and rule-generation trigger. Update existing API guidance verification without changing application behavior.

* Narrow the always-on Cursor UI adapter and correct the SimpleFIN comment

Split the design-system guidance out of docs/llm-guides/ui.md into
docs/llm-guides/design-system.md. The ui-ux-design-guidelines rule is
alwaysApply: true, so importing all of ui.md loaded the Stimulus,
localization and ViewComponent guidance (previously confined to scoped
rules) on every Cursor session; the always-on adapter now imports only the
design-system guide, matching the scope it had before the consolidation.
view_conventions and stimulus_conventions keep the full UI guide.

Also correct the stale Provider::Simplefin header comment: pending
inclusion defaults on and is resolved by the importer (explicit argument,
then SIMPLEFIN_INCLUDE_PENDING, then Setting.syncs_include_pending); the
previous comment described the flag as default-off.

* Read guidance files as UTF-8 in the API consistency validators

The frontmatter regex match ran against content read with the locale
default external encoding; the Cursor rule's description contains an em
dash, so under US-ASCII (LC_ALL=C) Regexp#match raised ArgumentError,
breaking the standalone no-Rails fallback the docs point contributors to.
Read all checked files with an explicit UTF-8 encoding in both the
standalone script and the Rails test.
2026-09-06 07:14:43 +02:00

2.9 KiB

Views, components and interaction

Design tokens, DS::* reuse and reviewer severity live in the design system guide, which is also the always-on Cursor design adapter. This guide covers templates, Hotwire, Stimulus and localization.

Hotwire and templates

Prefer semantic native HTML, including <dialog> and <details><summary>, using existing DS wrappers where available. Use Turbo Frames for page sections. Turbo Streams should enhance functionality, not be its sole dependency.

Keep state in URL query parameters before reaching for local storage or sessions; use the database when persistent state is necessary. Format money, numbers and dates server-side and pass display values to Stimulus. Client-side behavior is appropriate for interactions such as bulk selection where server round trips would hurt usability.

Use an existing component first, then an existing partial. Create a ViewComponent for reusable or complex styling/logic, variants/sizes, interaction, slots or a configurable API, and accessibility/ARIA behavior. Use partials for mostly static, simple or context-specific template content. Keep domain logic out of ERB; compute presentation logic in helpers or component Ruby files.

Follow the names of nearby components, including the DS::* namespace; do not impose the obsolete ButtonComponent/DialogComponent examples on this design system. Partials use an underscore prefix; shared partials live in app/views/shared/, context-specific partials under their controller's views.

Stimulus

  • Declare actions in HTML (data-action="click->toggle#toggle") rather than imperatively registering event listeners in controller initialization.
  • Keep controllers focused on one responsibility or tightly related responsibilities; domain logic belongs on the server.
  • Aim for fewer than seven targets. Use private helpers and a clear public API, with Stimulus callbacks, actions, targets, values and classes.
  • Controllers in app/components/ belong only to their component templates; global controllers in app/javascript/controllers/ may be shared across views.
  • Pass data through data-*-value attributes rather than inline JavaScript. Use Stimulus targets rather than manual getElementById lookups.

Localization

Use t() for all user-facing strings and update the corresponding locale files under config/locales/. Follow the feature's existing locale organization; there is no requirement to put every new key in a single en.yml.

Use descriptive, hierarchical keys such as accounts.index.title and components.transaction_details.show_details. Group related keys together; use interpolation (t("users.greeting", name: user.name)) and Rails pluralization (t("transactions.count", count: count)) for dynamic text. Keep examples localized too. Configure missing translations to raise during development; do not assume that this option is currently enabled in the checked-in environment configuration.