Skip to content

Unify filter/search bars onto shared CSS classes + partials - #2220

Merged
maebeale merged 4 commits into
mainfrom
maebeale/search-placeholder-styling
Aug 18, 2026
Merged

Unify filter/search bars onto shared CSS classes + partials#2220
maebeale merged 4 commits into
mainfrom
maebeale/search-placeholder-styling

Conversation

@maebeale

@maebeale maebeale commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

🤖 suggested review level: 5 Inspect 🔬 wide-reaching filter-bar restyle across ~30 index pages + shared helper/partials and select-height behavior

What is the goal of this PR and why is this important?

  • Filter/search bars had drifted into ~30 near-identical-but-inconsistent class strings (rounded-lg vs -md, different focus/label styles, btn-utility vs -outline vs -secondary clear buttons, ad-hoc search-icon buttons). This unifies them so every filter bar reads the same and future restyling is a one-place change.

How did you approach the change?

  • Single source of styling, no @apply: field/label classes live in SearchFormHelper#search_field_class / #search_label_class (Tailwind v4 scans app/helpers via @source). A helper rather than a partial because these classes decorate ~100 heterogeneous controls (selects, remote/multi-selects, date/number/text inputs) that can't share one field partial.
  • Shared partials for whole repeated elements: shared/_search_clear (standard "Clear filters" button) and shared/_search_submit (magnifier submit), both inline default Tailwind.
  • Swept ~34 filter partials + the shared events filter bar (registrants roster, bulk-reminder picker, attendees) + a few one-off filter forms onto them.
  • Placeholders render small + light grey and revert to normal when filled; "All"-prompt selects grey their prompt and match sibling text-input height. The only rule left in CSS is that select-placeholder :has() rule, written as raw CSS (line-height: 1.5rem), since its selector isn't expressible as a utility.
  • SimpleForm inputs get the same small-grey placeholder.

Anything else to add?

  • Verified: full suite green — 6914 examples, 0 failures (ai/test_extra, Vite build + all system specs). Every migrated ERB template compiles; no search-field/search-label refs remain anywhere.
  • Admin ahoy-activities keeps its page-specific indigo action buttons by design (fields/labels unified only).

Copilot AI lite review requested due to automatic review settings August 16, 2026 21:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 16, 2026 21:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale
maebeale marked this pull request as ready for review August 16, 2026 21:20
@maebeale
maebeale requested a review from jmilljr24 August 16, 2026 21:21
@maebeale maebeale changed the title Unify filter/search bars onto shared CSS classes + partials JM: Unify filter/search bars onto shared CSS classes + partials Aug 16, 2026
@maebeale
maebeale force-pushed the maebeale/search-placeholder-styling branch from e441e7d to 4acfabd Compare August 16, 2026 21:28
Copilot AI review requested due to automatic review settings August 16, 2026 21:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale
maebeale force-pushed the maebeale/search-placeholder-styling branch from 4acfabd to 2d89d65 Compare August 17, 2026 05:52
Copilot AI review requested due to automatic review settings August 17, 2026 05:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

maebeale and others added 2 commits August 17, 2026 08:41
Filter fields, labels, placeholders, and the clear/search buttons had
drifted into ~30 near-identical-but-inconsistent class strings across the
index pages. Centralize the look in .search-field / .search-label /
.search-select-placeholder / .search-submit (one CSS file) plus
shared/_search_clear and shared/_search_submit partials, so every filter
bar reads the same and restyling later is a one-place change.

