-
Notifications
You must be signed in to change notification settings - Fork 10
Mable Frontend Developer - Technical Task #8
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
base: main
Are you sure you want to change the base?
Conversation
- Refactored index.ts to follow Single Responsibility Principle - Removed redundant comments - Updated associated test files
…unit test for valueconverter function
|
Warning Rate limit exceeded@gitjeet has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 27 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis update introduces a modularized input system with specialized components for text, radio, switch, and dropdown inputs, each with integrated form validation and state handling. It adds a floating chatbot UI, new utility modules, and comprehensive test coverage. Build and test scripts are modernized, and a new automated barrel file generation process replaces manual exports. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Form
participant InputComponent
participant ValidationUtils
User->>InputComponent: Interacts (type/select/toggle)
InputComponent->>Form: Updates value via react-hook-form
InputComponent->>ValidationUtils: Applies validation rules
ValidationUtils-->>InputComponent: Returns validation result
InputComponent-->>Form: Triggers validation/updates error state
Form-->>User: Displays updated UI/errors
sequenceDiagram
participant User
participant Chatbot
participant useChatbotHook
participant onSendMessage
User->>Chatbot: Clicks toggle button
Chatbot->>useChatbotHook: Toggle open state
User->>Chatbot: Sends message
Chatbot->>useChatbotHook: send()
useChatbotHook->>onSendMessage: (async) Get bot reply
onSendMessage-->>useChatbotHook: Returns response
useChatbotHook-->>Chatbot: Updates messages, loading state
Chatbot-->>User: Renders new message
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 17
🔭 Outside diff range comments (1)
src/components/index.tsx (1)
1-3: Ensure the barrel generator actually runs and populates exports
Thegenerate:barrelstep is currently failing (tsx: not found), sosrc/components/index.tsxremains empty. Please:• Add or fix the TSX runtime in your devDependencies (e.g.
"tsx": "^3.x"in package.json).
• Verify yourgenerate:barrelscript in package.json uses the correct command:"scripts": { - "generate:barrel": "tsx scripts/generate-barrel.ts" + "generate:barrel": "tsx scripts/generate-barrel.ts" }• Re-run
pnpm installandpnpm generate:barrel, then confirmsrc/components/index.tsxcontains actual exports.Affected files:
- package.json (devDependencies & scripts)
- scripts/generate-barrel.ts
🧹 Nitpick comments (20)
jest.config.cjs (1)
5-5: Add trailing newline for consistency.Consider adding a trailing newline at the end of the file to follow standard file formatting conventions.
}; +src/components/Atoms/Controls/Input/utils/validation.test.ts (3)
17-17: Replaceanytype with proper typing.The type assertion uses
anywhich ESLint flags as an error. Use proper typing for better type safety.- expect((rules.min as any).value).toBe(0); + expect((rules.min as { value: number; message: string }).value).toBe(0);
22-22: Replaceanytypes with proper function signature.The type assertion uses
anywhich ESLint flags as an error. Use the actual function signature for better type safety.- const validateFn = rules.validate as (v: string, f: any) => any; + const validateFn = rules.validate as (value: string, formValues: any) => boolean | string;
3-33: Consider adding test coverage for email and tel validation.The test suite covers most input types but is missing tests for email and tel validation patterns that are implemented in the
getValidationRulesfunction.Consider adding these test cases:
+ it("email ⇒ pattern validation", () => { + const rules = getValidationRules("email", "email"); + const pattern = rules.pattern as { value: RegExp; message: string }; + expect(pattern.value.test("valid@example.com")).toBe(true); + expect(pattern.value.test("invalid-email")).toBe(false); + }); + + it("tel ⇒ phone number pattern", () => { + const rules = getValidationRules("tel", "phone"); + const pattern = rules.pattern as { value: RegExp; message: string }; + expect(pattern.value.test("1234567890")).toBe(true); + expect(pattern.value.test("123")).toBe(false); + });src/components/Atoms/Controls/Button/buttonVariants.ts (1)
15-16: Review outline variant text color handling for accessibility.The outline variant uses
text-whitefrom the base class, but when disabled it setsdisabled:text-primary-300. Consider if the text color should be different for the normal state of the outline variant to ensure proper contrast with the transparent background.Consider adjusting the outline variant:
outline: - "bg-transparent border border-primary-400 hover:bg-primary-600 disabled:border-primary-300 disabled:text-primary-300 disabled:cursor-not-allowed", + "bg-transparent border border-primary-400 text-primary-400 hover:bg-primary-600 hover:text-white disabled:border-primary-300 disabled:text-primary-300 disabled:cursor-not-allowed",src/components/Atoms/Controls/Input/InputBase.tsx (2)
33-36: Add aria-label to tooltip icon for better accessibility.The info icon should have an accessible label to help screen readers understand its purpose.
<AiOutlineInfoCircle className="text-white flex-shrink-0" size={16} + aria-label="Additional information" />
21-21: Consider using aria-disabled instead of opacity for disabled state.While visual opacity indicates disabled state, consider also adding
aria-disabledattribute for better accessibility support.<div - className={`flex flex-col gap-2 w-full py-1 h-fit ${disabled ? "opacity-40" : "opacity-100"}`} + className={`flex flex-col gap-2 w-full py-1 h-fit ${disabled ? "opacity-40" : "opacity-100"}`} + aria-disabled={disabled} >src/components/Atoms/Controls/Input/DropDownInput.tsx (1)
33-33: Consider clarifying the fallback logic.The current fallback chain
fieldValue → defaultValue → placeholdermight be confusing. Consider making the logic more explicit or adding a comment to clarify the intended behavior.- {fieldValue ? fieldValue : (props.defaultValue ?? props.placeholder)} + {fieldValue || props.defaultValue || props.placeholder}Or add a comment explaining the fallback priority.
scripts/generate-barrel.ts (1)
35-38: Consider potential naming conflicts for default exports.The script generates aliases for default exports using
path.basename(relativePath). If multiple directories have the same name, this could cause naming conflicts in the barrel file.Consider adding logic to detect and handle potential naming conflicts, perhaps by using the full relative path or appending a suffix.
src/components/Atoms/Controls/Input/utils/validation.ts (2)
11-11: Fix ESLint warning: use const instead of let.The
rulesvariable is never reassigned, so it should be declared asconst.- let rules: RegisterOptions = { + const rules: RegisterOptions = {
50-51: Consider merging custom validation with defaults.The current implementation completely replaces default rules with
customValidation. Consider merging them to preserve type-specific validations while allowing customization.- if (customValidation) return customValidation; - return rules; + return customValidation ? { ...rules, ...customValidation } : rules;This would allow custom validation to override specific rules while preserving others.
src/components/Atoms/Controls/Input/RadioInput.tsx (1)
30-31: Replace @ts-ignore with @ts-expect-error for better type safety.As suggested by ESLint, use
@ts-expect-errorinstead of@ts-ignoreto ensure the comment is only used when there's an actual type error.- // @ts-ignore + // @ts-expect-error ref={ref}src/components/Atoms/Controls/Input/TextInput.tsx (1)
42-46: Consider debouncing validation triggers to improve performance.Triggering validation on every change event could impact performance, especially for complex validation rules. Consider debouncing or triggering validation only on blur for better UX.
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { formOnChange(event); onChange?.(event); - trigger(name); + // Consider debouncing or trigger on blur instead };src/components/Atoms/Controls/FloatingChatbot/hooks/useChatbot.ts (2)
27-28: Make focus delay configurable instead of hardcoded.The 300ms delay for input focus is hardcoded and might not be suitable for all use cases or devices.
-useEffect(() => { - if (isOpen) setTimeout(() => inputRef.current?.focus(), 300); -}, [isOpen]); +useEffect(() => { + if (isOpen) { + const focusTimeout = setTimeout(() => inputRef.current?.focus(), 300); + return () => clearTimeout(focusTimeout); + } +}, [isOpen]);
51-60: Make response delay configurable and add cleanup.The hardcoded 500ms delay for bot responses should be configurable, and the timeout should be cleaned up on unmount.
+const RESPONSE_DELAY = 500; setTimeout(() => { const bot: ChatMessage = { - id: `bot-${Date.now()}`, + id: generateId('bot'), content: res, isUser: false, timestamp: new Date(), }; setMessages((p) => [...p, bot]); setIsLoading(false); -}, 500); +}, RESPONSE_DELAY);src/components/Atoms/Controls/FloatingChatbot/index.tsx (2)
170-170: Make chatbot dimensions configurable instead of hardcoded.The hardcoded width (350px) and height values (450px, 320px) should be configurable props to allow for different use cases and responsive design.
export interface ChatbotProps { title?: string; placeholderText?: string; position?: "bottom-right" | "bottom-left" | "top-right" | "top-left"; initialOpen?: boolean; onSendMessage?: (message: string) => Promise<string> | string; avatar?: React.ReactNode; className?: string; + width?: number; + height?: number; } export const Chatbot: React.FC<ChatbotProps> = ({ title = "Chat Support", placeholderText = "Type your message...", position = "bottom-right", initialOpen = false, onSendMessage, avatar, className, + width = 350, + height = 450, }) => {Then use these props in the component:
-style={{ width: 350, height: 450 }} +style={{ width, height }} -<div className={list()} style={{ height: 320 }}> +<div className={list()} style={{ height: height - 130 }}>Also applies to: 189-189
153-161: Consider using tailwind-variants for position mapping.The position mapping using object lookup and string interpolation could be more maintainable using the tailwind-variants approach already established in the codebase.
+const floatingContainer = tv({ + base: "fixed z-50", + variants: { + position: { + "bottom-right": "bottom-6 right-6", + "bottom-left": "bottom-6 left-6", + "top-right": "top-6 right-6", + "top-left": "top-6 left-6", + }, + }, + defaultVariants: { position: "bottom-right" }, +}); -const pos = { - "bottom-right": "bottom-6 right-6", - "bottom-left": "bottom-6 left-6", - "top-right": "top-6 right-6", - "top-left": "top-6 left-6", -}[position]; return ( - <div className={`fixed ${pos} z-50 ${className || ""}`}> + <div className={floatingContainer({ position, className })}>src/components/Atoms/Controls/Button/useSpinnerConfig.ts (1)
5-16: Replace hardcoded colors with design tokens.The hardcoded color values should be replaced with design system tokens for consistency and maintainability.
+// Consider importing from a design tokens file +const COLORS = { + primary: '#4FB7DD', + white: '#ffffff', + transparent: 'transparent', +} as const; export const getSpinnerColors = (variant: SpinnerVariant) => { if (variant === "outline") { return { - trackColor: "#4FB7DD", - spinnerColor: "transparent", + trackColor: COLORS.primary, + spinnerColor: COLORS.transparent, }; } return { - trackColor: "#ffffff", - spinnerColor: "transparent", + trackColor: COLORS.white, + spinnerColor: COLORS.transparent, }; };src/components/Atoms/Controls/BidirectionalSlider/index.tsx (1)
9-9: Prefer descriptive interface names over generic ones.The interface name
Propsis too generic. Consider keeping the original nameBidirectionalSliderPropsfor better clarity and searchability in the codebase.-interface Props { +interface BidirectionalSliderProps {src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.ts (1)
52-54: Document the use of 49.8 instead of 50.The use of
49.8instead of50appears intentional to maintain visual continuity at the origin boundary, but this should be documented for clarity.return val <= origin ? ((val - min) / (origin - min)) * 50 + // Use 49.8 to ensure visual continuity at the origin boundary : 49.8 + ((val - origin) / (max - origin)) * 50;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
package-lock.jsonis excluded by!**/package-lock.jsonpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (29)
jest.config.cjs(1 hunks)package.json(5 hunks)scripts/generate-barrel.ts(1 hunks)src/components/Atoms/Controls/BidirectionalSlider/index.tsx(1 hunks)src/components/Atoms/Controls/BidirectionalSlider/utils/gradient.ts(1 hunks)src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.test.ts(1 hunks)src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.ts(1 hunks)src/components/Atoms/Controls/Button/button.test.ts(1 hunks)src/components/Atoms/Controls/Button/buttonVariants.ts(1 hunks)src/components/Atoms/Controls/Button/index.tsx(3 hunks)src/components/Atoms/Controls/Button/useSpinnerConfig.ts(1 hunks)src/components/Atoms/Controls/FloatingChatbot/FloatingChatbot.stories.tsx(1 hunks)src/components/Atoms/Controls/FloatingChatbot/MessageBubble.tsx(1 hunks)src/components/Atoms/Controls/FloatingChatbot/hooks/useChatbot.ts(1 hunks)src/components/Atoms/Controls/FloatingChatbot/index.tsx(1 hunks)src/components/Atoms/Controls/Input/DropDownInput.tsx(1 hunks)src/components/Atoms/Controls/Input/Input.stories.tsx(3 hunks)src/components/Atoms/Controls/Input/InputBase.tsx(1 hunks)src/components/Atoms/Controls/Input/RadioInput.tsx(1 hunks)src/components/Atoms/Controls/Input/SwitchInput.tsx(1 hunks)src/components/Atoms/Controls/Input/TextInput.tsx(1 hunks)src/components/Atoms/Controls/Input/index.tsx(1 hunks)src/components/Atoms/Controls/Input/types/formutils.ts(1 hunks)src/components/Atoms/Controls/Input/types/types.ts(1 hunks)src/components/Atoms/Controls/Input/utils/validation.test.ts(1 hunks)src/components/Atoms/Controls/Input/utils/validation.ts(1 hunks)src/components/Atoms/Controls/Textarea/index.tsx(1 hunks)src/components/index.tsx(1 hunks)tsconfig.node.json(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (14)
src/components/Atoms/Controls/FloatingChatbot/MessageBubble.tsx (1)
src/components/Atoms/Controls/FloatingChatbot/hooks/useChatbot.ts (1)
ChatMessage(3-8)
src/components/Atoms/Controls/Button/button.test.ts (1)
src/components/Atoms/Controls/Button/useSpinnerConfig.ts (2)
getSpinnerColors(5-16)getSpinnerSize(18-20)
src/components/Atoms/Controls/Input/DropDownInput.tsx (2)
src/components/Atoms/Controls/Input/types/types.ts (2)
CustomInputProps(12-35)CustomChangeEvent(4-10)src/types.ts (1)
MenuItem(32-36)
src/components/Atoms/Controls/Input/utils/validation.ts (1)
src/components/Atoms/Controls/Input/types/types.ts (1)
CustomInputProps(12-35)
src/components/Atoms/Controls/Input/RadioInput.tsx (2)
src/components/Atoms/Controls/Input/types/types.ts (2)
CustomInputProps(12-35)CustomChangeEvent(4-10)src/components/Atoms/Controls/Input/Input.stories.tsx (1)
Radio(85-97)
src/components/Atoms/Controls/Input/utils/validation.test.ts (1)
src/components/Atoms/Controls/Input/utils/validation.ts (1)
getValidationRules(4-52)
src/components/Atoms/Controls/Input/InputBase.tsx (1)
src/components/Atoms/Misc/Tooltip/index.tsx (1)
Tooltip(38-98)
src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.test.ts (1)
src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.ts (1)
getBidirectionalValue(3-15)
src/components/Atoms/Controls/Input/TextInput.tsx (2)
src/components/Atoms/Controls/Input/types/types.ts (1)
CustomInputProps(12-35)src/components/Atoms/Controls/Input/utils/validation.ts (1)
getValidationRules(4-52)
src/components/Atoms/Controls/FloatingChatbot/index.tsx (2)
src/components/Atoms/Controls/FloatingChatbot/hooks/useChatbot.ts (2)
ChatMessage(3-8)useChatbot(10-84)src/components/Atoms/Controls/FloatingChatbot/MessageBubble.tsx (1)
MessageBubble(14-18)
src/components/Atoms/Controls/Button/index.tsx (1)
src/components/Atoms/Controls/Button/useSpinnerConfig.ts (2)
getSpinnerColors(5-16)getSpinnerSize(18-20)
src/components/Atoms/Controls/Input/types/types.ts (1)
src/types.ts (1)
MenuItem(32-36)
src/components/Atoms/Controls/Input/index.tsx (6)
src/components/Atoms/Controls/Input/types/types.ts (1)
CustomInputProps(12-35)src/components/Atoms/Controls/Input/RadioInput.tsx (1)
RadioInput(6-35)src/components/Atoms/Controls/Input/SwitchInput.tsx (1)
SwitchInput(6-65)src/components/Atoms/Controls/Input/DropDownInput.tsx (1)
DropdownInput(7-37)src/components/Atoms/Controls/Input/TextInput.tsx (1)
TextInput(17-85)src/components/Atoms/Controls/Input/InputBase.tsx (1)
InputBase(13-43)
src/components/Atoms/Controls/Input/types/formutils.ts (1)
src/components/Atoms/Controls/Input/types/types.ts (1)
CustomChangeEvent(4-10)
🪛 ESLint
jest.config.cjs
[error] 1-1: 'module' is not defined.
(no-undef)
src/components/Atoms/Controls/Input/Input.stories.tsx
[error] 42-42: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 52-52: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 62-62: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
src/components/Atoms/Controls/Input/utils/validation.ts
[error] 11-11: 'rules' is never reassigned. Use 'const' instead.
(prefer-const)
src/components/Atoms/Controls/Input/RadioInput.tsx
[error] 30-30: Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
(@typescript-eslint/ban-ts-comment)
src/components/Atoms/Controls/Input/utils/validation.test.ts
[error] 17-17: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 22-22: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 22-22: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
src/components/Atoms/Controls/FloatingChatbot/FloatingChatbot.stories.tsx
[error] 78-78: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
src/components/Atoms/Controls/Input/types/types.ts
[error] 7-7: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
src/components/Atoms/Controls/Input/index.tsx
[error] 9-9: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
🔇 Additional comments (30)
src/components/Atoms/Controls/Input/types/types.ts (1)
12-35: Well-structured interface design with comprehensive input type coverage.The
CustomInputPropsinterface effectively extends React's input attributes while providing custom functionality. The type union covers all necessary input variants and the integration withreact-hook-formis appropriate.tsconfig.node.json (1)
4-4: Proper Jest types integration for TypeScript testing support.Adding Jest types to the TypeScript configuration correctly enables type definitions for the new Jest testing setup.
src/components/Atoms/Controls/Textarea/index.tsx (1)
2-3: Good practice: Import organization follows standard conventions.Moving React and utility imports to the top of the file improves code organization and follows standard TypeScript/React conventions.
jest.config.cjs (1)
1-4: Standard Jest configuration with TypeScript support.The configuration correctly sets up Jest with TypeScript support using the
ts-jestpreset andnodeenvironment. The CommonJS syntax is appropriate for Jest configuration files.src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.test.ts (1)
3-29: Excellent test coverage with proper floating-point handling.The test suite comprehensively covers boundary conditions and linear scaling behavior. The use of
toBeCloseTofor the origin test shows good understanding of JavaScript's floating-point quirks (signed zero issue).src/components/Atoms/Controls/Button/buttonVariants.ts (1)
3-23: Well-structured button variant system.The implementation provides a clean, type-safe way to manage button variants with consistent styling patterns. The use of
tailwind-variantsensures good TypeScript integration and maintainability.src/components/Atoms/Controls/Input/InputBase.tsx (1)
13-43: Well-designed base component for consistent input styling.The component provides a clean abstraction for common input UI elements with good conditional rendering and proper TypeScript typing. The integration with the Tooltip component is well-implemented.
src/components/Atoms/Controls/FloatingChatbot/MessageBubble.tsx (1)
1-18: LGTM! Clean and focused component implementation.The
MessageBubblecomponent is well-implemented with:
- Clear separation of concerns using
tailwind-variants- Appropriate styling variants for user vs bot messages
- Simple, readable component logic
- Proper TypeScript integration with the
ChatMessageinterfacesrc/components/Atoms/Controls/Button/button.test.ts (2)
3-25: Comprehensive test coverage for spinner utilities.The tests effectively cover:
- All button variants for color selection
- Fallback behavior for spinner sizes
- Edge cases with undefined parameters
The test structure and assertions align well with the implementation in
useSpinnerConfig.ts.
27-40: Good coverage of size fallback logic.The size tests appropriately validate the fallback mechanism where undefined
spinnerSizeresults in size selection based on button size.src/components/Atoms/Controls/Input/DropDownInput.tsx (2)
7-14: Good integration with react-hook-form.The component properly uses
useFormContextanduseWatchto integrate with the form state. The ref forwarding is correctly implemented.
16-23: Well-structured event handling.The
handleSelectfunction correctly:
- Updates form state with
setValue- Creates a custom event matching the
CustomChangeEventinterface- Triggers validation with
triggerscripts/generate-barrel.ts (2)
1-15: Good use of ts-morph for AST analysis.The script setup is well-structured:
- Proper ES module compatibility with
__filenameand__dirname- Correct TypeScript configuration loading
- Appropriate use of ts-morph for parsing
21-46: Solid export detection and generation logic.The script effectively:
- Normalizes paths for cross-platform compatibility
- Separates default and named exports
- Generates appropriate re-export statements
- Handles cases with no exports gracefully
src/components/Atoms/Controls/Input/utils/validation.ts (1)
16-48: Comprehensive validation rules for different input types.The validation logic is well-implemented:
- Email regex follows standard pattern
- Phone validation requires exactly 10 digits
- Password validation enforces strong complexity requirements
- Number inputs have appropriate constraints
src/components/Atoms/Controls/Input/SwitchInput.tsx (1)
1-68: Well-implemented form-integrated switch component.The component follows React and react-hook-form best practices with proper ref forwarding, form state management, and validation integration. The implementation is clean and modular.
src/components/Atoms/Controls/Input/RadioInput.tsx (1)
1-38: Well-structured radio input component with proper form integration.The component correctly integrates with react-hook-form, handles option mapping with disabled states, and follows React patterns with forwardRef.
src/components/Atoms/Controls/BidirectionalSlider/utils/gradient.ts (1)
1-35: Mathematically sound gradient generation utility.The function correctly maps value ranges to percentage positions and generates appropriate CSS gradients for bidirectional visualization. The logic properly handles both sides of the origin point with accurate percentage calculations.
src/components/Atoms/Controls/Button/index.tsx (2)
2-4: Excellent modularization of styling and spinner logic.The extraction of
buttonVariantsand spinner utilities to separate modules improves maintainability and follows the Single Responsibility Principle.
23-24: Efficient computation of spinner configuration.Computing spinner colors and size once per render is efficient and clean. The extracted utilities provide consistent behavior across different button variants.
src/components/Atoms/Controls/Input/types/formutils.ts (2)
21-25: Clever event type detection for unified form handling.The use of
"nativeEvent"property to differentiate between native React events and custom events is a clean approach. This allows the utility to handle both event types appropriately while maintaining type safety.
9-32: Well-designed utility for consistent form change handling.The function provides a unified interface for handling both native and custom change events, properly integrating with react-hook-form's
setValueandtriggermethods. The generic typing ensures type safety across different form schemas.src/components/Atoms/Controls/Input/TextInput.tsx (2)
61-66: LGTM: Proper ref forwarding implementation.The ref forwarding logic correctly handles both function and object refs while maintaining compatibility with react-hook-form's internal ref management.
17-40: Ref destructuring pattern is safe and correctVerified that extracting
ref(and other handlers) fromregister()and merging it with the forwardedrefaligns with the recommended react-hook-form approach for custom inputs. No changes required.src/components/Atoms/Controls/FloatingChatbot/index.tsx (2)
194-210: LGTM: Excellent typing indicator implementation.The animated typing indicator with staggered bounce delays creates a polished user experience and follows good animation practices.
239-249: LGTM: Proper accessibility implementation.The button has appropriate ARIA labels and the conditional icon display based on open state provides clear visual feedback.
src/components/Atoms/Controls/Button/useSpinnerConfig.ts (1)
18-20: LGTM: Clean size mapping logic.The size determination logic is concise and handles the fallback from button size to spinner size appropriately.
src/components/Atoms/Controls/BidirectionalSlider/index.tsx (1)
36-48: Well-structured refactoring with proper separation of concerns.The extraction of value conversion logic to utility functions and the clean integration in the onChange handler improves maintainability and testability. The background gradient extraction also follows the same pattern effectively.
src/components/Atoms/Controls/FloatingChatbot/FloatingChatbot.stories.tsx (1)
1-69: Excellent Storybook setup with comprehensive documentation.The story configuration is well-structured with detailed documentation, appropriate controls, and clear descriptions of all props. The component subtitle and usage examples provide excellent context for developers.
src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.ts (1)
17-43: Well-implemented value conversion with proper precision handling.The function correctly handles rounding to gap increments, maintains appropriate decimal precision, and properly clamps values within bounds. The mathematical logic is sound and the implementation is clean.
src/components/Atoms/Controls/FloatingChatbot/FloatingChatbot.stories.tsx
Outdated
Show resolved
Hide resolved
src/components/Atoms/Controls/BidirectionalSlider/utils/valueConverter.ts
Show resolved
Hide resolved
…onverter.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…stories.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…unit test for valueconverter function
|
removed commits by coderabbit because few of them were incorrect |
Q1: Refactored Input Component
Inputcomponent to follow the Single Responsibility Principle (SRP).Q2: Refactored Two Additional Components
Button
buttonVariants.BidirectionalSlider
Q3: Added Floating Chatbot
Q4: Bundler Refactor (Optional)
Warning : The issue with the current bundler
generate-index.shis that it uses hardcoded glob values to find.tsxfiles. This approach is not performant for large or deeply nested component trees and often leads to broken or incomplete barrel files.Solution with ts-morph
generate-barrel.tsusingts-morph..tsxfiles insidesrc/components.src/components/index.tsxbarrel file.pnpm generate:barrel && tsup.Testing Strategy
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
Chores