Card Deck I
Prompt
Your task is to build a Card Deck viewer using React. The application should generate a standard deck of 52 playing cards and display them on screen with the ability to switch between two layouts.
Requirements
- Generate a standard deck of 52 playing cards using 4 suits (
Heart,Spade,Diamond,Club) and 13 ranks (Ace,2–10,Jack,Queen,King). - Each card should display its rank and suit combined (e.g.,
AceHeart,2Spade). - Render all cards in a list layout (stacked vertically) by default.
- Add a "Switch layout" button that toggles between a list layout and a grid layout (5 cards per row).
- All cards should have a blue border.
Example


Playground (Prompt 1)
Start by thinking about the data structure for the deck. You have 4 suits and 13 ranks. Using two arrays and nested loops is the simplest way to generate all 52 combinations.
For toggling layouts, a single boolean or string state is sufficient. You can conditionally apply different CSS class names based on this state to switch between list and grid layouts.
To make the grid layout work with 5 cards per row, CSS Grid with grid-template-columns: repeat(5, 1fr) is the most straightforward approach.
Solution (Prompt 1)
Explanation
This is an interview challenge asked at Adobe. We will go through the solution step by step. I will show you what an ideal solution looks like, common mistakes candidates make, and how to structure your components cleanly so you have plenty of time left for the follow-up prompts.
Before we start coding, read the prompt carefully. We need to generate 52 cards, render them in two layouts, add a toggle button, and style one suit differently. If anything is unclear, ask the interviewer. Do not start coding under pressure only to realise you missed a requirement halfway through.
Now, let's start solving.
Step 1: Creating the Deck Utility
The first thing we need is the data — a deck of 52 cards. We have 4 suits and 13 ranks, so we use two arrays and nested loops to generate every combination.
I am going to create a utils folder and add a deck.js file inside it. The reason I separate this into a utility is that deck generation is pure data logic, it has nothing to do with React or UI. Keeping it in its own file makes it reusable and testable.
utils/deck.js
const SUITS = ['Heart', 'Spade', 'Diamond', 'Club'];
const RANKS = [
'Ace',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'Jack',
'Queen',
'King',
];
function createDeck() {
const deck = [];
for (const suit of SUITS) {
for (const rank of RANKS) {
deck.push({
id: `${rank}${suit}`,
rank,
suit,
});
}
}
return deck;
}
export { createDeck };We define SUITS and RANKS as constants at the top of the file. These are uppercase because they are constant values that never change. Inside createDeck, we loop through each suit and each rank, creating a card object with id, rank, and suit. The id is a combination of rank and suit (like AceHeart) which we will use as the React key and also as the display text.
Interview Tip
Always use console.log after generating data. Call console.log(createDeck()) and check the console to make sure you get exactly 52 cards and the shape looks correct. Do not assume it works — verify it. Many candidates skip this step and later debug why cards are not rendering correctly, only to find their data generation had a bug.
Common Pitfalls
- Some candidates use
Array.fromwith complex index math to generate the deck. While that works, it is harder to read and debug under time pressure. Simple nestedfor...ofloops are clear, fast to write, and easy for the interviewer to follow. Do not over-engineer the simple things. - Some candidates forget to give each card a unique
id. Later when they try to render the cards with.map(), they have no good value for thekeyprop and either skip it or use the array index. Always plan your data structure with rendering in mind.
Step 2: Setting Up App.js and Creating CardGrid
Now that we have our deck data, let's set up App.js. First, let's import our createDeck function and generate the deck. Since the deck does not change, we can create it outside the component — there is no reason to regenerate 52 cards on every render.
App.js
import React, { useState } from 'react';
import './styles.css';
import { createDeck } from './utils/deck';
import CardGrid from './components/CardGrid';
const deck = createDeck();
export default function App() {
const [layout, setLayout] = useState('list');
const handleToggleLayout = () => {
setLayout((prev) =>
prev === 'list' ? 'grid' : 'list'
);
};
return (
<main className="wrapper">
<button onClick={handleToggleLayout}>
Switch layout
</button>
<CardGrid cards={deck} layout={layout} />
</main>
);
}We are using a layout state with two values: 'list' and 'grid'. The toggle function uses the functional form of setLayout to flip between the two. We pass the deck and layout as props to a CardGrid component.
Now let's create the CardGrid component. This component is responsible for rendering all the cards. It applies different CSS class names based on the layout prop.
components/CardGrid.js
import React from 'react';
import Card from './Card';
export default function CardGrid({ cards, layout }) {
return (
<div className={layout === 'grid' ? 'grid' : 'list'}>
{cards.map((card) => (
<Card key={card.id} card={card} />
))}
</div>
);
}The key decision here is that CardGrid does not own any state. It just takes cards and layout as props and renders. The layout toggle state lives in App.js. This keeps CardGrid reusable — you could use it anywhere and pass different cards and layouts without it needing to know about toggle logic.
We use card.id as the React key prop since every card has a unique id like AceHeart or 10Club.
Now, inside CardGrid we are rendering a Card component for each card. We need to create this component. This is the natural flow — you start building the parent, and when you need to render each item, you stop and create the child component.
Common Pitfalls
Some candidates render the entire card deck directly inside App.js using .map() without creating separate components. This works for the first prompt, but when the interviewer adds follow-up requirements (flip, mark, swap), the code becomes a mess. Break it down early — it takes 2 extra minutes and saves you 10 minutes later.
Step 3: Creating the Card Component
Each card needs to show its name.
components/Card.js
import React from 'react';
export default function Card({ card }) {
return <div className="card">{card.id}</div>;
}The Card component is simple. It receives a card prop and renders the card's id as text inside a div with the card class. Right now it does not need any conditional logic — all cards look the same.
Step 4: Styling List and Grid Layouts
Now let's add the CSS to make our two layouts work.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
width: 100%;
}
.wrapper {
padding: 12px;
}
.list {
display: flex;
flex-direction: column;
}
.grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
}
.card {
border: 2px solid blue;
padding: 12px;
min-height: 100px;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
}As always, the first thing I do is add box-sizing: border-box; to make sizing predictable.
For the list layout, we use display: flex; flex-direction: column; which stacks all cards vertically. This gives us the table-like list view from the first screenshot.
For the grid layout, we use CSS Grid with grid-template-columns: repeat(5, 1fr). This creates exactly 5 equal-width columns. The gap: 12px adds spacing between cards so they do not stick together. CSS Grid is the right tool here because we need a fixed number of columns with equal widths, which is exactly what Grid does best.
For the cards, we give a border: 2px solid blue for a clear visual boundary. The min-height: 100px gives each card enough visual height. We also use display: flex; flex-direction: column; to ensure that the card text and future buttons (in follow-up prompts) stack nicely vertically.
CSS Grid vs Flexbox
Some candidates try to achieve the grid layout using Flexbox with flex-wrap: wrap and width: 20% on each card. This works but is more fragile — you need to handle gaps differently, and percentage widths get tricky with padding and borders. CSS Grid with repeat(5, 1fr) handles all of this naturally in one line. Use Grid when you have a defined number of columns, use Flexbox when you need flexible one-directional layouts.
Component Architecture Summary
Let's step back and look at what we have built:
utils/deck.js— Pure data logic. Generates the 52-card deck. No React dependency.App.js— The parent component. Holds thelayoutstate and toggle logic. Creates the deck and passes data down.components/CardGrid.js— Renders the list of cards using the correct layout class. Receivescardsandlayoutas props.components/Card.js— Renders a single card with its name.
This structure is clean and each piece has a single responsibility. When the interviewer gives the next prompt (adding flip or swap), we will not need to restructure anything — we will just extend the existing components.
Communicate While You Code
Throughout the interview, talk about why you are making certain decisions:
- I am creating a separate utility for deck generation because it is pure data logic and does not belong in a React component
- I chose to keep the layout state in App.js because CardGrid should be a reusable presentation component
- I am using CSS Grid for the grid layout because we need a fixed number of columns
The interviewer is evaluating your thought process, not just whether it works. Explaining your reasoning shows seniority and gets you closer to a "Strong Yes".
Interviewer Criteria
HTML/CSS
Does my layout match the provided example for both list and grid views?
Did I style the UI quickly (10 minutes or less)?
Are my CSS class names descriptive and consistent?
JavaScript
Was I able to correctly generate all 52 cards from suits and ranks?
Have I used ES6 features efficiently, such as const, arrow functions, template literals, and for...of loops?
Are my variable and function names descriptive and consistent?
Did I separate the deck generation logic from the UI logic?
React
Have I used the key prop appropriately on all iterated elements?
Did I use a clean toggle pattern for switching layouts?
Am I comfortable using React hooks like useState?
Did I keep the deck creation outside the component to avoid unnecessary re-creation on every render?
Component Architecture
Did I create separate components for
CardandCardGrid?Did I extract the deck generation into a utility file?
Are the names of my components, functions, and handlers clear and descriptive?
Time Checkpoints
- 10:00 AM
Interview starts 👥
- 10:03 AM
Prompt given by the interviewer
- 10:05 AM
Candidate reads the prompt, asks clarifying questions, and starts coding
- 10:08 AM
Deck utility created with suits and ranks
- 10:12 AM
Cards rendered in list layout
- 10:16 AM
Switch layout button and grid layout working
- 10:20 AM
Suit-based border styling applied, Card and CardGrid components separated
- 10:20 AM
Prompt 2 given by the interviewer ➡️