Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@TWilson023
Copy link
Collaborator

@TWilson023 TWilson023 commented Nov 10, 2025

  • Fix placeholders
  • Update bounty description max character counter
  • Fix overflow/scrolling/max-height
  • Improve prose spacing+consistency
  • Add rich editor for integrations overview

Summary by CodeRabbit

  • New Features

    • Rich text editors now support markdown formatting (headings, bold, italic, and links) in bounty descriptions and app overviews
    • New styling presets for text editors: default, condensed, and relaxed modes
  • Improvements

    • Expanded editor areas with scrolling support for improved content editing
    • Enhanced character counter display with better number formatting

@vercel
Copy link
Contributor

vercel bot commented Nov 10, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Nov 10, 2025 8:23pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

This PR introduces styling flexibility to the RichTextEditor system by adding a style prop with preset configurations (default, condensed, relaxed), enhances character counting with optional spacing, and replaces plain textareas with rich text editors in OAuth app management forms while applying consistent prose styling across multiple components.

Changes

Cohort / File(s) Change Summary
RichTextProvider core styling
packages/ui/src/rich-text-area/rich-text-provider.tsx
Exports PROSE_STYLES constant with three preset variants (default, condensed, relaxed) for margin control; adds optional style prop to RichTextProviderProps; integrates selected prose style into editor's root className
Character counter formatting
apps/web/ui/shared/max-characters-counter.tsx
Adds optional spaced prop for controlling spacing around slash separator; formats both current and max character counts using nFormatter with full representation
OAuth app editors (textarea → RichTextEditor)
apps/web/ui/oauth-apps/add-edit-app-form.tsx, apps/web/ui/oauth-apps/add-edit-integration-form.tsx
Replaces TextareaAutosize with RichTextProvider-wrapped editors (RichTextArea + RichTextToolbar); supports markdown, headings, bold, italic, and links; editor editable state gated by canManageApp permission
Editor height and scroll configuration
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx, apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor.tsx, apps/web/ui/shared/message-input.tsx
Adds style prop to RichTextProvider; expands editor height from max-h-24 to max-h-48; enables overflow-auto and scrollbar-hide for smooth scrolling
Prose styling application
apps/web/ui/messages/messages-panel.tsx, apps/web/ui/partners/bounties/claim-bounty-modal.tsx
Applies PROSE_STYLES utility classes to markdown components; consolidates hardcoded prose class combinations into preset style variants for consistent rendering

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify PROSE_STYLES constant correctly applies across all RichTextProvider instances and rendering contexts
  • Confirm OAuth app editor replacements preserve functionality: getMarkdown() extraction for readme value, canManageApp permission gating, and read-only state handling
  • Validate nFormatter integration with MaxCharactersCounter produces expected formatted output for all character count displays

Possibly related PRs

  • Rich text messages and bounties #3067: Introduces RichTextProvider/RichTextArea foundation that this PR builds upon with styling enhancements and character counter updates
  • Bounty submission character limit #3049: Adds MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH limit and counter display in claim-bounty-modal; this PR updates the same character counting UI with new MaxCharactersCounter props
  • Partner comment editing #2850: Modifies the same MessageInput component; this PR adds styling/scroll configuration while the related PR adjusts props and lifecycle behavior

Suggested reviewers

  • steven-tey

Poem

🐰 Whiskers twitch with delight,
Rich text editors now styled just right!
With prose presets dancing in three,
And counters formatted—one, two, three!
OAuth forms bloom with markdown's embrace,
A thousand more features fall into place!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Rich text fixes/improvements' is vague and generic, using non-descriptive terms that don't convey meaningful information about the specific changes in the changeset. Consider using a more specific title that captures the main change, such as 'Add rich text editor styling improvements and prose formatting consistency' or reference the primary objective.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rich-text-fixes

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/ui/oauth-apps/add-edit-integration-form.tsx (1)

244-270: LGTM! Rich text editor implementation is solid.

The conversion from TextareaAutosize to RichTextEditor is well-implemented:

  • Proper permission handling via editable={canManageApp} and container disabled styling
  • Feature selection (headings, bold, italic, links) is appropriate for integration overview
  • The style="relaxed" and overflow/scrolling fixes align with PR objectives
  • Markdown extraction in onChange correctly syncs editor state with form data
  • Initial value and null handling are correct

Optional: Consider improving type safety on line 255

