KendoReact Playground
This is a submission for the KendoReact Free Components Challenge. What I Built Hey there! I’m Aniruddha Adak, and I built a little web playground that’s basically my excuse to relive my childhood while pretending to be a serious developer. This project is a React app with three sections: a Game Page (think Tetris and Memory Game, but with less yelling at the screen), a Sites Section (fancy dashboards and portfolios because adulting), and a Blocks Page (cool UI bits like login cards and sidebars). It’s all tied together with a snazzy toolbar that screams, “Click me, I’m fun!” I used TypeScript because I like my code to yell at me before it breaks, and Vite because I’m too impatient for slow builds. The result? A fast, interactive app that’s equal parts nostalgia and nerdy joy. Here’s the code that powers it all: Main App (src/App.tsx) This is the heart of my playground—navigation and all! import React from 'react'; import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; import { Toolbar, Button } from '@progress/kendo-react-buttons'; import GamePage from './pages/GamePage.tsx'; import SitesSection from './pages/SitesSection.tsx'; import BlocksPage from './pages/BlocksPage.tsx'; const App: React.FC = () => { return ( Games Sites Blocks ); }; export default App; Vite Entry (src/main.tsx) How I get this party started with Vite: import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App.tsx'; ReactDOM.createRoot(document.getElementById('root')!).render( ); Vite Config (vite.config.ts) My Vite setup—keeps things fast and sassy: import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], server: { hmr: { overlay: true, }, }, }); Game Page (src/pages/GamePage.tsx) Where the fun begins—games galore! import React, { useState } from 'react'; import { Button } from '@progress/kendo-react-buttons'; import { Dialog } from '@progress/kendo-react-dialogs'; import MemoryGame from '../components/games/MemoryGame.tsx'; import TetrisGame from '../components/games/TetrisGame.tsx'; interface Game { name: string; component: JSX.Element; } const GamePage: React.FC = () => { const [selectedGame, setSelectedGame] = useState(null); const games: Game[] = [ { name: 'Memory Game', component: }, { name: 'Tetris', component: }, ]; return ( Games {games.map((game, index) => ( setSelectedGame(game.component)}> {game.name} ))} {selectedGame && ( setSelectedGame(null)} width={500}> {selectedGame} )} ); }; export default GamePage; Memory Game (src/components/games/MemoryGame.tsx) Flipping cards like a pro (or a kid with too much sugar): import React, { useState } from 'react'; import { Button } from '@progress/kendo-react-buttons'; import { Animation } from '@progress/kendo-react-animation'; const MemoryGame: React.FC = () => { const [flipped, setFlipped] = useState(Array(4).fill(false)); const handleFlip = (index: number) => { const newFlipped = [...flipped]; newFlipped[index] = !newFlipped[index]; setFlipped(newFlipped); }; return ( {flipped.map((isFlipped, index) => ( handleFlip(index)} style={{ width: '100px', height: '100px' }} > {isFlipped ? '⭐' : 'Back'} ))} ); }; export default MemoryGame; Tetris Game (src/components/games/TetrisGame.tsx) A Tetris wannabe that’s more chill than the real deal: import React, { useState } from 'react'; import { Button } from '@progress/kendo-react-buttons'; import { ProgressBar } from '@progress/kendo-react-progressbars'; const TetrisGame: React.FC = () => { const [score, setScore] = useState(0); const handleAction = () => { setScore((prevScore) => prevScore + 10); }; return ( Tetris Grid Move Block ); }; export default TetrisGame; Sites Section (src/pages/SitesSection.tsx) Where I pretend to be a grown-up with dashboards: import React, { useState } from 'react'; import { Button } from '@progress/kendo-react-buttons'; import { Dialog } from '@progress/kendo-react-dialogs'; import FinancialDashboard from '../components/sites/FinancialDashboard.tsx'; import Portfolio from '../components/sites/Portfolio.tsx'; interface Site { name: string; component: JSX.Element; } const SitesSection: React.FC = () => { const [selectedSite, setSelectedSite] = useState(null); const sites: Site[] = [ { name: 'Financ

