Last active
January 3, 2025 04:54
-
-
Save lxe/597092e937c406e88a3f1d0f50c3e630 to your computer and use it in GitHub Desktop.
Conditional Component Group
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from 'react'; | |
// First, let's define our conditional components | |
const C = ({ if: condition, elseif: elseIfCondition, else: isElse, children }) => { | |
if (condition !== undefined && condition) { | |
return <>{children}</>; | |
} | |
if (elseIfCondition !== undefined && elseIfCondition) { | |
return <>{children}</>; | |
} | |
if (isElse !== undefined) { | |
return <>{children}</>; | |
} | |
return null; | |
}; | |
const ConditionalGroup = ({ children }) => { | |
const childrenWithTracking = React.Children.map(children, (child, index) => { | |
if (!React.isValidElement(child)) return child; | |
let shouldRender = false; | |
let prevConditionMet = false; | |
for (let i = 0; i < index; i++) { | |
const sibling = children[i]; | |
if (!React.isValidElement(sibling)) continue; | |
const siblingProps = sibling.props; | |
if ( | |
(siblingProps.if !== undefined && siblingProps.if) || | |
(siblingProps.elseif !== undefined && siblingProps.elseif) | |
) { | |
prevConditionMet = true; | |
break; | |
} | |
} | |
if (!prevConditionMet) { | |
if (child.props.if !== undefined) { | |
shouldRender = child.props.if; | |
} else if (child.props.elseif !== undefined) { | |
shouldRender = child.props.elseif; | |
} else if (child.props.else !== undefined) { | |
shouldRender = true; | |
} | |
} | |
return shouldRender ? child : null; | |
}); | |
return <>{childrenWithTracking}</>; | |
}; | |
// Now let's create a demo component | |
const ConditionalDemo = () => { | |
const [count, setCount] = useState(0); | |
return ( | |
<div className="p-6 max-w-lg mx-auto bg-white rounded-xl shadow-lg space-y-4"> | |
<div className="space-y-2"> | |
<h2 className="text-xl font-bold">Conditional Rendering Demo</h2> | |
<p className="text-gray-600">Current count: {count}</p> | |
<div className="space-x-2"> | |
<button | |
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" | |
onClick={() => setCount(c => c - 1)} | |
> | |
Decrease | |
</button> | |
<button | |
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" | |
onClick={() => setCount(c => c + 1)} | |
> | |
Increase | |
</button> | |
</div> | |
</div> | |
<div className="mt-4 p-4 border rounded-lg bg-gray-50"> | |
<ConditionalGroup> | |
<C if={count > 5}> | |
<div className="text-green-600 font-semibold"> | |
Count is greater than 5! π | |
</div> | |
</C> | |
<C elseif={count > 0}> | |
<div className="text-blue-600 font-semibold"> | |
Count is positive but not greater than 5 π | |
</div> | |
</C> | |
<C elseif={count === 0}> | |
<div className="text-gray-600 font-semibold"> | |
Count is zero 0οΈβ£ | |
</div> | |
</C> | |
<C else> | |
<div className="text-red-600 font-semibold"> | |
Count is negative π | |
</div> | |
</C> | |
</ConditionalGroup> | |
</div> | |
</div> | |
); | |
}; | |
export default ConditionalDemo; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment