Skip to content

refactor(form-builder): improve routing form and field input components#1736

Open
github-actions[bot] wants to merge 6 commits into
mainfrom
routing_form_improvements
Open

refactor(form-builder): improve routing form and field input components#1736
github-actions[bot] wants to merge 6 commits into
mainfrom
routing_form_improvements

Conversation

@github-actions
Copy link
Copy Markdown

@github-actions github-actions Bot commented May 13, 2026

Summary

This PR refactors and improves the routing form and form builder components, including UI/UX enhancements, styling improvements, and code simplifications.

Changes

  • Refactored duplicated logic in Canvas and Real Form renderer
  • Improved styling and appearance of form fields and routing form
  • Simplified routing form styling code with UI changes
  • Added new FormFieldInput component with enhanced functionality
  • Updated calendar and time picker components with minor fixes
  • Hid calendar field for non-enterprise users
  • Improved FieldRenderer and FieldSettingsPanel components
  • Updated routing form theme and routing link page

Testing Notes

  • Verify routing form UI and UX improvements
  • Test form field inputs and appearance in form builder
  • Confirm calendar field visibility based on user type
  • Check for any regressions in form rendering and field settings
  • Validate that routing links work correctly with updated form components

@github-actions github-actions Bot added the main Auto PR target: main label May 13, 2026
@github-actions
Copy link
Copy Markdown
Author

This PR is being marked as stale due to inactivity.

@github-actions github-actions Bot added the stale label May 28, 2026
@avnotaklu avnotaklu removed the stale label May 28, 2026
@github-actions github-actions Bot changed the title refactor(form-builder): improve routing form and field input handling refactor(form-builder): improve routing form styling and simplify code May 28, 2026
@avnotaklu
Copy link
Copy Markdown

@greptile

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR refactors the routing form field rendering by extracting shared components (FormFieldInput, FormFieldRow, FormFieldWrapper, formFieldAppearance) and consolidating duplicated styling logic that previously existed separately in FieldRenderer and FormInputFields.

  • FormFieldInput unifies preview (canvas) and runtime (public form) rendering into a single switch-based component, delegating from FieldRenderer and FormInputFields.
  • formFieldAppearance.ts centralises appearance/style derivation; getRoutingFormTheme.ts adds new CSS-variable-based theming driven by a secondary colour config.
  • FieldLibrary now hides the calendar field type for non-enterprise users, gated via useMeQuery.

Confidence Score: 3/5

Not safe to merge as-is: radio button accent colour and checkbox icon colour regress to secondaryColor on all forms where the two colours differ, and the date/time picker components in the calendar field will receive undefined CSS variables in non-underline mode, potentially breaking their appearance.

Three concrete wrong-colour bugs were introduced during consolidation: RadioField.accentColor now receives secondaryColor, checkboxStyle.color also receives secondaryColor instead of accentColor, and both ExtendedDatePicker and TimePicker always pass a truthy resolvedUnderlineColor as secondaryColor to getFieldAppearance, which unconditionally injects CSS-variable-based styling classes even when no secondary theme is active and the required CSS variables are not defined.

packages/features/form-builder/components/FormFieldInput.tsx (radio/checkbox colour props), packages/app-store/routing-forms/components/calendar/ExtendedDatePicker.tsx and TimePicker.tsx (secondary-theme class guard)

Important Files Changed

Filename Overview
packages/features/form-builder/components/FormFieldInput.tsx New unified field-input component consolidating preview and runtime rendering; contains two behavioral regressions: RadioField receives secondaryColor for its accentColor prop instead of the actual accentColor prop, and checkboxStyle.color uses secondaryColor instead of accentColor.
packages/app-store/routing-forms/components/calendar/ExtendedDatePicker.tsx Refactored to use shared getFieldAppearance; but resolvedUnderlineColor (always truthy) is passed as secondaryColor, causing secondary-theme CSS-variable classes to be applied even in default mode where those variables are not defined.
packages/app-store/routing-forms/components/calendar/TimePicker.tsx Same resolvedUnderlineColor-as-secondaryColor bug as ExtendedDatePicker: secondary-theme CSS-variable classes applied unconditionally in default variant.
packages/features/form-builder/components/formFieldAppearance.ts New shared appearance helper that centralises field-style logic; implementation looks correct but is sensitive to a truthy secondaryColor activating CSS-variable classes, which callers in ExtendedDatePicker and TimePicker exploit unintentionally.
packages/app-store/routing-forms/lib/getRoutingFormTheme.ts New utility for resolving routing form theme colours and CSS; normalizeColor duplicates logic that also exists in FieldSettingsPanel.tsx but is otherwise clean.
packages/features/form-builder/components/FormFieldRow.tsx Simple layout component that centralises col-span logic for full/half-width fields; straightforward extraction with no issues.
packages/features/form-builder/components/FormFieldWrapper.tsx New shared wrapper that standardises label, help text, and error rendering across canvas and runtime renderers; clean extraction.
packages/features/form-builder/components/FieldRenderer.tsx Replaced ~260 lines of field-switch logic with a thin delegate to FormFieldInput in preview mode; clean simplification.
packages/app-store/routing-forms/components/FormInputFields.tsx Substantially slimmed by delegating custom-field rendering to FormFieldInput and layout to FormFieldRow/FormFieldWrapper; the accentColor-to-checkboxStyle regression lives in the new FormFieldInput component it delegates to.
packages/features/form-builder/components/FieldSettingsPanel.tsx Adds debounced colour input for secondaryColor, normalises hex values on change, and auto-resets panel tab when field selection changes; all small and correct, though normalizeHexColor is now duplicated from getRoutingFormTheme.ts.
packages/features/form-builder/components/FormBuilderPage.tsx Integrates resolveRoutingFormTheming for theme CSS and fetches enterprise status via useMeQuery to conditionally hide the calendar field type; straightforward and correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[FormInputFields] --> B[FormFieldRow]
    A --> C[FormFieldWrapper]
    C --> D[FormFieldInput]
    E[FieldRenderer] --> D
    D --> F{field.type}
    F --> G[text / email / phone / textarea]
    F --> H[date DatePicker]
    F --> I[calendar CalendarFieldController]
    F --> J[select / multiselect]
    F --> K[radio / checkbox / boolean]
    F --> L[layout divider / heading / paragraph]
    D --> M[getFieldAppearance]
    M --> N[CSS vars ROUTING_FORM_THEME_CSS]
    N --> O[data-routing-form-theme=secondary]
