Skip to content

Instantly share code, notes, and snippets.

@lxe
Last active January 3, 2025 04:54
Show Gist options
  • Save lxe/597092e937c406e88a3f1d0f50c3e630 to your computer and use it in GitHub Desktop.
Save lxe/597092e937c406e88a3f1d0f50c3e630 to your computer and use it in GitHub Desktop.
Conditional Component Group
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