This is a submission for the KendoReact Free Components Challenge.
What I Built
Hey there! I’m Aniruddha Adak, and I built a little web playground that’s basically my excuse to relive my childhood while pretending to be a serious developer.
This project is a React app with three sections: a Game Page (think Tetris and Memory Game, but with less yelling at the screen), a Sites Section (fancy dashboards and portfolios because adulting), and a Blocks Page (cool UI bits like login cards and sidebars).
It’s all tied together with a snazzy toolbar that screams, “Click me, I’m fun!”
I used TypeScript because I like my code to yell at me before it breaks, and Vite because I’m too impatient for slow builds.
The result? A fast, interactive app that’s equal parts nostalgia and nerdy joy. Here’s the code that powers it all:
Main App (src/App.tsx
)
This is the heart of my playground—navigation and all!
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { Toolbar, Button } from '@progress/kendo-react-buttons';
import GamePage from './pages/GamePage.tsx';
import SitesSection from './pages/SitesSection.tsx';
import BlocksPage from './pages/BlocksPage.tsx';
const App: React.FC = () => {
return (
<Router>
<Toolbar style={{ marginBottom: '20px' }}>
<Link to="/games" style={{ marginRight: '10px' }}>
<Button>GamesButton>
Link>
<Link to="/sites" style={{ marginRight: '10px' }}>
<Button>SitesButton>
Link>
<Link to="/blocks">
<Button>BlocksButton>
Link>
Toolbar>
<Switch>
<Route path="/games" component={GamePage} />
<Route path="/sites" component={SitesSection} />
<Route path="/blocks" component={BlocksPage} />
<Route path="/" component={GamePage} />
Switch>
Router>
);
};
export default App;
Vite Entry (src/main.tsx
)
How I get this party started with Vite:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
React.StrictMode>
);
Vite Config (vite.config.ts
)
My Vite setup—keeps things fast and sassy:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
hmr: {
overlay: true,
},
},
});
Game Page (src/pages/GamePage.tsx
)
Where the fun begins—games galore!
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Dialog } from '@progress/kendo-react-dialogs';
import MemoryGame from '../components/games/MemoryGame.tsx';
import TetrisGame from '../components/games/TetrisGame.tsx';
interface Game {
name: string;
component: JSX.Element;
}
const GamePage: React.FC = () => {
const [selectedGame, setSelectedGame] = useState<JSX.Element | null>(null);
const games: Game[] = [
{ name: 'Memory Game', component: <MemoryGame /> },
{ name: 'Tetris', component: <TetrisGame /> },
];
return (
<div style={{ padding: '20px' }}>
<h1>Gamesh1>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
{games.map((game, index) => (
<Button key={index} onClick={() => setSelectedGame(game.component)}>
{game.name}
Button>
))}
div>
{selectedGame && (
<Dialog title="Play Game" onClose={() => setSelectedGame(null)} width={500}>
{selectedGame}
Dialog>
)}
div>
);
};
export default GamePage;
Memory Game (src/components/games/MemoryGame.tsx
)
Flipping cards like a pro (or a kid with too much sugar):
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Animation } from '@progress/kendo-react-animation';
const MemoryGame: React.FC = () => {
const [flipped, setFlipped] = useState<boolean[]>(Array(4).fill(false));
const handleFlip = (index: number) => {
const newFlipped = [...flipped];
newFlipped[index] = !newFlipped[index];
setFlipped(newFlipped);
};
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px' }}>
{flipped.map((isFlipped, index) => (
<Animation key={index} transitionName={isFlipped ? 'flip' : ''}>
<Button
onClick={() => handleFlip(index)}
style={{ width: '100px', height: '100px' }}
>
{isFlipped ? '⭐' : 'Back'}
Button>
Animation>
))}
div>
);
};
export default MemoryGame;
Tetris Game (src/components/games/TetrisGame.tsx
)
A Tetris wannabe that’s more chill than the real deal:
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { ProgressBar } from '@progress/kendo-react-progressbars';
const TetrisGame: React.FC = () => {
const [score, setScore] = useState<number>(0);
const handleAction = () => {
setScore((prevScore) => prevScore + 10);
};
return (
<div>
<div
style={{
width: '200px',
height: '400px',
border: '1px solid black',
marginBottom: '10px',
}}
>
<p style={{ textAlign: 'center' }}>Tetris Gridp>
div>
<Button onClick={handleAction}>Move BlockButton>
<ProgressBar value={score} max={100} labelVisible={true} style={{ marginTop: '10px' }} />
div>
);
};
export default TetrisGame;
Sites Section (src/pages/SitesSection.tsx
)
Where I pretend to be a grown-up with dashboards:
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Dialog } from '@progress/kendo-react-dialogs';
import FinancialDashboard from '../components/sites/FinancialDashboard.tsx';
import Portfolio from '../components/sites/Portfolio.tsx';
interface Site {
name: string;
component: JSX.Element;
}
const SitesSection: React.FC = () => {
const [selectedSite, setSelectedSite] = useState<JSX.Element | null>(null);
const sites: Site[] = [
{ name: 'Financial Dashboard', component: <FinancialDashboard /> },
{ name: 'Portfolio', component: <Portfolio /> },
];
return (
<div style={{ padding: '20px' }}>
<h1>Sitesh1>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
{sites.map((site, index) => (
<Button key={index} onClick={() => setSelectedSite(site.component)}>
{site.name}
Button>
))}
div>
{selectedSite && (
<Dialog title="Site Preview" onClose={() => setSelectedSite(null)} width={600}>
{selectedSite}
Dialog>
)}
div>
);
};
export default SitesSection;
Financial Dashboard (src/components/sites/FinancialDashboard.tsx
)
Fancy numbers and badges—look at me, adulting!
import React from 'react';
import { Typography } from '@progress/kendo-react-common';
import { Badge } from '@progress/kendo-react-indicators';
import { ProgressBar } from '@progress/kendo-react-progressbars';
const FinancialDashboard: React.FC = () => {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
<Typography.h2>Financial OverviewTypography.h2>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<Typography.p>Revenue: $10,000Typography.p>
<Badge themeColor="success">+5%Badge>
div>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<Typography.p>Expenses: $7,000Typography.p>
<Badge themeColor="error">-2%Badge>
div>
<ProgressBar value={70} labelVisible={true} />
div>
);
};
export default FinancialDashboard;
Portfolio (src/components/sites/Portfolio.tsx
)
My imaginary projects, looking sharp:
import React from 'react';
import { Typography } from '@progress/kendo-react-common';
import { Button } from '@progress/kendo-react-buttons';
const Portfolio: React.FC = () => {
return (
<div>
<Typography.h2>Project GalleryTypography.h2>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '20px' }}>
<div>
<Typography.h3>Project 1Typography.h3>
<Button>View DetailsButton>
div>
<div>
<Typography.h3>Project 2Typography.h3>
<Button>View DetailsButton>
div>
div>
div>
);
};
export default Portfolio;
Blocks Page (src/pages/BlocksPage.tsx
)
UI goodies I can’t stop playing with:
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Dialog } from '@progress/kendo-react-dialogs';
import LoginCard from '../components/blocks/LoginCard.tsx';
import SidebarLayout from '../components/blocks/SidebarLayout.tsx';
interface Block {
name: string;
component: JSX.Element;
}
const BlocksPage: React.FC = () => {
const [selectedBlock, setSelectedBlock] = useState<JSX.Element | null>(null);
const blocks: Block[] = [
{ name: 'Login Card', component: <LoginCard /> },
{ name: 'Sidebar Layout', component: <SidebarLayout /> },
];
return (
<div style={{ padding: '20px' }}>
<h1>Blocksh1>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
{blocks.map((block, index) => (
<Button key={index} onClick={() => setSelectedBlock(block.component)}>
{block.name}
Button>
))}
div>
{selectedBlock && (
<Dialog title="Block Demo" onClose={() => setSelectedBlock(null)} width={400}>
{selectedBlock}
Dialog>
)}
div>
);
};
export default BlocksPage;
Login Card (src/components/blocks/LoginCard.tsx
)
A login form that’s simpler than my password:
import React from 'react';
import { Input } from '@progress/kendo-react-inputs';
import { Button } from '@progress/kendo-react-buttons';
const LoginCard: React.FC = () => {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<Input label="Username" placeholder="Enter username" />
<Input label="Password" type="password" placeholder="Enter password" />
<Button>LoginButton>
div>
);
};
export default LoginCard;
Sidebar Layout (src/components/blocks/SidebarLayout.tsx
)
A sidebar that pops up like my cat at dinnertime:
import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Dialog } from '@progress/kendo-react-dialogs';
const SidebarLayout: React.FC = () => {
const [isOpen, setIsOpen] = useState<boolean>(false);
return (
<div>
<Button onClick={() => setIsOpen(!isOpen)}>Toggle SidebarButton>
{isOpen && (
<Dialog title="Sidebar" onClose={() => setIsOpen(false)} width={200}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<Button>Menu Item 1Button>
<Button>Menu Item 2Button>
div>
Dialog>
)}
div>
);
};
export default SidebarLayout;
KendoReact Experience
Oh man, KendoReact’s free components were like my coding fairy godmothers!
I leaned hard on the Button
component—those little clickable heroes are everywhere, launching games and toggling sidebars.
The Dialog
component was my MVP, popping up games and demos like a jack-in-the-box (but less creepy).
I sprinkled in Animation
for that sweet card-flipping action in the Memory Game—because who doesn’t love a little pizzazz?
The ProgressBar
kept my Tetris score in check (spoiler: I’m still terrible at it), while Typography
made my text look pro without me trying too hard.
Honestly, these components saved me from CSS nightmares and made me look like I know what I’m doing. T
hat was fun—less hair-pulling, more high-fiving myself.
I learned KendoReact is like a cheat code for building fast and pretty!
Happy coding, folks—may your bugs be few and your buttons be plenty!