Hone logo
Hone
Problems

Implementing Slot Props in Vue with TypeScript

Slot props allow you to pass data down from a parent component to a child component's slot, enabling dynamic content injection and greater component reusability. This challenge will guide you in creating a Vue component that utilizes slot props to customize its behavior and appearance based on data passed from its parent. Successfully completing this challenge demonstrates a strong understanding of Vue's slot mechanism and TypeScript's type safety.

Problem Description

You are tasked with creating a Card component in Vue.js using TypeScript. This Card component should accept a title prop and a footer prop. The title prop is a string representing the card's title, which should be displayed prominently. The footer prop is an object containing optional properties: icon (a string representing an icon class, e.g., "fas fa-check-circle") and text (a string representing the footer text). The Card component should render a basic card structure, displaying the title and, if provided, the footer with its icon and text. The footer content should be rendered within a named slot called "footer-content".

Key Requirements:

  • The Card component must be written in TypeScript.
  • The title prop must be a string.
  • The footer prop must be an object with optional icon (string) and text (string) properties.
  • The component must render the title.
  • If a footer prop is provided, it should render an icon (if present) and text within the "footer-content" slot.
  • The component should be reusable and adaptable to different footer content.

Expected Behavior:

When a parent component uses the Card component and provides a title and a footer object with both icon and text, the card should display the title and the footer with the specified icon and text within the "footer-content" slot. If only one of icon or text is provided, only that property should be rendered. If no footer is provided, the "footer-content" slot should remain empty.

Edge Cases to Consider:

  • What happens if the icon prop is an empty string? Should it be rendered or skipped? (Assume it should be skipped).
  • What happens if the text prop is null or undefined? (Assume it should be skipped).
  • What happens if the footer prop is null or undefined? (The footer should not be rendered).

Examples

Example 1:

Input:
<Card title="Welcome!" footer={{ icon: "fas fa-smile", text: "Success!" }} />

Output:
<div class="card">
  <h1>Welcome!</h1>
  <div class="card-footer">
    <i class="fas fa-smile"></i>
    <span>Success!</span>
  </div>
</div>

Explanation: The card displays the title "Welcome!" and the footer with the smile icon and the text "Success!".

Example 2:

Input:
<Card title="Important Notice" footer={{ text: "Please read carefully." }} />

Output:
<div class="card">
  <h1>Important Notice</h1>
  <div class="card-footer">
    <span>Please read carefully.</span>
  </div>
</div>

Explanation: The card displays the title "Important Notice" and the footer with only the text "Please read carefully." because the icon is missing.

Example 3:

Input:
<Card title="Simple Card" />

Output:
<div class="card">
  <h1>Simple Card</h1>
</div>

Explanation: The card displays the title "Simple Card" and no footer because no footer prop was provided.

Constraints

  • The title prop must be a string.
  • The icon prop (within the footer object) must be a string.
  • The text prop (within the footer object) must be a string.
  • The component should be reasonably performant (no unnecessary re-renders).
  • Use standard Vue.js and TypeScript practices.

Notes

  • Consider using template literals for cleaner HTML generation.
  • Think about how to handle optional properties in the footer object using TypeScript's optional properties and conditional rendering.
  • You can use any CSS framework or styling approach you prefer for the card's appearance. The focus is on the slot prop implementation, not the styling.
  • The Card component should be a single-file component (.vue).
  • Assume the fas icon classes are available (e.g., from Font Awesome).
Loading editor...
typescript