Skip to content

feat: per-field CSS class hook + README refresh#71

Merged
devCluna merged 1 commit into
mainfrom
feat/css-class-hook
Jul 9, 2026
Merged

feat: per-field CSS class hook + README refresh#71
devCluna merged 1 commit into
mainfrom
feat/css-class-hook

Conversation

@devCluna

@devCluna devCluna commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Wire the per-field 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.
  • README refresh — documents CAPTCHA, hidden tracking fields, the --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)

cssClass only 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 input naturally out-specifies the plugin's flat .sfb-input rule — clean override, no !important.

Verification

  • Type-check (server + admin) ✓, build ✓, 17/17 tests ✓.
  • Verified in the rendered DOM via headless Chrome: <div class="sfb-field my-custom-class" ...>.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for optional CAPTCHA protection, including Turnstile and reCAPTCHA v2.
    • Added hidden tracking fields with URL-prefilled values, defaults, and CSV export support.
    • Added redirect URL configuration for forms.
    • Added custom CSS class support for embedded form fields and content blocks.
  • Documentation

    • Expanded setup guidance for CAPTCHA, tracking fields, embedded-form styling, and security configuration.
    • Documented CAPTCHA verification failures and rate-limiting responses.
    • Added instructions for running tests and type checks.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The 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.

Changes

Form updates

Layer / File(s) Summary
Propagate field CSS classes
admin/src/components/FormPreview.tsx, server/src/controllers/form.ts
Admin previews and embedded forms now apply field.cssClass to structural and generic field wrappers.
Document form capabilities
README.md
README documentation covers CAPTCHA, hidden tracking fields, styling, API errors, development checks, and completed roadmap items.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

A bunny hops through fields with flair,
CSS classes bloom everywhere.
CAPTCHA guards and trackers hide,
README pages grow wide-eyed.
Thump, thump—forms are dressed with care!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding per-field CSS class support and updating the README.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/css-class-hook

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8e658a6 and f60f87b.

📒 Files selected for processing (3)
  • README.md
  • admin/src/components/FormPreview.tsx
  • server/src/controllers/form.ts

if (field.type === 'divider') {
var hr = document.createElement('hr');
hr.className = 'sfb-divider';
if (field.cssClass) hr.className += ' ' + field.cssClass;

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.

🎯 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.

@devCluna devCluna merged commit e182ba6 into main Jul 9, 2026
3 checks passed
@devCluna devCluna deleted the feat/css-class-hook branch July 9, 2026 22:36
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.

1 participant