Loading

Fix All in Claude Code Fix All in Codex

Reviews (1): Last reviewed commit: "chore: Simplify routing form styling cod..." | Re-trigger Greptile

Comment on lines +262 to +271
<RadioField
key={index}
id={`${field.id}-radio-${index}`}
label={option.label}
value={String(option.value)}
disabled={disabled}
accentColor={secondaryColor}
secondaryColor={secondaryColor}
variant={uiConfig.radioVariant ?? "default"}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 RadioField accentColor regression

accentColor is set to secondaryColor here, discarding the accentColor prop entirely. In the original FormInputFields.tsx the radio button received the actual accentColor prop (accentColor={accentColor}). Any form where the two color values differ will now show the wrong accent on radio buttons.

Suggested change
<RadioField
key={index}
id={`${field.id}-radio-${index}`}
label={option.label}
value={String(option.value)}
disabled={disabled}
accentColor={secondaryColor}
secondaryColor={secondaryColor}
variant={uiConfig.radioVariant ?? "default"}
/>
accentColor={accentColor}
secondaryColor={secondaryColor}

Fix in Claude Code Fix in Codex

Comment on lines +67 to +70
const checkboxStyle = {
...(secondaryColor ? { color: secondaryColor } : {}),
...(secondaryColor ? { borderColor: secondaryColor } : {}),
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 checkboxStyle.color uses wrong prop

color is set from secondaryColor but the original code used accentColor for the color property and secondaryColor only for borderColor. The accentColor prop (available in scope) is completely unused in this style object, causing checkbox ticks/icons to render with secondaryColor instead of accentColor.

Suggested change
const checkboxStyle = {
...(secondaryColor ? { color: secondaryColor } : {}),
...(secondaryColor ? { borderColor: secondaryColor } : {}),
};
const checkboxStyle = {
...(accentColor ? { color: accentColor } : {}),
...(secondaryColor ? { borderColor: secondaryColor } : {}),
};

Fix in Claude Code Fix in Codex

? "var(--cal-border-muted)"
: underlineColor ?? "var(--cal-secondary)";
const underlineStyle = isUnderline ? { borderBottomColor: resolvedUnderlineColor } : undefined;
const { dateButtonClassName, underlineStyle } = getFieldAppearance(variant, resolvedUnderlineColor);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Secondary-theme CSS classes applied unconditionally in default mode

resolvedUnderlineColor is always a non-empty string (underlineColor ?? "var(--cal-secondary)"), so getFieldAppearance always receives a truthy secondaryColor. When variant === "default", hasSecondaryTheme becomes true and dateButtonClassName gets classes like bg-[var(--routing-input-surface)] / border-[var(--routing-input-border)]. Those CSS custom properties are only defined under [data-routing-form-theme="secondary"]; without that ancestor they resolve to their initial values, stripping the button of its normal background/border and breaking its visual appearance. The same problem exists in TimePicker.tsx line 45.

Suggested change
const { dateButtonClassName, underlineStyle } = getFieldAppearance(variant, resolvedUnderlineColor);
const { dateButtonClassName, underlineStyle } = getFieldAppearance(variant, isUnderline ? resolvedUnderlineColor : undefined);

Fix in Claude Code Fix in Codex

}),
}
: undefined;
const { selectControlClassName, selectStyles } = getFieldAppearance(variant, resolvedUnderlineColor);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Same issue as ExtendedDatePicker: resolvedUnderlineColor is always truthy, so secondary-theme CSS-variable classes are always applied. Guard with isUnderline to avoid injecting undefined CSS-variable references in default mode.

Suggested change
const { selectControlClassName, selectStyles } = getFieldAppearance(variant, resolvedUnderlineColor);
const { selectControlClassName, selectStyles } = getFieldAppearance(variant, isUnderline ? resolvedUnderlineColor : undefined);

Fix in Claude Code Fix in Codex

@avnotaklu avnotaklu force-pushed the routing_form_improvements branch from 71065dd to b260136 Compare May 28, 2026 11:50
@github-actions github-actions Bot changed the title refactor(form-builder): improve routing form styling and simplify code refactor(routing): improve routing form styling and code structure May 28, 2026
@github-actions github-actions Bot changed the title refactor(routing): improve routing form styling and code structure refactor(form-builder): improve routing form and field input components May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

main Auto PR target: main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant