Conversation
… README - Add modern landing page with 10 sections (hero, features, testimonials, FAQ, etc.) - Add 97 Malaysian foods with categories to database - Implement infinite scroll pagination (load 10, more on scroll) - Add category filter on search page - Create comprehensive contributor README with branch strategy - Update color scheme to green/dark theme
📝 WalkthroughWalkthroughThis pull request introduces comprehensive food search and categorization features across the entire stack. Backend adds paginated and category endpoints; database seeding expands to categorized Malaysian foods with indexing; frontend introduces a SearchPage with infinite scroll, a landing page composed of reusable sections, and new UI primitives. Documentation is provided via README. Changes
Sequence DiagramsequenceDiagram
actor User
participant SearchUI as SearchPage
participant State as Component State
participant TRPC as TRPC Client
participant Backend as Food API
participant DB as Database
User->>SearchUI: Load search page
SearchUI->>SearchUI: Initialize categories query
TRPC->>Backend: categoriesQuery()
Backend->>DB: Fetch distinct categories
DB-->>Backend: [categories]
Backend-->>TRPC: [categories]
TRPC-->>SearchUI: Render category filter
alt User searches for food
User->>SearchUI: Type search query
SearchUI->>State: Debounce input (1.5s)
Note over State: After 1.5s delay
State->>TRPC: searchQuery(term)
TRPC->>Backend: food.search(term)
Backend->>DB: Find foods by name
DB-->>Backend: [matching foods]
Backend-->>TRPC: Results
TRPC-->>SearchUI: Render search results
else User selects category
User->>SearchUI: Click category filter
State->>TRPC: allPaginatedQuery(cursor=0, limit, category)
TRPC->>Backend: food.allPaginated()
Backend->>DB: Fetch foods + count
DB-->>Backend: [foods], total
Backend-->>TRPC: Items, nextCursor, total
TRPC-->>SearchUI: Render paginated results
end
User->>SearchUI: Scroll near bottom
SearchUI->>SearchUI: IntersectionObserver triggers
State->>TRPC: fetchNextPage(cursor)
TRPC->>Backend: allPaginated(nextCursor, limit)
Backend->>DB: Fetch next batch
DB-->>Backend: [foods]
Backend-->>TRPC: Results
TRPC-->>SearchUI: Append to results grid
User->>SearchUI: Click food card
SearchUI->>SearchUI: Open detail modal
SearchUI->>User: Show macro breakdown, serving info
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes 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.
Actionable comments posted: 2
🧹 Nitpick comments (12)
README.md (2)
32-44: Add language identifier to the fenced code block.The code block lacks a language identifier, which impacts syntax highlighting and accessibility.
🔎 Proposed fix
-``` +```text Kal-Monorepo/ ├── packages/
221-227: Add language identifier to the fenced code block.The code block lacks a language identifier for proper rendering.
🔎 Proposed fix
-``` +```text feat: add new feature fix: bug fixpackages/kal-frontend/src/components/ui/Container.tsx (1)
7-24: Consider minor optimizations for maintainability.The component works correctly, but two optional refinements could improve it:
- Move the
sizesobject outside the component to avoid recreation on each render- Consider using a className utility like
clsxorcnfor better className composition🔎 Proposed refactor
+const sizes = { + sm: "max-w-2xl", + md: "max-w-4xl", + lg: "max-w-5xl", + xl: "max-w-6xl", +}; + export function Container({ children, className = "", size = "lg", }: ContainerProps) { - const sizes = { - sm: "max-w-2xl", - md: "max-w-4xl", - lg: "max-w-5xl", - xl: "max-w-6xl", - }; return ( <div className={`mx-auto px-6 ${sizes[size]} ${className}`}> {children} </div> ); }packages/kal-frontend/src/components/ui/Button.tsx (1)
12-38: Consider using a className utility for better composition.Similar to the Container component, consider extracting the variants and sizes objects outside the component and using a className utility like
clsxorcnfor more robust className composition, especially when dealing with conditional classes.packages/kal-db/scripts/seed-safe.ts (1)
9-158: Consider extracting shared code to reduce duplication.The helper functions (
getDatabaseUri,getDbName) and the entire food dataset are duplicated betweenseed.tsandseed-safe.ts. This creates a maintenance burden where changes must be synchronized across both files.Consider creating a shared module (e.g.,
seed-common.ts) that exports:
- The helper functions
- The food dataset
- Shared database connection logic
Both seed scripts can then import from this common module.
packages/kal-frontend/src/components/landing/Testimonials.tsx (1)
39-41: Consider adding accessibility attributes to the decorative SVG.The quote icon is decorative and should include
aria-hidden="true"to prevent it from being announced by screen readers.🔎 Suggested improvement
- <svg className="w-8 h-8 text-accent/30 mb-4" fill="currentColor" viewBox="0 0 24 24"> + <svg className="w-8 h-8 text-accent/30 mb-4" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <path d="M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z" /> </svg>packages/kal-frontend/src/components/landing/CTA.tsx (1)
17-19: Consider adding accessibility attributes to the decorative SVG.The arrow icon is decorative and should include
aria-hidden="true"to prevent screen readers from announcing it separately from the button text.🔎 Suggested improvement
- <svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" /> </svg>packages/kal-frontend/src/components/landing/FAQ.tsx (1)
43-58: Consider enhancing accordion accessibility.The accordion buttons should include ARIA attributes to properly convey state to assistive technologies. The chevron SVG should be marked as decorative.
🔎 Suggested improvements
<button onClick={() => setOpenIndex(openIndex === index ? null : index)} + aria-expanded={openIndex === index} + aria-controls={`faq-answer-${index}`} className="w-full px-6 py-5 flex items-center justify-between text-left hover:bg-dark-elevated/50 transition-colors" > <span className="font-medium text-content-primary">{faq.question}</span> <svg className={`w-5 h-5 text-content-muted transition-transform duration-200 ${ openIndex === index ? "rotate-180" : "" }`} fill="none" stroke="currentColor" viewBox="0 0 24 24" + aria-hidden="true" > <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /> </svg> </button> {openIndex === index && ( - <div className="px-6 pb-5"> + <div id={`faq-answer-${index}`} className="px-6 pb-5"> <p className="text-content-secondary leading-relaxed">{faq.answer}</p> </div> )}packages/kal-frontend/src/components/landing/Features.tsx (1)
4-59: Consider adding accessibility attributes to decorative SVGs.All the feature icons are decorative and should include
aria-hidden="true"to prevent them from being announced separately by screen readers, since the feature titles and descriptions already convey the meaning.🔎 Example for one icon
icon: ( - <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13 10V3L4 14h7v7l9-11h-7z" /> </svg> ),Apply this pattern to all six feature icons in the array.
packages/kal-frontend/src/components/landing/Hero.tsx (1)
39-41: Consider adding accessibility attributes to the decorative SVG.The arrow icon is decorative and should include
aria-hidden="true"to prevent screen readers from announcing it separately from the button text.🔎 Suggested improvement
- <svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" /> </svg>packages/kal-frontend/src/components/landing/Navbar.tsx (1)
48-59: Consider enhancing mobile menu accessibility.The mobile menu toggle button should include ARIA attributes to properly convey its state and purpose to assistive technologies. The SVG icons should be marked as decorative.
🔎 Suggested improvements
<button onClick={() => setMobileMenuOpen(!mobileMenuOpen)} + aria-expanded={mobileMenuOpen} + aria-label="Toggle navigation menu" className="md:hidden p-2 text-content-secondary hover:text-content-primary" > - <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> {mobileMenuOpen ? ( <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /> ) : ( <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" /> )} </svg> </button>packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
19-23: Applymx-autoconditionally based oncenteredprop.The subtitle paragraph always applies
mx-auto(line 20), which horizontally centers the element block even whencentered={false}. This creates a layout inconsistency where left-aligned text is rendered within a centered container, potentially causing unexpected spacing or alignment issues.🔎 Proposed fix
{subtitle && ( - <p className="text-content-secondary text-lg max-w-2xl mx-auto"> + <p className={`text-content-secondary text-lg max-w-2xl ${centered ? 'mx-auto' : ''}`}> {subtitle} </p> )}
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
README.mdpackages/kal-backend/src/routers/food.tspackages/kal-db/scripts/seed-safe.tspackages/kal-db/scripts/seed.tspackages/kal-frontend/src/app/globals.csspackages/kal-frontend/src/app/page.tsxpackages/kal-frontend/src/app/search/page.tsxpackages/kal-frontend/src/components/landing/CTA.tsxpackages/kal-frontend/src/components/landing/FAQ.tsxpackages/kal-frontend/src/components/landing/Features.tsxpackages/kal-frontend/src/components/landing/Footer.tsxpackages/kal-frontend/src/components/landing/Hero.tsxpackages/kal-frontend/src/components/landing/HowItWorks.tsxpackages/kal-frontend/src/components/landing/Navbar.tsxpackages/kal-frontend/src/components/landing/ProblemSolution.tsxpackages/kal-frontend/src/components/landing/SampleFoods.tsxpackages/kal-frontend/src/components/landing/Testimonials.tsxpackages/kal-frontend/src/components/ui/Button.tsxpackages/kal-frontend/src/components/ui/Container.tsxpackages/kal-frontend/src/components/ui/SectionHeading.tsxpackages/kal-frontend/tailwind.config.ts
🧰 Additional context used
🧬 Code graph analysis (12)
packages/kal-frontend/src/components/landing/Testimonials.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
SectionHeading(8-26)
packages/kal-frontend/src/components/landing/Navbar.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/Button.tsx (1)
Button(12-53)
packages/kal-frontend/src/components/landing/ProblemSolution.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
SectionHeading(8-26)
packages/kal-frontend/src/components/landing/HowItWorks.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
SectionHeading(8-26)
packages/kal-frontend/src/components/landing/FAQ.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
SectionHeading(8-26)
packages/kal-frontend/src/app/page.tsx (10)
packages/kal-frontend/src/components/landing/Navbar.tsx (1)
Navbar(14-85)packages/kal-frontend/src/components/landing/Hero.tsx (1)
Hero(10-65)packages/kal-frontend/src/components/landing/ProblemSolution.tsx (1)
ProblemSolution(18-65)packages/kal-frontend/src/components/landing/HowItWorks.tsx (1)
HowItWorks(37-77)packages/kal-frontend/src/components/landing/Features.tsx (1)
Features(61-94)packages/kal-frontend/src/components/landing/SampleFoods.tsx (1)
SampleFoods(14-64)packages/kal-frontend/src/components/landing/Testimonials.tsx (1)
Testimonials(22-63)packages/kal-frontend/src/components/landing/FAQ.tsx (1)
FAQ(26-70)packages/kal-frontend/src/components/landing/CTA.tsx (1)
FinalCTA(4-25)packages/kal-frontend/src/components/landing/Footer.tsx (1)
Footer(4-28)
packages/kal-frontend/src/components/landing/SampleFoods.tsx (3)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/SectionHeading.tsx (1)
SectionHeading(8-26)packages/kal-frontend/src/components/ui/Button.tsx (1)
Button(12-53)
packages/kal-frontend/src/app/search/page.tsx (1)
packages/kal-frontend/src/lib/trpc.ts (1)
trpc(5-5)
packages/kal-frontend/src/components/landing/Hero.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/Button.tsx (1)
Button(12-53)
packages/kal-frontend/src/components/landing/CTA.tsx (2)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)packages/kal-frontend/src/components/ui/Button.tsx (1)
Button(12-53)
packages/kal-frontend/src/components/landing/Footer.tsx (1)
packages/kal-frontend/src/components/ui/Container.tsx (1)
Container(7-24)
packages/kal-backend/src/routers/food.ts (1)
packages/kal-backend/src/lib/trpc.ts (1)
publicProcedure(7-7)
🪛 LanguageTool
README.md
[grammar] ~3-~3: Use a hyphen to join words.
Context: ...lorie Tracker 🥗 A simple, fast calorie tracking app focused on Malaysian cuisin...
(QB_NEW_EN_HYPHEN)
🪛 markdownlint-cli2 (0.18.1)
README.md
32-32: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
221-221: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
243-243: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
🔇 Additional comments (16)
packages/kal-frontend/tailwind.config.ts (1)
11-48: LGTM! Well-structured design token system.The semantic color palette (dark, accent, content) provides clear naming and good organization. The animations are standard and appropriate for modern UI transitions.
packages/kal-frontend/src/app/globals.css (1)
5-44: LGTM! Well-structured CSS with good accessibility practices.The CSS variable system aligns well with the Tailwind configuration. Good inclusion of accessibility features like
:focus-visibleand thoughtful touches like selection styling and font smoothing.packages/kal-db/scripts/seed.ts (3)
20-30: Verify URL parsing handles edge cases correctly.The database name extraction from
DATABASE_URLmay not handle all edge cases properly. If the pathname is just/or empty,pathname.slice(1).split("?")[0]would return an empty string rather than falling back to "kal".🔎 Suggested improvement
const getDbName = () => { if (process.env.DATABASE_URL) { try { const url = new URL(process.env.DATABASE_URL); - return url.pathname.slice(1).split("?")[0]; + const dbName = url.pathname.slice(1).split("?")[0]; + return dbName || "kal"; } catch { return "kal"; } } return MONGODB_DATABASE || "kal"; };
33-152: LGTM! Comprehensive and well-structured food database.The Malaysian food dataset is extensive (97 items) with consistent schema across all entries. Category organization is logical and complete.
176-179: Good addition of category index for query performance.Creating an index on the
categoryfield will optimize the category filter queries mentioned in the PR objectives.packages/kal-db/scripts/seed-safe.ts (1)
187-189: Good consistency with seed.ts for category indexing.The category index creation is consistent with the main seed script, ensuring query performance for category filtering in both seeding scenarios.
packages/kal-frontend/src/components/landing/Footer.tsx (1)
4-28: LGTM! Clean and well-structured Footer component.The component uses semantic HTML, responsive layout, and dynamic copyright year generation. Good integration with the shared Container component.
packages/kal-frontend/src/components/landing/ProblemSolution.tsx (1)
18-65: LGTM!The problem-solution comparison is well-structured with clear visual distinction between the two sections. The use of contrasting colors and icons effectively communicates the concept.
packages/kal-frontend/src/components/landing/SampleFoods.tsx (1)
38-51: LGTM! Good use of text labels alongside color indicators.The macro breakdown uses colored dots alongside text labels (P:, C:, F:), which ensures the information is accessible even if colors cannot be perceived. This follows accessibility best practices.
packages/kal-frontend/src/app/page.tsx (1)
12-33: LGTM! Clean modular landing page composition.The landing page effectively composes all section components with proper structure and decorative background effects. The modular approach makes the codebase maintainable and each section reusable.
packages/kal-backend/src/routers/food.ts (2)
43-82: LGTM! Pagination logic is correctly implemented.The cursor-based pagination implementation is sound:
- Parallel fetching of items and count optimizes performance
- nextCursor calculation correctly handles edge cases
- Optional category filtering integrates cleanly
84-90: Category field indexing is already in place.Verification confirms that an index on the
categoryfield has been created in the foods collection. The seed scripts (packages/kal-db/scripts/seed.tsandseed-safe.ts) explicitly create this index with the comment "Create index on category for filtering", ensuring thedistinct("category")query will perform efficiently as the dataset grows.packages/kal-frontend/src/app/search/page.tsx (4)
18-42: LGTM! Search state management is well-implemented.The debounced search with Enter-to-search functionality is correctly implemented:
- Proper cleanup of debounce timer
- useCallback optimization for the key handler
- Reasonable 1.5s delay balances UX and server load
55-68: LGTM! Infinite query setup follows React Query best practices.The infinite query configuration is correct:
- Properly disabled during search mode
- nextCursor correctly extracted from backend response
- initialCursor: 0 aligns with backend pagination
- Query automatically resets when category filter changes (React Query handles this via input changes)
70-85: LGTM! IntersectionObserver implementation is correct.The infinite scroll logic properly:
- Disconnects observer on cleanup
- Checks all necessary conditions before fetching (intersection, hasNextPage, not already fetching)
- Includes searchQuery in dependencies to recreate observer when switching modes
158-187: Well-designed category filter with proper mode isolation.The category filter correctly:
- Only displays in browse mode (not during search)
- Uses proper active state styling
- Integrates with the infinite query, which automatically resets pagination when category changes
| <div key={index} className="text-center"> | ||
| {/* Step number */} | ||
| <div className="relative inline-flex items-center justify-center mb-6"> | ||
| <div className="w-16 h-16 rounded-2xl bg-dark-surface border border-dark-border flex items-center justify-center text-accent"> | ||
| {step.icon} | ||
| </div> | ||
| <span className="absolute -top-2 -right-2 w-6 h-6 rounded-full bg-accent text-dark text-sm font-bold flex items-center justify-center"> | ||
| {step.number} | ||
| </span> | ||
| </div> | ||
|
|
||
| {/* Content */} | ||
| <h3 className="text-xl font-semibold text-content-primary mb-2"> | ||
| {step.title} | ||
| </h3> | ||
| <p className="text-content-secondary"> | ||
| {step.description} | ||
| </p> | ||
|
|
||
| {/* Connector line (not on last) */} | ||
| {index < steps.length - 1 && ( | ||
| <div className="hidden md:block absolute top-8 left-full w-full h-px bg-dark-border -translate-y-1/2" /> | ||
| )} | ||
| </div> |
There was a problem hiding this comment.
Fix positioning context for connector lines.
The connector line at lines 68-70 uses absolute positioning with left-full, but the parent div at line 48 lacks position: relative. This causes the line to position relative to the nearest positioned ancestor (likely the section or Container), not the step card itself, breaking the visual connection between steps.
🔎 Proposed fix
- {steps.map((step, index) => (
- <div key={index} className="text-center">
+ {steps.map((step, index) => (
+ <div key={index} className="text-center relative">
{/* Step number */}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div key={index} className="text-center"> | |
| {/* Step number */} | |
| <div className="relative inline-flex items-center justify-center mb-6"> | |
| <div className="w-16 h-16 rounded-2xl bg-dark-surface border border-dark-border flex items-center justify-center text-accent"> | |
| {step.icon} | |
| </div> | |
| <span className="absolute -top-2 -right-2 w-6 h-6 rounded-full bg-accent text-dark text-sm font-bold flex items-center justify-center"> | |
| {step.number} | |
| </span> | |
| </div> | |
| {/* Content */} | |
| <h3 className="text-xl font-semibold text-content-primary mb-2"> | |
| {step.title} | |
| </h3> | |
| <p className="text-content-secondary"> | |
| {step.description} | |
| </p> | |
| {/* Connector line (not on last) */} | |
| {index < steps.length - 1 && ( | |
| <div className="hidden md:block absolute top-8 left-full w-full h-px bg-dark-border -translate-y-1/2" /> | |
| )} | |
| </div> | |
| {steps.map((step, index) => ( | |
| <div key={index} className="text-center relative"> | |
| {/* Step number */} | |
| <div className="relative inline-flex items-center justify-center mb-6"> | |
| <div className="w-16 h-16 rounded-2xl bg-dark-surface border border-dark-border flex items-center justify-center text-accent"> | |
| {step.icon} | |
| </div> | |
| <span className="absolute -top-2 -right-2 w-6 h-6 rounded-full bg-accent text-dark text-sm font-bold flex items-center justify-center"> | |
| {step.number} | |
| </span> | |
| </div> | |
| {/* Content */} | |
| <h3 className="text-xl font-semibold text-content-primary mb-2"> | |
| {step.title} | |
| </h3> | |
| <p className="text-content-secondary"> | |
| {step.description} | |
| </p> | |
| {/* Connector line (not on last) */} | |
| {index < steps.length - 1 && ( | |
| <div className="hidden md:block absolute top-8 left-full w-full h-px bg-dark-border -translate-y-1/2" /> | |
| )} | |
| </div> | |
| ))} |
🤖 Prompt for AI Agents
In packages/kal-frontend/src/components/landing/HowItWorks.tsx around lines 48
to 71, the connector line uses absolute positioning but its parent container
isn't positioned, so the line is positioned relative to an ancestor instead of
the step card; fix this by adding a positioning context (e.g., apply relative
positioning) to the parent div at line 48 so the absolute connector is anchored
to the step element, and verify layout on mobile and md breakpoints so the
connector only shows where intended.
| return ( | ||
| <button onClick={onClick} className={styles}> | ||
| {children} | ||
| </button> | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add explicit type="button" to prevent unintended form submissions.
The button element should include type="button" to prevent it from acting as a submit button when used inside forms.
🔎 Proposed fix
return (
- <button onClick={onClick} className={styles}>
+ <button type="button" onClick={onClick} className={styles}>
{children}
</button>
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return ( | |
| <button onClick={onClick} className={styles}> | |
| {children} | |
| </button> | |
| ); | |
| return ( | |
| <button type="button" onClick={onClick} className={styles}> | |
| {children} | |
| </button> | |
| ); |
🤖 Prompt for AI Agents
In packages/kal-frontend/src/components/ui/Button.tsx around lines 48 to 52 the
rendered <button> lacks an explicit type, which causes it to act as a submit
button when placed inside forms; update the JSX to include type="button" on the
button element so it will not trigger form submission (keep existing onClick and
className props unchanged).
… README
Summary by CodeRabbit
New Features
Documentation
Style
✏️ Tip: You can customize this high-level summary in your review settings.