Hone logo
Hone
Problems

Building a Reusable Vue Component Library with TypeScript

This challenge focuses on creating a basic, reusable component library in Vue.js using TypeScript. Building component libraries is a crucial skill for any Vue developer, enabling code reuse, consistency, and faster development across projects. This exercise will guide you through structuring a simple library with a few components.

Problem Description

You are tasked with creating a minimal Vue component library. The library should contain three components: Button, Input, and Card. Each component should be written in TypeScript and demonstrate basic props and styling. The library should be structured in a way that allows for easy addition of new components in the future. The final output should be a functional Vue library that can be imported and used in another Vue project.

Key Requirements:

  • Component Structure: Each component (Button, Input, Card) should be a separate .vue file.
  • TypeScript: All components must be written using TypeScript, including prop type definitions.
  • Props:
    • Button: label (string), variant (string - 'primary', 'secondary', 'success'), disabled (boolean, default: false)
    • Input: type (string - 'text', 'password', default: 'text'), placeholder (string), modelValue (string - for v-model compatibility), onChange (function)
    • Card: title (string), body (string)
  • Styling: Each component should have basic styling (using inline styles or a simple CSS file) to visually differentiate them. Focus on clarity and demonstration of styling, not complex design.
  • Library Structure: The components should be exported from a single index.ts file, making it easy to import the entire library.
  • v-model support: The Input component should implement modelValue and update:modelValue props to support v-model.

Expected Behavior:

  • The Button component should display the provided label and change its appearance based on the variant prop. It should be disabled if the disabled prop is true.
  • The Input component should display the provided type and placeholder. It should emit an event when the input value changes, allowing for external handling. It should also correctly handle v-model.
  • The Card component should display the provided title and body within a visually distinct card-like container.
  • When imported into another Vue project, the components should render correctly and behave as expected.

Edge Cases to Consider:

  • Invalid variant prop values for the Button component (handle gracefully, perhaps with a default style).
  • Empty title or body for the Card component.
  • Ensure proper event handling for the Input component's onChange event.

Examples

Example 1: Button

Input:  <Button label="Click Me" variant="primary" />
Output: A button labeled "Click Me" with a primary style.
Explanation: The Button component renders a button element with the provided label and applies the "primary" style.

Example 2: Input

Input: <Input type="password" placeholder="Password" modelValue="initialValue" @onChange="updateValue" />
Output: An input field of type password with the placeholder "Password" and an initial value of "initialValue".  Changes to the input will trigger the `updateValue` function.
Explanation: The Input component renders an input element with the specified type, placeholder, and initial value. It also listens for the 'change' event and emits a custom event with the new value.

Example 3: Card

Input: <Card title="My Card" body="This is the card body." />
Output: A card-like container displaying "My Card" as the title and "This is the card body." as the body.
Explanation: The Card component renders a container with the title and body displayed within it.

Constraints

  • Component Size: Each component should be relatively small and focused on demonstrating the core concepts. Avoid complex logic or external dependencies.
  • Styling: Keep styling simple and focused on demonstrating basic CSS application. No need for advanced CSS frameworks.
  • TypeScript Strictness: Enable strict TypeScript compilation options (e.g., strict: true, noImplicitAny: true) in your tsconfig.json file.
  • No External Libraries: Do not use external UI libraries (e.g., Vuetify, Element UI). Focus on building components from scratch.

Notes

  • Consider using Vue's defineComponent for better type inference.
  • Think about how you would extend this library to include more components in the future. A clear and organized structure is key.
  • Focus on creating a well-structured and maintainable codebase. Good naming conventions and clear comments are encouraged.
  • The goal is to demonstrate understanding of Vue component structure, TypeScript, props, and basic styling. A fully polished UI is not required.
Loading editor...
typescript