The type assertion (editor as any).getMarkdown() works correctly since markdown mode is enabled, but could be improved with proper typing. However, this would require changes to the RichTextProvider types in the @dub/ui package, which is outside the scope of this PR.

If you decide to improve this in a future PR, you could add proper typing to the editor instance when markdown is enabled:

// In packages/ui/src/rich-text-area/rich-text-provider.tsx
// Add a type that includes getMarkdown() when markdown is true
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0623f8c and 38dc267.

📒 Files selected for processing (9)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx (4 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor.tsx (1 hunks)
  • apps/web/ui/messages/messages-panel.tsx (2 hunks)
  • apps/web/ui/oauth-apps/add-edit-app-form.tsx (2 hunks)
  • apps/web/ui/oauth-apps/add-edit-integration-form.tsx (2 hunks)
  • apps/web/ui/partners/bounties/claim-bounty-modal.tsx (2 hunks)
  • apps/web/ui/shared/max-characters-counter.tsx (1 hunks)
  • apps/web/ui/shared/message-input.tsx (1 hunks)
  • packages/ui/src/rich-text-area/rich-text-provider.tsx (5 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx:180-189
Timestamp: 2025-09-24T15:50:16.414Z
Learning: TWilson023 prefers to keep security vulnerability fixes separate from refactoring PRs when the vulnerable code is existing and was only moved/relocated rather than newly introduced.
📚 Learning: 2025-10-15T01:05:43.266Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2958
File: apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx:432-457
Timestamp: 2025-10-15T01:05:43.266Z
Learning: In apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx, defer refactoring the custom MenuItem component (lines 432-457) to use the shared dub/ui MenuItem component to a future PR, as requested by steven-tey.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor.tsx
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx
  • apps/web/ui/oauth-apps/add-edit-integration-form.tsx
📚 Learning: 2025-09-24T15:47:40.293Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx:152-157
Timestamp: 2025-09-24T15:47:40.293Z
Learning: The Button component from dub/ui automatically adds type="button" when an onClick prop is passed, preventing accidental form submissions without requiring explicit type specification. The implementation uses: type={onClick ? "button" : type}

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx
  • apps/web/ui/oauth-apps/add-edit-integration-form.tsx
📚 Learning: 2025-09-24T15:47:40.293Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx:152-157
Timestamp: 2025-09-24T15:47:40.293Z
Learning: The Button component from dub/ui automatically adds type="button" when an onClick prop is passed, preventing accidental form submissions without requiring explicit type specification.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx
  • apps/web/ui/oauth-apps/add-edit-app-form.tsx
  • apps/web/ui/oauth-apps/add-edit-integration-form.tsx
📚 Learning: 2025-09-24T16:10:37.349Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/ui/partners/partner-about.tsx:11-11
Timestamp: 2025-09-24T16:10:37.349Z
Learning: In the Dub codebase, the team prefers to import Icon as a runtime value from "dub/ui" and uses Icon as both a type and variable name in component props, even when this creates shadowing. This is their established pattern and should not be suggested for refactoring.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx
  • apps/web/ui/oauth-apps/add-edit-app-form.tsx
  • apps/web/ui/messages/messages-panel.tsx
  • apps/web/ui/oauth-apps/add-edit-integration-form.tsx
📚 Learning: 2025-09-24T15:47:40.293Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx:152-157
Timestamp: 2025-09-24T15:47:40.293Z
Learning: The Button component from dub/ui automatically sets type="button" when an onClick prop is passed and defaults to type="submit" otherwise, using the logic: type={props.onClick ? "button" : "submit"}. This prevents accidental form submissions when buttons are used for modal triggers or other non-form actions.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx
🧬 Code graph analysis (5)
apps/web/ui/partners/bounties/claim-bounty-modal.tsx (1)
packages/ui/src/rich-text-area/rich-text-provider.tsx (1)
  • PROSE_STYLES (20-24)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx (2)
apps/web/ui/shared/max-characters-counter.tsx (1)
  • MaxCharactersCounter (4-26)
apps/web/lib/constants/bounties.ts (1)
  • BOUNTY_DESCRIPTION_MAX_LENGTH (1-1)
apps/web/ui/oauth-apps/add-edit-app-form.tsx (3)
packages/ui/src/rich-text-area/rich-text-provider.tsx (1)
  • RichTextProvider (69-242)
packages/ui/src/rich-text-area/index.tsx (1)
  • RichTextArea (9-32)
packages/ui/src/rich-text-area/rich-text-toolbar.tsx (1)
  • RichTextToolbar (16-129)
apps/web/ui/messages/messages-panel.tsx (1)
packages/ui/src/rich-text-area/rich-text-provider.tsx (1)
  • PROSE_STYLES (20-24)
apps/web/ui/oauth-apps/add-edit-integration-form.tsx (3)
packages/ui/src/rich-text-area/rich-text-provider.tsx (1)
  • RichTextProvider (69-242)
packages/ui/src/rich-text-area/index.tsx (1)
  • RichTextArea (9-32)
packages/ui/src/rich-text-area/rich-text-toolbar.tsx (1)
  • RichTextToolbar (16-129)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (13)
apps/web/ui/shared/max-characters-counter.tsx (1)

1-26: LGTM! Clean implementation of formatted character counting.

The addition of nFormatter for both current and max values provides consistency, and the optional spaced prop adds useful flexibility for different UI contexts. The implementation is straightforward and correct.

apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor.tsx (1)

514-514: LGTM! Appropriate styling choice for campaign editor.

The style="relaxed" prop applies the relaxed prose spacing variant, which is suitable for a campaign editor where content benefits from more breathing room.

apps/web/ui/shared/message-input.tsx (1)

56-60: LGTM! Appropriate styling and overflow handling for message input.

The style="condensed" provides tight spacing suitable for message inputs, and the addition of overflow-auto scrollbar-hide enables clean scrolling when content exceeds the max height.

apps/web/ui/partners/bounties/claim-bounty-modal.tsx (1)

419-421: LGTM! Standardizes prose styling for bounty descriptions.

Applying PROSE_STYLES.default ensures consistent vertical spacing for markdown content across the application.

apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty-sheet.tsx (2)

825-825: LGTM! Increased editor height improves UX for longer descriptions.

Doubling the max-height from max-h-24 to max-h-48 provides more space for bounty descriptions, which is appropriate given the complexity of bounty requirements.


850-856: LGTM! Consistent character counter implementation.

Using the MaxCharactersCounter component with the spaced prop provides formatted, readable character counts that align with the shared component pattern.

apps/web/ui/messages/messages-panel.tsx (1)

192-193: LGTM! Standardizes message markdown styling.

Applying PROSE_STYLES.condensed provides consistent tight paragraph spacing while also adding appropriate list spacing that was previously missing.

apps/web/ui/oauth-apps/add-edit-app-form.tsx (1)

338-364: LGTM! Excellent UX improvement with rich text editor.

The replacement of the plain textarea with a full-featured rich text editor significantly enhances the editing experience for OAuth app overviews. The implementation properly handles:

  • Feature selection (headings, bold, italic, links)
  • Markdown support for the overview content
  • Disabled state via canManageApp
  • Appropriate height constraints and scrolling
  • Styling consistency with the new style="relaxed" prop
packages/ui/src/rich-text-area/rich-text-provider.tsx (4)

20-24: LGTM! Well-designed style system for rich text editors.

The PROSE_STYLES constant provides a clean, reusable way to define spacing presets:

  • default: Balanced spacing suitable for most content
  • condensed: Tight spacing for compact interfaces like messages
  • relaxed: Maximum spacing by relying on default prose styles

The as const ensures type safety, and exporting enables consistent usage across components.


40-40: LGTM! Type-safe style prop with sensible default.

The style prop uses keyof typeof PROSE_STYLES for type safety, ensuring only valid style variants can be passed. The default value of "default" maintains backward compatibility.

Also applies to: 78-78


123-123: LGTM! Correct handling of editable prop for placeholder behavior.

Using editable ?? true ensures the placeholder displays correctly when editable is undefined. The comment clearly explains the rationale.


205-207: LGTM! Proper integration of style system into editor.

The PROSE_STYLES[style] application in the className correctly applies the selected spacing preset to the editor content.

apps/web/ui/oauth-apps/add-edit-integration-form.tsx (1)

13-15: LGTM! Imports added correctly.

The new RichTextArea, RichTextProvider, and RichTextToolbar imports are necessary for the rich text editor implementation and follow the existing import pattern.

@steven-tey steven-tey merged commit f0fe555 into main Nov 10, 2025
8 checks passed
@steven-tey steven-tey deleted the rich-text-fixes branch November 10, 2025 23:17
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