-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add RTL alignment support to program lander + application pages #3073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis pull request systematically adds bidirectional text support across the application by introducing Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
apps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsx (1)
51-72: Default RTL flag never makes it into the form
useProgram()resolves asynchronously, so on the first renderprogramisundefined.useFormonly consumesdefaultValuesduring that first render, which leavesdirectionstuck asundefined. When the program finishes loading withrtlContentEnabledAt, new accordion blocks still default to LTR unless the author notices and manually flips the toggle. Please hydrate the form once the program arrives (and only when the user hasn’t already touched the field) so RTL defaults kick in automatically. One way is to importuseEffect, surfaceisDirty, and callsetValuewithshouldDirty: false.-import { Dispatch, SetStateAction, useId, useRef } from "react"; +import { Dispatch, SetStateAction, useEffect, useId, useRef } from "react"; … - formState: { errors }, + formState: { errors, isDirty }, } = useForm<AccordionBlockData>({ … - direction: program?.rtlContentEnabledAt ? "rtl" : undefined, + direction: program?.rtlContentEnabledAt ? "rtl" : undefined, }, }); + + useEffect(() => { + if (!defaultValues?.direction && program?.rtlContentEnabledAt && !isDirty) { + setValue("direction", "rtl", { shouldDirty: false }); + } + }, [ + defaultValues?.direction, + program?.rtlContentEnabledAt, + isDirty, + setValue, + ]);apps/web/ui/partners/groups/design/lander/modals/text-block-modal.tsx (1)
43-107: Same async default bug hereThe text block modal has the same sequencing issue:
directionis derived fromprograminsidedefaultValues, butprogramisundefinedon the initial render. After the SWR fetch completes, the form keeps the originalundefinedvalue, so RTL-enabled programs still default to LTR when authors create new text blocks. Please mirror theuseEffectpattern (importuseEffect, exposesetValueandisDirty) to seed"rtl"when the toggle is available and untouched.-import { Dispatch, SetStateAction, useId } from "react"; +import { Dispatch, SetStateAction, useEffect, useId } from "react"; … - const { - handleSubmit, - register, - control, - formState: { errors }, - } = useForm<TextBlockData>({ + const { + handleSubmit, + register, + control, + setValue, + formState: { errors, isDirty }, + } = useForm<TextBlockData>({ defaultValues: { direction: program?.rtlContentEnabledAt ? "rtl" : undefined, ...defaultValues, }, }); + + useEffect(() => { + if (!defaultValues?.direction && program?.rtlContentEnabledAt && !isDirty) { + setValue("direction", "rtl", { shouldDirty: false }); + } + }, [ + defaultValues?.direction, + program?.rtlContentEnabledAt, + isDirty, + setValue, + ]);apps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsx (1)
86-283: Propagation gap for RTL defaultsThis modal also relies on
program?.rtlContentEnabledAtinside the first-renderdefaultValues, so it never updates once the program finishes loading. Result: on programs with RTL enabled, newly added short-text questions stay LTR unless the user toggles manually. Align with the other modals by seeding the field after the fetch—importuseEffect, exposesetValue/isDirty, and set"rtl"only when there isn’t an explicitdefaultValues?.directionand the form hasn’t been touched.-import { Dispatch, SetStateAction, useId } from "react"; +import { Dispatch, SetStateAction, useEffect, useId } from "react"; … - const { - control, - handleSubmit, - register, - formState: { errors }, - watch, - } = useForm<FormData>({ + const { + control, + handleSubmit, + register, + setValue, + formState: { errors, isDirty }, + watch, + } = useForm<FormData>({ defaultValues: { direction: program?.rtlContentEnabledAt ? "rtl" : undefined, ...formDataForShortTextFieldData(defaultValues), }, }); + + useEffect(() => { + if (!defaultValues?.direction && program?.rtlContentEnabledAt && !isDirty) { + setValue("direction", "rtl", { shouldDirty: false }); + } + }, [ + defaultValues?.direction, + program?.rtlContentEnabledAt, + isDirty, + setValue, + ]);apps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsx (1)
86-105: Default RTL state never activates after async program load
useProgram()returnsprogramasynchronously, souseFormfreezes the initial default withdirection: undefined. When the SWR request resolves, the form still thinks direction is unset, the toggle appears unchecked, and submissions persist"ltr"unless the user toggles manually. This breaks the expected default behavior for RTL-enabled programs. Please backfilldirectionwhen the program data arrives.-import { Dispatch, SetStateAction, useId } from "react"; +import { Dispatch, SetStateAction, useEffect, useId } from "react"; @@ - const { - control, - handleSubmit, - register, - formState: { errors }, - watch, - } = useForm<FormData>({ + const { + control, + handleSubmit, + register, + formState: { errors }, + watch, + setValue, + } = useForm<FormData>({ @@ - const maxLengthEnabled = watch("data.maxLengthEnabled"); + const direction = watch("direction"); + const maxLengthEnabled = watch("data.maxLengthEnabled"); + + useEffect(() => { + if ( + program?.rtlContentEnabledAt && + !defaultValues?.direction && + !direction + ) { + setValue("direction", "rtl", { shouldDirty: false }); + } + }, [program?.rtlContentEnabledAt, defaultValues?.direction, direction, setValue]);apps/web/ui/partners/groups/design/application-form/modals/multiple-choice-field-modal.tsx (1)
47-113: Multiple-choice RTL toggle also starts in the wrong stateSame async timing problem here:
useFormcapturesdirectionbeforeprogramis available, so the toggle renders unchecked and saved data remains LTR unless the user intervenes. Please seed the field once the program arrives.-import { Dispatch, SetStateAction, useId, useRef } from "react"; +import { Dispatch, SetStateAction, useEffect, useId, useRef } from "react"; @@ - const { - handleSubmit, - register, - watch, - setValue, - setError, - clearErrors, - formState: { errors }, - control, - } = form; + const { + handleSubmit, + register, + watch, + setValue, + setError, + clearErrors, + formState: { errors }, + control, + } = form; @@ - const fields = watch("data.options"); + const direction = watch("direction"); + const fields = watch("data.options"); + + useEffect(() => { + if ( + program?.rtlContentEnabledAt && + !defaultValues?.direction && + !direction + ) { + setValue("direction", "rtl", { shouldDirty: false }); + } + }, [program?.rtlContentEnabledAt, defaultValues?.direction, direction, setValue]);
🧹 Nitpick comments (5)
apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
4-10: Consider making the component generic for type safety.The
Control<any>type loses type safety. Consider making the component generic to preserve form type information.Apply this diff to improve type safety:
-export function RightToLeftToggle({ +export function RightToLeftToggle<T extends Record<string, any>>({ control, name, }: { - control: Control<any>; + control: Control<T>; name: string; }) {apps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsx (1)
61-61: Consider defaulting to "ltr" instead of undefined.When
rtlContentEnabledAtis falsy,directionis set toundefined. WhileRightToLeftTogglehandles this, explicitly defaulting to"ltr"would be more consistent and clearer.Apply this diff:
- direction: program?.rtlContentEnabledAt ? "rtl" : undefined, + direction: program?.rtlContentEnabledAt ? "rtl" : "ltr",apps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsx (1)
62-62: Consider defaulting to "ltr" instead of undefined.Similar to the select-field-modal, explicitly defaulting to
"ltr"would be more consistent than usingundefined.Apply this diff:
- direction: program?.rtlContentEnabledAt ? "rtl" : undefined, + direction: program?.rtlContentEnabledAt ? "rtl" : "ltr",apps/web/ui/partners/lander/lander-hero.tsx (1)
26-26: Simplify thedirattribute logic.The current conditional checks if content exists before applying direction, but this is unnecessary. Additionally,
landerData.directioncould beundefined, which would result in an undefineddirattribute.Apply this diff to all three elements:
- dir={landerData.label ? landerData.direction : "ltr"} + dir={landerData.direction || "ltr"}This ensures:
- Direction applies whether using custom or default text
- Always falls back to
"ltr"if direction is undefinedAlso applies to: 35-35, 44-44
apps/web/ui/partners/lander/blocks/text-block.tsx (1)
13-16: Consider providing explicit fallback fordirattribute.Since
block.data.directioncan beundefined, it's better to explicitly fall back to"ltr"to ensure consistent behavior.Apply this diff:
- <BlockTitle title={block.data.title} dir={block.data.direction} /> - <BlockMarkdown dir={block.data.direction}> + <BlockTitle title={block.data.title} dir={block.data.direction || "ltr"} /> + <BlockMarkdown dir={block.data.direction || "ltr"}> {block.data.content} </BlockMarkdown>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
apps/web/lib/zod/schemas/program-application-form.ts(6 hunks)apps/web/lib/zod/schemas/program-lander.ts(5 hunks)apps/web/lib/zod/schemas/programs.ts(1 hunks)apps/web/ui/partners/groups/design/application-form/application-hero-preview.tsx(2 hunks)apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx(2 hunks)apps/web/ui/partners/groups/design/application-form/fields/long-text-field.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/fields/multiple-choice-field.tsx(2 hunks)apps/web/ui/partners/groups/design/application-form/fields/select-field.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/fields/short-text-field.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/modals/edit-application-hero-modal.tsx(3 hunks)apps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/application-form/modals/multiple-choice-field-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/lander/modals/edit-hero-modal.tsx(3 hunks)apps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsx(5 hunks)apps/web/ui/partners/groups/design/lander/modals/text-block-modal.tsx(4 hunks)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx(1 hunks)apps/web/ui/partners/lander/blocks/accordion-block.tsx(1 hunks)apps/web/ui/partners/lander/blocks/block-markdown.tsx(1 hunks)apps/web/ui/partners/lander/blocks/block-title.tsx(1 hunks)apps/web/ui/partners/lander/blocks/files-block.tsx(2 hunks)apps/web/ui/partners/lander/blocks/text-block.tsx(1 hunks)apps/web/ui/partners/lander/lander-hero.tsx(4 hunks)packages/prisma/schema/program.prisma(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 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-09-17T17:44:03.965Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2857
File: apps/web/lib/actions/partners/update-program.ts:96-0
Timestamp: 2025-09-17T17:44:03.965Z
Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.
Applied to files:
apps/web/lib/zod/schemas/programs.ts
📚 Learning: 2025-10-15T01:52:37.048Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2958
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/members/page-client.tsx:270-303
Timestamp: 2025-10-15T01:52:37.048Z
Learning: In React components with dropdowns or form controls that show modals for confirmation (e.g., role selection, delete confirmation), local state should be reverted to match the prop value when the modal is cancelled. This prevents the UI from showing an unconfirmed change. The solution is to either: (1) pass an onClose callback to the modal that resets the local state, or (2) observe modal visibility state and reset on close. Example context: RoleCell component in apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/members/page-client.tsx where role dropdown should revert to user.role when UpdateUserModal is cancelled.
Applied to files:
apps/web/ui/partners/groups/design/application-form/modals/edit-application-hero-modal.tsxapps/web/ui/partners/groups/design/lander/modals/edit-hero-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/multiple-choice-field-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsxapps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsxapps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsxapps/web/ui/partners/groups/design/lander/modals/text-block-modal.tsx
📚 Learning: 2025-07-30T15:25:13.936Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx:56-66
Timestamp: 2025-07-30T15:25:13.936Z
Learning: In apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx, the form schema uses partial condition objects to allow users to add empty/unconfigured condition fields without type errors, while submission validation uses strict schemas to ensure data integrity. This two-stage validation pattern improves UX by allowing progressive completion of complex forms.
Applied to files:
apps/web/ui/partners/groups/design/application-form/modals/edit-application-hero-modal.tsxapps/web/lib/zod/schemas/program-application-form.ts
📚 Learning: 2025-09-18T16:33:17.719Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2858
File: apps/web/ui/partners/partner-application-tabs.tsx:1-1
Timestamp: 2025-09-18T16:33:17.719Z
Learning: When a React component in Next.js App Router uses non-serializable props (like setState functions), adding "use client" directive can cause serialization warnings. If the component is only imported by Client Components, it's better to omit the "use client" directive to avoid these warnings while still getting client-side execution through promotion.
Applied to files:
apps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsxapps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsxapps/web/ui/partners/groups/design/lander/modals/text-block-modal.tsx
📚 Learning: 2025-08-25T21:03:24.285Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2736
File: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/bounty-card.tsx:1-1
Timestamp: 2025-08-25T21:03:24.285Z
Learning: In Next.js App Router, Server Components that use hooks can work without "use client" directive if they are only imported by Client Components, as they get "promoted" to run on the client side within the Client Component boundary.
Applied to files:
apps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsxapps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsxapps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsxapps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsxapps/web/ui/partners/groups/design/lander/modals/text-block-modal.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/ui/partners/groups/design/application-form/fields/form-control.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/ui/partners/groups/design/application-form/fields/form-control.tsx
📚 Learning: 2025-10-17T08:18:19.278Z
Learnt from: devkiran
Repo: dubinc/dub PR: 0
File: :0-0
Timestamp: 2025-10-17T08:18:19.278Z
Learning: In the apps/web codebase, `@/lib/zod` should only be used for places that need OpenAPI extended zod schema. All other places should import from the standard `zod` package directly using `import { z } from "zod"`.
Applied to files:
apps/web/lib/zod/schemas/program-lander.tsapps/web/lib/zod/schemas/program-application-form.ts
🧬 Code graph analysis (16)
apps/web/ui/partners/groups/design/application-form/modals/edit-application-hero-modal.tsx (1)
apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
packages/ui/src/tooltip.tsx (1)
InfoTooltip(193-199)
apps/web/ui/partners/groups/design/lander/modals/edit-hero-modal.tsx (1)
apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/application-form/modals/multiple-choice-field-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/application-form/application-hero-preview.tsx (1)
apps/web/ui/partners/lander/blocks/block-markdown.tsx (1)
BlockMarkdown(5-35)
apps/web/ui/partners/lander/blocks/text-block.tsx (2)
apps/web/ui/partners/lander/blocks/block-title.tsx (1)
BlockTitle(3-14)apps/web/ui/partners/lander/blocks/block-markdown.tsx (1)
BlockMarkdown(5-35)
apps/web/ui/partners/groups/design/application-form/modals/short-text-field-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/application-form/fields/select-field.tsx (1)
apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx (1)
FormControl(20-54)
apps/web/ui/partners/lander/lander-hero.tsx (1)
apps/web/lib/types.ts (1)
ProgramLanderData(470-470)
apps/web/ui/partners/groups/design/application-form/modals/long-text-field-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/lander/modals/accordion-block-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/lander/modals/text-block-modal.tsx (2)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-40)apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
RightToLeftToggle(4-31)
apps/web/ui/partners/groups/design/application-form/fields/short-text-field.tsx (1)
apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx (1)
FormControl(20-54)
apps/web/ui/partners/groups/design/application-form/fields/long-text-field.tsx (1)
apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx (1)
FormControl(20-54)
🔇 Additional comments (20)
packages/prisma/schema/program.prisma (1)
51-51: LGTM!The
rtlContentEnabledAtfield addition follows the established pattern for feature timestamp fields in the Program model.apps/web/ui/partners/groups/design/right-to-left-toggle.tsx (1)
11-30: LGTM!The component logic correctly toggles between "rtl" and "ltr" values, and the UI implementation with label and tooltip is clean and user-friendly.
apps/web/ui/partners/lander/blocks/accordion-block.tsx (1)
18-18: LGTM!The
dirattribute propagation correctly enables RTL layout support for the accordion block content.apps/web/ui/partners/lander/blocks/files-block.tsx (2)
15-15: LGTM!The
dirattribute correctly enables RTL layout for the files block.
45-45: Nice touch with the icon flip!The
rtl:-scale-x-100class appropriately mirrors the arrow icon in RTL mode, maintaining visual consistency with text direction.apps/web/ui/partners/groups/design/application-form/fields/select-field.tsx (1)
29-38: LGTM!The direction is correctly extracted and passed to
FormControlvialabelProps, enabling RTL support for the select field label.apps/web/ui/partners/groups/design/application-form/fields/long-text-field.tsx (1)
27-31: LGTM!The
dirprop correctly enables RTL text direction for the long text field.apps/web/ui/partners/groups/design/application-form/fields/short-text-field.tsx (1)
31-35: LGTM!The
dirprop correctly enables RTL text direction for the short text field.apps/web/ui/partners/groups/design/application-form/fields/multiple-choice-field.tsx (1)
26-26: Thedirpropagation in multiple-choice-field is consistent with the standard pattern used across other field components.Multiple-choice-field correctly passes
dir={direction}directly toFormControl, matching the pattern used by short-text-field and long-text-field. Select-field is the outlier, usinglabelProps={{ dir: direction }}instead. If consistency is desired across all field types, select-field should be reviewed rather than multiple-choice-field.apps/web/ui/partners/groups/design/application-form/modals/select-field-modal.tsx (2)
3-3: LGTM!The integration of
useProgramandRightToLeftToggleis consistent with the RTL support pattern used across other modals in this PR.Also applies to: 18-18, 45-45
247-250: LGTM!The conditional rendering and wiring of the RTL toggle is correctly implemented and consistent with other modals in this PR.
apps/web/ui/partners/groups/design/application-form/modals/edit-application-hero-modal.tsx (2)
21-21: LGTM!The import and form setup for RTL support is correct.
Also applies to: 51-51
155-161: LGTM!The RTL toggle is correctly integrated with the application form data structure.
apps/web/ui/partners/groups/design/lander/modals/edit-hero-modal.tsx (2)
15-15: LGTM!The import and form setup for RTL support is correct.
Also applies to: 43-43
134-137: LGTM!The RTL toggle integration with lander data is correctly implemented.
apps/web/ui/partners/groups/design/lander/modals/files-block-modal.tsx (2)
3-3: LGTM!The integration of
useProgramandRightToLeftTogglefollows the established pattern.Also applies to: 18-18, 49-49
261-264: LGTM!The RTL toggle is correctly integrated into the files block modal.
apps/web/ui/partners/lander/lander-hero.tsx (1)
11-14: LGTM!The type extension to include
directionis appropriate for RTL support.apps/web/ui/partners/lander/blocks/block-title.tsx (1)
1-14: LGTM!The refactor to support HTML props forwarding is well-implemented and enables clean direction propagation.
apps/web/lib/zod/schemas/programs.ts (1)
39-39: AddrtlContentEnabledAttoupdateProgramSchemato enable RTL control via the API.The field is read-only in the current implementation but should follow the same pattern as
messagingEnabledAt. Both are feature flag timestamps inProgramSchema, but onlymessagingEnabledAtis included inupdateProgramSchema(line 71). This prevents programs from enabling or disabling RTL support through the update endpoint. AddrtlContentEnabledAt: z.coerce.date().nullish()toupdateProgramSchemaand handle it inupdate-program.tssimilar tomessagingEnabledAt.⛔ Skipped due to learnings
Learnt from: TWilson023 Repo: dubinc/dub PR: 2857 File: apps/web/lib/actions/partners/update-program.ts:96-0 Timestamp: 2025-09-17T17:44:03.965Z Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/zod/schemas/program-lander.ts(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 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.
🔇 Additional comments (1)
apps/web/lib/zod/schemas/program-lander.ts (1)
4-4: LGTM! Direction schema is well-defined.The enum values match the HTML5
dirattribute standard, and marking it optional ensures backward compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/ui/partners/lander/blocks/accordion-block.tsx (1)
27-29: Adddir="auto"to the accordion content for consistent RTL support.The accordion title has
dir="auto"for RTL support, but the content (item.content) does not. If titles can be RTL, the content should also support automatic text direction.Consider adding
dir="auto"to theAccordionContentorBlockMarkdowncomponent:- <AccordionContent> + <AccordionContent dir="auto"> <BlockMarkdown className="py-2">{item.content}</BlockMarkdown> </AccordionContent>
🧹 Nitpick comments (1)
apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx (1)
41-50: Consider addingdir="auto"to error/helper text for consistency.The error and helper text div doesn't inherit the
labelDirattribute. If error messages or helper text can contain RTL content, they may benefit fromdir="auto"for proper alignment.If needed, apply this diff:
{(error || helperText) && ( <div className={cn( "mt-2 text-xs", error ? "text-red-500" : "text-neutral-500", )} + dir="auto" > {error || helperText} </div> )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/web/ui/partners/groups/design/application-form/application-hero-preview.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx(2 hunks)apps/web/ui/partners/groups/design/application-form/fields/long-text-field.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/fields/multiple-choice-field.tsx(3 hunks)apps/web/ui/partners/groups/design/application-form/fields/select-field.tsx(1 hunks)apps/web/ui/partners/groups/design/application-form/fields/short-text-field.tsx(1 hunks)apps/web/ui/partners/lander/blocks/accordion-block.tsx(1 hunks)apps/web/ui/partners/lander/blocks/block-markdown.tsx(1 hunks)apps/web/ui/partners/lander/blocks/block-title.tsx(1 hunks)apps/web/ui/partners/lander/blocks/files-block.tsx(1 hunks)apps/web/ui/partners/lander/lander-hero.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- apps/web/ui/partners/lander/blocks/files-block.tsx
- apps/web/ui/partners/groups/design/application-form/fields/select-field.tsx
- apps/web/ui/partners/lander/lander-hero.tsx
- apps/web/ui/partners/groups/design/application-form/fields/short-text-field.tsx
- apps/web/ui/partners/groups/design/application-form/fields/long-text-field.tsx
🧰 Additional context used
🧠 Learnings (3)
📓 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-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/ui/partners/groups/design/application-form/fields/form-control.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/ui/partners/groups/design/application-form/fields/form-control.tsx
🧬 Code graph analysis (1)
apps/web/ui/partners/groups/design/application-form/application-hero-preview.tsx (1)
packages/email/src/react-email.d.ts (1)
Heading(16-16)
🔇 Additional comments (8)
apps/web/ui/partners/lander/blocks/block-title.tsx (1)
3-5: LGTM! Consistent and correct RTL implementation.The
dir="auto"attribute enables automatic bidirectional text direction handling. Verification confirms this pattern is applied consistently across the lander components (spans, accordions, headings), validating the approach aligns with the PR's systematic RTL support additions.apps/web/ui/partners/groups/design/application-form/fields/form-control.tsx (2)
2-10: LGTM! Clean type extension for bidirectional text support.The approach of extending
HTMLAttributes<HTMLLabelElement>and addinglabelDiris clean and type-safe. This enables external control of label directionality while allowing additional HTML attributes to be passed through.
20-31: Implementation correctly separates concerns.The
labelDiris appropriately applied to the inner container div (line 31) where the label text renders, whilerestprops are spread to the outer label element (line 30). This separation allows for proper text direction control without conflicting with other label attributes.apps/web/ui/partners/groups/design/application-form/fields/multiple-choice-field.tsx (3)
52-82: Proper RTL support for checkbox options.The
dir="auto"attribute on the label (line 55) enables automatic text direction handling for checkbox options. The text direction will appropriately cascade to the nested span element (lines 79-80).
116-130: Proper RTL support for radio button options.The
dir="auto"attribute on the label (line 119) enables automatic text direction handling for radio options, with appropriate cascading to the nested span (lines 127-129).
138-148: Correct usage of the updated FormControl API.The
labelDir="auto"prop correctly utilizes the new FormControl capability to enable automatic text direction for the field label, aligning with the RTL support objectives of this PR.apps/web/ui/partners/lander/blocks/block-markdown.tsx (1)
12-31: RTL support implementation verified—no issues found.The
dir="auto"addition on the wrapper div is correct and consistent with the RTL support rollout across other block components (BlockTitle, FilesBlock). The prose styles properly cascade to the nested Markdown content, and all consumers (TextBlock, AccordionBlock) integrate correctly without breaking changes.apps/web/ui/partners/groups/design/application-form/application-hero-preview.tsx (1)
33-35: LGTM! RTL support correctly implemented.The
dir="auto"attribute enables automatic text direction detection for the title, allowing the browser to handle both LTR and RTL content appropriately. This aligns with the PR objectives to add RTL content support.
Adds
dir="auto"throughout the lander and application pagesSummary by CodeRabbit