Skip to content

Search Input UX Policy (Canonical)

This is the canonical rule for search and filter input UX across LMS, CMS, and shared UI surfaces.

Scope

  • Applies to search/filter bars in list pages, admin screens, workarea panels, dialogs, sidebars, and import pickers.
  • Does not apply to full forms. Full-form labeling/layout remains governed by 056-full-form-ux-policy.mdc.

Core Contract

  • Use shadcn Input for search controls.
  • Put guidance text in the input placeholder.
  • Add a localized aria-label on each search input.
  • Prefer type="search" for search semantics.
  • Keep search icon + clear button affordance where already used.
  • Clear buttons must use type="button" and a localized aria-label (typically accessibility.clearSearch).

Consistency Requirements

  • Do not render standalone helper text above a search field when that text is intended as in-field guidance.
  • Preserve existing behavior when migrating:
    • query param contracts (search or field-specific filters),
    • submit semantics and URL state,
    • pagination behavior,
    • stable data-testid hooks.

Implementation Guidance

  • For client-rendered list surfaces, prefer the shared @open-learning-hub/ui/search-input primitive to keep icon/clear/testid behavior consistent.
  • For server-rendered LMS list pages that use <form method="get">, keep the existing server-first pattern (Input type="search" + aria-label) and avoid client conversions solely for search UI reuse.
  • When one free-text value searches or filters multiple database fields, use a single search input.
  • Apply that query server-side with an OR condition across the relevant fields.
  • Do not split free-text filtering into parallel text fields such as action, actor, and tenant unless product explicitly requires separate structured filters.
  • Keep constrained filters separate when the input is not free text, such as status, role, or type dropdowns.
  • Preserve tenant, permission, and other authorization scopes outside the broad search OR condition.

i18n Guidance

  • Prefer distinct keys when copy intent differs:
    • searchPlaceholder for visible guidance,
    • searchLabel (or equivalent) for aria-label.
  • Reusing one key for both is allowed when product copy is intentionally identical.

Accessibility + Testing

  • Search bars may use placeholder + aria-label without a visible label when they are listing/filter controls (not full forms).
  • Add or update tests for changed search controls to cover:
    • placeholder text,
    • aria-label presence,
    • clear-button aria-label,
    • unchanged filter/query behavior.

Reference Implementations

  • apps/lms/src/app/\[locale\]/admin/tenants/_components/tenants-manager.tsx
  • apps/lms/src/app/\[locale\]/admin/users/page.tsx
  • apps/lms/src/app/\[locale\]/admin/audit/page.tsx
  • apps/cms/src/components/widgets/shared/asset-picker-dialog.tsx
  • apps/cms/src/components/workarea/import-pages.tsx