Hone logo
Hone
Problems

Vue Custom Directives: Interactive Highlight and Tooltip

This challenge focuses on creating and utilizing custom Vue.js directives to enhance user interaction with web elements. You'll develop two distinct directives: one for highlighting text on hover and another for displaying a tooltip when an element is hovered over. This is a fundamental skill for building dynamic and engaging user interfaces in Vue.

Problem Description

You are tasked with building two custom Vue.js directives in TypeScript:

  1. v-highlight: This directive should change the background color of the element it's applied to when the user hovers their mouse over it. The directive should accept an optional color argument to customize the highlight color. If no color is provided, it should default to a specific color (e.g., yellow).
  2. v-tooltip: This directive should display a tooltip containing specified text when the user hovers their mouse over the element it's applied to. The tooltip text should be passed as the value to the directive. The tooltip should be positioned appropriately relative to the target element.

Key Requirements:

  • Both directives must be implemented using Vue 3's Composition API or Options API with TypeScript.
  • v-highlight:
    • Should change the backgroundColor style on mouseenter.
    • Should revert to the original backgroundColor on mouseleave.
    • Should accept an optional color argument (e.g., v-highlight="'lightblue'").
    • If no argument is provided, it should default to a predefined highlight color (e.g., 'yellow').
  • v-tooltip :
    • Should create and display a tooltip element when the target element is hovered.
    • The tooltip's content should be the value of the directive (e.g., v-tooltip="'This is a tooltip message'").
    • The tooltip should be hidden when the mouse leaves the target element.
    • The tooltip should be visually distinct and positioned above or below the target element.

Expected Behavior:

When the directives are applied to HTML elements in a Vue component, hovering over those elements should trigger the defined behavior (highlighting or tooltip display).

Edge Cases to Consider:

  • Elements that already have a background color defined. The v-highlight directive should correctly restore the original background color.
  • Dynamic updates to the tooltip text. The directive should update the tooltip content if the bound value changes.
  • Multiple directives applied to the same element.

Examples

Example 1: v-highlight

Vue Component:

<template>
  <p v-highlight>This text will be highlighted yellow on hover.</p>
  <p v-highlight="'#90EE90'">This text will be highlighted light green on hover.</p>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
// Assume vHighlight directive is registered globally or locally

export default defineComponent({
  name: 'HighlightExample',
});
</script>

Expected Behavior: When hovering over the first paragraph, its background should turn yellow. When hovering over the second paragraph, its background should turn light green. When the mouse leaves, the original background (or lack thereof) should be restored.

Example 2: v-tooltip

Vue Component:

<template>
  <button v-tooltip="'Click this button to perform an action.'">Hover for Info</button>
  <span v-tooltip="'This is a span with a dynamic tooltip.'">Some Text</span>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
// Assume vTooltip directive is registered globally or locally

export default defineComponent({
  name: 'TooltipExample',
});
</script>

Expected Behavior: Hovering over the button will display a tooltip with the text "Click this button to perform an action.". Hovering over the span will display a tooltip with the text "This is a span with a dynamic tooltip.". The tooltip should disappear when the mouse leaves the element.

Example 3: Combining Directives and Dynamic Tooltip

Vue Component:

<template>
  <div v-highlight="'lightblue'" v-tooltip="tooltipMessage">
    This div has both highlighting and a dynamic tooltip.
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
// Assume vHighlight and vTooltip directives are registered

export default defineComponent({
  name: 'CombinedExample',
  setup() {
    const tooltipMessage = ref('Initial tooltip message.');

    // Simulate dynamic update
    setTimeout(() => {
      tooltipMessage.value = 'The tooltip message has been updated!';
    }, 3000);

    return {
      tooltipMessage,
    };
  },
});
</script>

Expected Behavior: The div will be highlighted light blue on hover. Initially, the tooltip will show "Initial tooltip message.". After 3 seconds, the tooltip content will dynamically update to "The tooltip message has been updated!".

Constraints

  • Your solution must be written in TypeScript.
  • The directives should be implemented as Vue 3 custom directives.
  • For v-tooltip, the tooltip element should be appended to the body to avoid overflow issues within parent containers.
  • Styling for the tooltip (e.g., position, background, padding) should be applied inline or via a CSS class, ensuring it's clearly visible.
  • Performance: The directives should not introduce significant lag or performance degradation, especially when many elements have them applied.
  • No external libraries (other than Vue.js itself) are permitted for the core directive logic.

Notes

  • Consider using the mounted, updated, and unmounted (or beforeUnmount) lifecycle hooks of directives for managing element manipulation and cleanup.
  • For v-tooltip, you'll need to calculate the position of the tooltip based on the target element's position and dimensions.
  • Think about how to store and retrieve the original styles for v-highlight so they can be restored correctly.
  • You can register directives globally or locally within components. For this challenge, consider how you might register them for ease of use in your examples.
  • The exact styling of the tooltip is up to you, but it should be functional and visually distinct.
Loading editor...
typescript