feat: per-field CSS class hook + README refresh#71
Conversation
📝 WalkthroughWalkthroughThe README documents CAPTCHA, hidden tracking fields, embedded styling, and development commands. Admin previews and embedded forms now apply configured CSS classes to field wrappers and structural elements. ChangesForm updates
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/src/controllers/form.ts`:
- Line 242: Align structural field rendering between the embed and admin
preview: update the embed handling for divider, heading, and paragraph in the
relevant controller/rendering logic so cssClass is applied to the same wrapper
or inner element used by FormPreview.tsx. Ensure all three cases consistently
target the matching DOM element and preserve existing content and styling
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 8d07fb91-6a3f-4e9e-8ece-0b2f7f0eca46
📒 Files selected for processing (3)
README.mdadmin/src/components/FormPreview.tsxserver/src/controllers/form.ts
| if (field.type === 'divider') { | ||
| var hr = document.createElement('hr'); | ||
| hr.className = 'sfb-divider'; | ||
| if (field.cssClass) hr.className += ' ' + field.cssClass; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Admin preview and embed apply cssClass to different elements for structural types.
For divider, heading, and paragraph, the admin preview (FormPreview.tsx lines 240/248/256) puts cssClass on a wrapper <div>, while the embed puts it directly on the element (<hr>, <p>, <p>). A user styling .my-heading in the admin preview targets a wrapper div, but in production the same class sits on the <p> itself — different box model, different cascade. This means the admin preview won't faithfully reflect how cssClass-based styles render in the embed.
Consider wrapping these elements in a <div> in the embed (matching the admin preview) or moving cssClass to the inner element in the admin preview, so both renderers apply the class to the same element in the DOM tree.
Also applies to: 250-250, 259-259
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@server/src/controllers/form.ts` at line 242, Align structural field rendering
between the embed and admin preview: update the embed handling for divider,
heading, and paragraph in the relevant controller/rendering logic so cssClass is
applied to the same wrapper or inner element used by FormPreview.tsx. Ensure all
three cases consistently target the matching DOM element and preserve existing
content and styling behavior.
Summary
cssClass— it was stored in settings but never applied to any rendered element (dead field). It's now added to the field's wrapper in the embed, the hosted public page, and the admin preview, so an embedding developer can target a single field from their own stylesheet.--sfb-*/.sfb-*styling contract, the per-field CSS class, the CAPTCHA submit error, test commands, and updates the roadmap.Why cssClass (and not the global customCss)
cssClassonly adds a class name to the DOM — no arbitrary CSS injection, so no scoping/footgun risk. The developer writes the CSS in their own host stylesheet. Because the class sits on the field wrapper (not the input),.my-class inputnaturally out-specifies the plugin's flat.sfb-inputrule — clean override, no!important.Verification
<div class="sfb-field my-custom-class" ...>.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation