Creating Interactive Task Cards
Creating Interactive Task Cards
In our previous lesson, we transformed static column placeholders into dynamic, reusable Column components. Now that we have this flexible container structure in place, it's time to populate these columns with their core content: individual task cards.
Task cards are the building blocks of any Kanban system. Each card represents a single work item that can move between columns as work progresses. A well-designed task card should communicate key information at a glance while being interactive and accessible. In this lesson, we'll create cards that display a title and an optional description, with visual feedback when hovered over or focused.
Building The TaskCard Component
Let's create a new file called TaskCard.svelte in our components directory. This component will represent each individual task in our Kanban board.
Defining Component Props
We'll start by defining the component's props using Svelte 5's $props() function, which you'll remember from our work with the Column component. The key difference here is that we're making the description optional by providing a default empty string value:
Building The Component Template
The template portion needs to handle two scenarios: when a description exists and when it doesn't. We'll use Svelte's {#if} block for conditional rendering:
The {#if} block ensures the description paragraph only appears when a description is provided.
Notice we've included tabindex="0" to make the card keyboard-navigable. This is an important accessibility feature that allows users to interact with our cards using keyboard navigation.
Implementing Interactive Styling
For styling, we'll implement several important interaction states:
The transition property creates smooth animations when the card moves, while the :hover and :focus pseudo-classes provide clear visual feedback to users.
Understanding Reactive Design Principles
Our TaskCard component embodies several key reactive programming principles:
-
Data as the Single Source of Truth: The props we define (
titleanddescription) are our component's data model, and the UI is derived from this data. -
Declarative Rendering: We declare that the description paragraph should only appear when a description exists, using the
{#if}block. -
Automatic UI Updates: If the
descriptionprop changes, our UI will automatically update to show or hide the paragraph without any manual DOM manipulation.
This reactive approach means our component will consistently reflect its current data state, making the UI predictable and easier to reason about.
Populating Columns With Tasks
Now that we have our TaskCard component, let's integrate it with the Column component we built in the previous lesson. The @render children?.() pattern we implemented in the Column component will automatically handle our TaskCards:
This implementation will render three columns with sample tasks. The first column shows two tasks (one with a description, one without), demonstrating both use cases of our conditional rendering. The responsive behavior we implemented earlier remains intact — columns will stack vertically on smaller screens while maintaining all task card styling and interactions.
Summary & Practice Prep
In this lesson, we've completed a crucial part of our Kanban board by implementing interactive TaskCard components. You've learned how to create components with optional props, conditionally render content, and implement accessible interactions. These skills form the foundation for the more advanced features we'll add in future lessons.
The practice exercises will help you solidify these concepts by:
- Creating
TaskCardswith different combinations of titles and descriptions - Customizing the visual appearance of cards (colors, spacing, shadows)
- Testing keyboard navigation between cards
- Experimenting with adding new task types
Remember that while our current implementation is static, the component patterns we've established will work seamlessly when we later connect to dynamic data sources. The separation between presentation (TaskCard) and container (Column) components will prove especially valuable as our application grows in complexity.
