Skip to content

A lightweight πŸ’‘ React utility component that makes conditional rendering cleaner and more readable using JSX-friendly syntax.

Notifications You must be signed in to change notification settings

joelnbl/react-chousy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

react-chousy banner

🎭 react-chousy

A lightweight πŸ’‘ React utility component that makes conditional rendering cleaner and more readable using JSX-friendly syntax.

No more messy ? : everywhere β€” just clean and simple conditional blocks.


πŸš€ Features

βœ… Intuitive JSX syntax
βœ… Type-safe with TypeScript
βœ… Fully tree-shakable
βœ… Works with any React component
βœ… Super lightweight (~300 bytes gzipped)


πŸ“¦ Install

npm install react-chousy

✨ Usage

import { ConditionalRender } from 'react-chousy';

<ConditionalRender condition={isLoggedIn}>
  {{
    true: <p>Welcome, hero 🦸!</p>,
    false: <p>Access denied! 🚫 Please log in.</p>
  }}
</ConditionalRender>

🧠 Bonus: Nesting

<ConditionalRender condition={isLoggedIn}>
  {{
    true: (
      <ConditionalRender condition={hasProfile}>
        {{
          true: <p>Welcome to your profile πŸ‘€</p>,
          false: <p>Finish setting up your profile ✍️</p>
        }}
      </ConditionalRender>
    ),
    false: <p>Please log in to continue πŸ‘‹</p>
  }}
</ConditionalRender>

πŸ›  API

Prop Type Description
condition boolean The condition to evaluate
children { true, false } JSX Content to render based on the result

πŸ”€ SwitchCaseRender

A JSX-friendly alternative to switch statements. Pass a value and render different elements based on matched keys.

✨ Usage

import { SwitchCaseRender } from 'react-chousy';

<SwitchCaseRender value={status}>
  {{
    idle: <p>Waiting...</p>,
    loading: <p>Loading...</p>,
    success: <p>βœ… Success!</p>,
    error: <p>❌ Error</p>,
    default: <p>Unknown status</p>
  }}
</SwitchCaseRender>

πŸ“˜ Real-world example

import { SwitchCaseRender } from 'react-chousy';

const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle");

<SwitchCaseRender value={status}>
  {{
    idle: <p>Esperando acciΓ³n...</p>,
    loading: <p>Cargando...</p>,
    success: <p>Β‘Completado con Γ©xito!</p>,
    error: <p>OcurriΓ³ un error.</p>,
    default: <p>Estado desconocido</p>,
  }}
</SwitchCaseRender>

πŸ›  API

Prop Type Description
value string | number The value to match
children Record<string, ReactNode> Keys that match the value + optional default fallback

πŸŒ€ ChousyEach (Rails-inspired map/each for React)

A declarative, flexible, and beautiful way to render lists in React, inspired by Ruby/Rails' each method. Supports optional selection state and side effects out of the box.

✨ Usage

import { ChousyEach } from 'react-chousy';

const fruits = ['🍎', '🍌', 'πŸ‡'];

<ChousyEach of={fruits}>
  {(fruit, idx) => (
    <span>{fruit}</span>
  )}
</ChousyEach>

🎯 With selection state (trackSelection)

import { ChousyEach } from 'react-chousy';

const fruits = ['🍎', '🍌', 'πŸ‡'];

<ChousyEach of={fruits} trackSelection>
  {(fruit, idx, { selectedIdx, setSelectedIdx }) => (
    <button
      className={selectedIdx === idx ? 'font-bold text-blue-600' : 'text-gray-700'}
      onClick={() => setSelectedIdx(idx)}
    >
      {fruit}
    </button>
  )}
</ChousyEach>

⚑ With effect on list change (onChange)

import { ChousyEach } from 'react-chousy';

const fruits = ['🍎', '🍌', 'πŸ‡'];

<ChousyEach
  of={fruits}
  onChange={list => console.log('List changed:', list)}
>
  {(fruit, idx) => <span>{fruit}</span>}
</ChousyEach>

🧭 Navbar highlighting (navHighlight)

import { ChousyEach } from 'react-chousy';

const menu = [
  { label: 'Home', path: '/' },
  { label: 'About', path: '/about' },
  { label: 'Contact', path: '/contact' },
];

// Assume you get currentPath from your router (e.g., window.location.pathname or a router hook)
const currentPath = '/about';

<ChousyEach
  of={menu}
  navHighlight
  getPath={item => item.path}
  currentPath={currentPath}
>
  {(item, idx, { isActive }) => (
    <a
      href={item.path}
      className={isActive ? 'text-blue-600 font-bold' : 'text-gray-700'}
    >
      {item.label}
    </a>
  )}
</ChousyEach>

πŸ›  ChousyEach API

Prop Type Description
of T[] Array of items to render
children (item: T, idx: number, helpers?) => ReactNode Render function for each item. If trackSelection or navHighlight is true, helpers are provided
className string Optional Tailwind classes for the <ul>
onChange (list: T[]) => void Optional effect callback when list changes
trackSelection boolean If true, exposes selectedIdx and setSelectedIdx to children
navHighlight boolean If true, highlights the item whose path matches currentPath
getPath (item: T, idx: number) => string Function to extract the path from each item
currentPath string The current path to match for highlighting

πŸ‘¨β€πŸ’» Author

Made with ❀️ by Joelnbl
πŸ”— GitHub
🐦 Twitter


πŸ™Œ Contributors

Thanks to these awesome people:

πŸ“ License

MIT β€” use it freely, improve it, and share it!

About

A lightweight πŸ’‘ React utility component that makes conditional rendering cleaner and more readable using JSX-friendly syntax.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •