CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-opentiny--vue-common

Cross-framework compatibility utilities and adapters for building Vue components that work seamlessly across Vue 2, Vue 2.7, and Vue 3

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

breakpoints.mddocs/

Responsive Breakpoints

The Responsive Breakpoints system provides reactive breakpoint detection based on Tailwind CSS breakpoint specifications. It enables components to respond dynamically to viewport size changes using a hook-based API.

Capabilities

Breakpoint Detection Hook

Creates a reactive breakpoint detection system that monitors viewport size and updates components accordingly.

/**
 * Create reactive breakpoint detection hook
 * @returns Object with current breakpoint state
 */
function useBreakpoint(): {
  /** Current active breakpoint (reactive) */
  current: Ref<'2xl' | 'xl' | 'lg' | 'md' | 'sm' | 'default'>;
};

Breakpoint Definitions:

  • '2xl' - Screens 1536px and wider
  • 'xl' - Screens 1280px and wider (but less than 1536px)
  • 'lg' - Screens 1024px and wider (but less than 1280px)
  • 'md' - Screens 768px and wider (but less than 1024px)
  • 'sm' - Screens 640px and wider (but less than 768px)
  • 'default' - Screens less than 640px wide

Usage Examples:

import { useBreakpoint, hooks } from "@opentiny/vue-common";

export default {
  setup() {
    const breakpoint = useBreakpoint();
    
    // Watch for breakpoint changes
    hooks.watch(breakpoint.current, (current, previous) => {
      console.log(`Breakpoint changed from ${previous} to ${current}`);
    });
    
    // Computed properties based on breakpoint
    const isMobile = hooks.computed(() => {
      return breakpoint.current.value === 'default' || 
             breakpoint.current.value === 'sm';
    });
    
    const isDesktop = hooks.computed(() => {
      return ['lg', 'xl', '2xl'].includes(breakpoint.current.value);
    });
    
    // Conditional rendering based on breakpoint
    const columns = hooks.computed(() => {
      switch (breakpoint.current.value) {
        case '2xl': return 6;
        case 'xl': return 4;
        case 'lg': return 3;
        case 'md': return 2;
        default: return 1;
      }
    });
    
    return {
      breakpoint,
      isMobile,
      isDesktop,
      columns
    };
  }
};

Server-Side Rendering Support

The breakpoint system includes built-in SSR support with safe fallbacks for server environments.

SSR Behavior:

  • Returns false for all matches properties during server-side rendering
  • Provides no-op event listeners to prevent errors
  • Defaults to 'default' breakpoint on server
  • Automatically updates to correct breakpoint after hydration

Usage in SSR:

import { useBreakpoint, hooks } from "@opentiny/vue-common";

export default {
  setup() {
    const breakpoint = useBreakpoint();
    const isHydrated = hooks.ref(false);
    
    hooks.onMounted(() => {
      isHydrated.value = true;
    });
    
    // Safe breakpoint usage that works with SSR
    const safeBreakpoint = hooks.computed(() => {
      if (!isHydrated.value) {
        return 'default'; // Safe fallback for SSR
      }
      return breakpoint.current.value;
    });
    
    return {
      safeBreakpoint
    };
  }
};

Component Responsive Patterns

Common patterns for using breakpoints in component development.

Responsive Component Layout:

import { useBreakpoint, hooks } from "@opentiny/vue-common";

export default {
  setup() {
    const breakpoint = useBreakpoint();
    
    // Responsive grid system
    const gridCols = hooks.computed(() => {
      const breakpointMap = {
        'default': 'grid-cols-1',
        'sm': 'grid-cols-2',
        'md': 'grid-cols-3',
        'lg': 'grid-cols-4',
        'xl': 'grid-cols-5',
        '2xl': 'grid-cols-6'
      };
      return breakpointMap[breakpoint.current.value];
    });
    
    // Responsive spacing
    const spacing = hooks.computed(() => {
      const isMobile = ['default', 'sm'].includes(breakpoint.current.value);
      return isMobile ? 'p-4 gap-2' : 'p-8 gap-4';
    });
    
    // Responsive typography
    const textSize = hooks.computed(() => {
      const sizeMap = {
        'default': 'text-sm',
        'sm': 'text-base',
        'md': 'text-lg',
        'lg': 'text-xl',
        'xl': 'text-2xl',
        '2xl': 'text-3xl'
      };
      return sizeMap[breakpoint.current.value];
    });
    
    return {
      gridCols,
      spacing,
      textSize
    };
  }
};

Responsive Navigation:

import { useBreakpoint, hooks } from "@opentiny/vue-common";

export default {
  setup() {
    const breakpoint = useBreakpoint();
    
    const navigationStyle = hooks.computed(() => {
      const isMobile = ['default', 'sm'].includes(breakpoint.current.value);
      
      if (isMobile) {
        return {
          type: 'drawer',
          position: 'bottom',
          showLabels: false
        };
      }
      
      return {
        type: 'horizontal',
        position: 'top',
        showLabels: true
      };
    });
    
    const showSidebar = hooks.computed(() => {
      return ['lg', 'xl', '2xl'].includes(breakpoint.current.value);
    });
    
    return {
      navigationStyle,
      showSidebar
    };
  }
};

Performance Considerations

The breakpoint system is optimized for performance with several built-in optimizations:

Debounced Updates:

  • Uses debounced event listeners to prevent excessive updates during window resizing
  • Default debounce delay is 0ms (next tick) for immediate response

Memory Management:

  • Automatically removes event listeners when components unmount
  • Uses onBeforeUnmount hook for cleanup

Efficient Matching:

  • Evaluates breakpoints in descending order (largest to smallest)
  • Stops evaluation at first match for optimal performance

Browser Compatibility:

  • Falls back gracefully when window.matchMedia is not available
  • Provides consistent API across all supported environments

Media Query Integration

The system uses native CSS media queries through the window.matchMedia API:

// Internal media query definitions (for reference)
const mediaQueries = {
  '2xl': '(min-width:1536px)',
  'xl': '(min-width:1280px)', 
  'lg': '(min-width:1024px)',
  'md': '(min-width:768px)',
  'sm': '(min-width:640px)'
};

This ensures consistency with Tailwind CSS breakpoints and provides native browser performance.

Install with Tessl CLI

npx tessl i tessl/npm-opentiny--vue-common

docs

adapter.md

breakpoints.md

composition-hooks.md

css-utilities.md

design-system.md

index.md

setup.md

svg-icons.md

theme-mode.md

tile.json