Placeholders now render small + light grey and revert to normal text when
a value is entered; "All"-prompt selects grey their prompt like a
placeholder and match the height of sibling text inputs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@maebeale
maebeale force-pushed the maebeale/search-placeholder-styling branch from 2d89d65 to a546814 Compare August 17, 2026 12:41
Copilot AI review requested due to automatic review settings August 17, 2026 12:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment on lines +111 to +138
/* Shared filter/search-bar styling — restyle every filter bar here. In the
components layer so markup utility overrides (w-64, bg-white, pr-10) win. */
@layer components {
.search-field {
@apply w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-800 shadow-sm;
@apply focus:border-blue-500 focus:ring focus:ring-blue-200 focus:outline-none;
}

.search-field::placeholder {
@apply text-sm text-gray-400;
}

.search-label {
@apply block text-xs font-semibold uppercase text-gray-500 tracking-wide mb-1;
}

/* Grey the "All" prompt like a placeholder; text-sm/6 keeps the input's
line-height so the select stays the same height. */
.search-select-placeholder:has(option:first-child:checked) {
@apply text-sm/6 text-gray-400;
}

/* Magnifier submit; pair with a `.search-field pr-10` input in a relative wrapper. */
.search-submit {
@apply absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-blue-600;
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Shared filter/search-bar styling — restyle every filter bar here. In the
components layer so markup utility overrides (w-64, bg-white, pr-10) win. */
@layer components {
.search-field {
@apply w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-800 shadow-sm;
@apply focus:border-blue-500 focus:ring focus:ring-blue-200 focus:outline-none;
}
.search-field::placeholder {
@apply text-sm text-gray-400;
}
.search-label {
@apply block text-xs font-semibold uppercase text-gray-500 tracking-wide mb-1;
}
/* Grey the "All" prompt like a placeholder; text-sm/6 keeps the input's
line-height so the select stays the same height. */
.search-select-placeholder:has(option:first-child:checked) {
@apply text-sm/6 text-gray-400;
}
/* Magnifier submit; pair with a `.search-field pr-10` input in a relative wrapper. */
.search-submit {
@apply absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-blue-600;
}
}
.search-select-placeholder:has(option:first-child:checked) {
color: rgb(156 163 175); /* gray-400 */
font-size: 0.875rem; /* text-sm */
line-height: 1.5; /* /6 */
}

Using @apply is frowned up with the guidance we just added about tailwind and we've done a pretty good job about not using it thus far.

Could we create shared partials instead and use the default tailwind classes in them? It would remove a lot of duplicate code and also remove the need for @apply.

I think only that placeholder code might need to live in this file and that shouldn't need @apply.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Done — all @apply removed. .search-field/.search-label/.search-submit are gone; field/label styling moved to SearchFormHelper#search_field_class/#search_label_class (a helper rather than a partial because these classes decorate ~100 heterogeneous controls — selects, remote/multi-selects, date/number/text inputs — that can't share one field partial; Tailwind v4 still generates the literals since it scans app/helpers via @source). _search_submit/_search_clear stay as shared partials with inline default Tailwind. Only this :has() placeholder rule remains, as raw CSS.

Two notes: I applied it via a normal commit (GitHub's "Apply suggestion" is a UI-only button, no API to commit it), and I corrected the line-height in your snippet from 1.5 to 1.5remtext-sm/6 means a 1.5rem line-height, and the unitless 1.5 would have shrunk the select and undone the "keep it the same height as a text input" purpose this rule exists for.

Per review: @apply trades away Tailwind's benefits and the project avoids it.
The field/label classes decorate ~100 heterogeneous filter controls that can't
share one partial, so they move to SearchFormHelper#search_field_class /
#search_label_class (Tailwind v4 scans app/helpers via @source); submit/clear
stay as shared partials with inline default Tailwind. Only the :has() select
placeholder rule remains in CSS, as raw CSS rather than @apply.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 17, 2026 16:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment on lines +111 to +113
/* Filter/search-bar field and label styling lives in shared partials +
SearchFormHelper#search_field_class (default Tailwind, no @apply). Only this
placeholder rule stays here — its :has() selector isn't expressible as a utility. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment only makes sense if you are looking at the PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Good catch — reworded it to describe what the rule does (greying the select's blank first option like a placeholder, raw CSS because :has() has no utility equivalent) rather than narrating the change. Pushed in 2b60e6f.

The prior comment narrated the PR ("styling now lives in ... no @apply, only
this stays here") and mislabeled the helper as a partial. Describe what the rule
does instead, so it reads correctly from the file alone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 17, 2026 19:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale maebeale changed the title JM: Unify filter/search bars onto shared CSS classes + partials Unify filter/search bars onto shared CSS classes + partials Aug 17, 2026
@maebeale
maebeale merged commit 579a468 into main Aug 18, 2026
3 checks passed
@maebeale
maebeale deleted the maebeale/search-placeholder-styling branch August 18, 2026 03:18
maebeale added a commit that referenced this pull request Aug 18, 2026
The /features filter bar was the lone search box the #2220 unification
missed, so its labels rendered in the old normal style while every sibling
index now shows the shared eyebrow style. Route its labels and fields through
search_label_class/search_field_class so it matches.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
maebeale added a commit that referenced this pull request Aug 18, 2026
Adopt SearchFormHelper field/label classes + shared/_search_clear (introduced on
main in #2220) so the form filter matches every other index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
maebeale added a commit that referenced this pull request Aug 18, 2026
…missions index (#2237)

* Add slug + published to Form; extract FormAnswerPersistence for public forms

Foundation for a public pretty-URL endpoint for standalone (event-less) forms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Public pretty-URL endpoint for standalone forms + form-filterable submissions index

Publish an event-less Form at /f/:slug for account-free public filling; view
those submissions via the form-filterable /form_submissions index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Refresh forms_controller brakeman ignore for :slug/:published permit

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Trim comments to non-obvious whys per CLAUDE.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Seed standalone public forms + designate public (event-less) submissions in index

Adds a dev seed (two published event-less forms with submissions/answers) and
marks event-less public submissions with a 'Public form' pill in the index so a
blank Event column reads as intentional, not missing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix View link escaping the results frame; consolidate answer persistence onto FormSubmission; forms UX polish

- Bug: View link inside the submissions results Turbo frame navigated the frame
  to a frameless show page (Oopsie); break it out with turbo_frame _top.
- Move persist_answer + hardened file-upload handling onto FormSubmission;
  registration, public forms, and bulk payment now share it (mixin removed).
- Forms index: event-connected unpublished forms read 'Event form' not
  'Not published'; delete link removed; submissions count links back with a
  Forms eyebrow anchored to the row.
- Editor: clarify publish only controls the public link; swap Save/Delete
  placement and show a reason when a form can't be deleted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add FormSubmission#persist_answer model spec (text, multi-value, upsert, forged upload)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Email confirmation + admin FYI on public form submission

Mirror event registration: new form_submission_confirmation(_fyi) notification
kinds, NotificationMailer methods + views, job dispatch, and previews. Sent from
PublicFormSubmission to the submitter and the AWBW team.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Forms index: show public-link and event-form chips independently

A form can be both; render a chip for each that applies (rename column to
Availability) rather than one-or-the-other.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Align submissions filter with the shared search-bar helpers/partials

Adopt SearchFormHelper field/label classes + shared/_search_clear (introduced on
main in #2220) so the form filter matches every other index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Capture "Other" answers and keep the form filter on public-form submissions

Public forms were the only submission path that skipped
OtherResponses::CaptureFromSubmission, so a sector question answered
"Other: …" never reached the curation queue — it only lived in the form
answer, invisible to promotion.

The submissions View link carried person_id but not form_id, so arriving
from the forms index and clicking back landed on that person's
submissions rather than the form-filtered list you came from.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Reject a slug that parameterizes away instead of blanking it

parameterize strips "!!!" (or any input with no url-safe characters) down to
"", which the format validation waves through as blank and the unique index
then collides on for the second such form — surfacing to the admin as the
baffling "Slug has already been taken". Keep the typed value intact so the
format error fires instead, and the admin sees what they entered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Keep the Forms eyebrow across the submission detail round trip

The View link told the detail page it came from the submissions index, but
not where that index was itself reached from — so returning from a submission
opened via Forms landed on the filtered index with the "← Forms" back link
gone. Carry the origin forward on the link and hand it back on the way home.
The filter form carries it too, so changing the filter doesn't strip it out
of the frame's params and orphan the View links.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Refresh the drifted controller and service counts in AGENTS.md

This branch adds a controller and a service, and both directory counts were
already well behind the tree — the numbers are only useful if they're close.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants