Skip to content

Conversation

@Agarwalchetan
Copy link

@Agarwalchetan Agarwalchetan commented Oct 31, 2025

This PR enhances the LingoProviderWrapper component in the React package by adding optional loadingComponent and errorComponent props, enabling developers to provide custom UI for loading and error states instead of the default null behavior.

This resolves two TODO comments in the codebase that identified the need for better loading and error state handling.

Changes

Core Implementation

  • Added loadingComponent prop: Optional component to display while the dictionary is loading
  • Added errorComponent prop: Optional component to display when dictionary loading fails
  • Refactored state management: Changed from simple D | null to discriminated union with loading, loaded, and error states
  • Type-safe error handling: Automatically converts any thrown value to an Error object
  • Removed TODO comments: Both TODOs in provider.tsx are now resolved

Testing

  • Added 5 comprehensive test cases covering:
    • Custom loading component rendering
    • Custom error component with error message display
    • Non-Error object conversion to Error
    • State transition verification
    • Backward compatibility
  • All 77 tests in the React package pass

Benefits

  • Better UX: Developers can now show meaningful loading states instead of blank screens
  • Proper error handling: Custom error UI with access to error details
  • Backward compatible: Maintains existing null behavior when props are not provided
  • Type-safe: Full TypeScript support with proper error typing
  • Well documented: Comprehensive JSDoc with usage examples

Example Usage

import { LingoProviderWrapper } from "lingo.dev/react/client";

function App() {
  return (
    <LingoProviderWrapper
      loadDictionary={loadDictionary}
      loadingComponent={
        <div className="loading-spinner">
          Loading translations...
        </div>
      }
      errorComponent={({ error }) => (
        <div className="error-message">
          Failed to load translations: {error.message}
        </div>
      )}
    >
      <YourApp />
    </LingoProviderWrapper>
  );
}

Checklist

  • Linked to existing issue (addresses TODOs in codebase)
  • Added comprehensive tests (5 new test cases, all passing)
  • Added changeset (pnpm new)
  • All tests pass (pnpm turbo test)
  • Code formatted (pnpm format)
  • Format check passes (pnpm format:check)
  • Backward compatible (no breaking changes)
  • Documentation included (JSDoc with examples)

Code Quality

  • Surgical PR: Single, focused objective
  • Elegant implementation: Uses TypeScript discriminated unions for type-safe state management
  • Comprehensive testing: Tests cover both positive and negative paths, including edge cases
  • Zero breaking changes: Fully backward compatible with existing implementations

Test Results

Test Files  18 passed (18)
Tests       77 passed (77)
Duration    22.99s

Before/After

Before:

// Loading state: renders null (blank screen)
// Error state: renders null (blank screen, error only in console)

After:

// Loading state: renders custom loading component (optional)
// Error state: renders custom error component with error details (optional)
// Default: maintains backward compatible null behavior

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the LingoProviderWrapper component by adding optional loadingComponent and errorComponent props to enable custom UI for loading and error states, resolving TODO comments in the codebase.

Key Changes:

  • Added optional loadingComponent and errorComponent props with comprehensive JSDoc documentation
  • Refactored state management from simple D | null to discriminated union with loading, loaded, and error states
  • Added 5 new test cases covering loading, error, and state transition scenarios

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/react/src/client/provider.tsx Added new props and state management logic for custom loading/error components
packages/react/src/client/provider.spec.tsx Added comprehensive test coverage for new loading and error component functionality
.changeset/improved-loading-error-states.md Added changeset documenting the new minor feature with usage examples
Comments suppressed due to low confidence (1)

packages/react/src/client/provider.spec.tsx:167

  • Unused variable rerender.
      const { findByTestId, rerender } = render(

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

.fn()
.mockResolvedValue({ locale: "en", files: {} });

const { findByTestId, rerender } = render(
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

The rerender destructured from render() is assigned but never used in this test. This suggests either incomplete test implementation or unnecessary variable assignment.

Consider removing the unused rerender variable:

const { findByTestId } = render(
Suggested change
const { findByTestId, rerender } = render(
const { findByTestId } = render(

Copilot uses AI. Check for mistakes.
Copy link
Author

@Agarwalchetan Agarwalchetan Nov 14, 2025

Choose a reason for hiding this comment

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

Improved Old Problems

@Agarwalchetan
Copy link
Author

Again Check this Request

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.

1 participant