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

css-utilities.mddocs/

CSS Class Utilities

The CSS Class Utilities provide comprehensive tools for managing CSS classes including Tailwind CSS class merging, object/array stringification, and deduplication. These utilities enable dynamic class composition and consistent styling across components.

Capabilities

Class Merging with Tailwind

Advanced CSS class merging that intelligently handles Tailwind CSS class conflicts and deduplication.

/**
 * Merge CSS classes with Tailwind-aware conflict resolution
 * @param cssClasses - Variable number of CSS class inputs
 * @returns Merged and deduplicated class string
 */
function mergeClass(...cssClasses: CssClass[]): string;

type CssClass = string | CssClassObject | CssClassArray;
interface CssClassObject {
  [key: string]: any;
}
type CssClassArray = Array<string | CssClassObject>;

Usage Examples:

import { mergeClass } from "@opentiny/vue-common";

// Merge simple class strings
const classes = mergeClass('btn', 'text-blue-500', 'hover:text-blue-700');
// Result: "btn text-blue-500 hover:text-blue-700"

// Handle Tailwind conflicts (later classes override earlier ones)
const conflictResolved = mergeClass('text-red-500', 'text-blue-500');
// Result: "text-blue-500" (blue overrides red)

// Mix strings, objects, and arrays
const mixed = mergeClass(
  'base-class',
  { 'active': isActive, 'disabled': !enabled },
  ['flex', 'items-center'],
  conditionalClass && 'extra-class'
);

// Responsive classes
const responsive = mergeClass(
  'w-full',
  'sm:w-1/2',
  'md:w-1/3',
  'lg:w-1/4'
);

Class Stringification

Utilities for converting various CSS class formats to strings.

/**
 * Convert CSS classes to string format
 * @param cssClasses - CSS classes in any supported format
 * @returns Stringified CSS classes
 */
function stringifyCssClass(cssClasses: CssClass[] | CssClass): string;

/**
 * Convert CSS class object to string
 * @param cssClassObject - Object with class names as keys and boolean values  
 * @returns Space-separated class string
 */
function stringifyCssClassObject(cssClassObject: CssClassObject): string;

/**
 * Convert CSS class array to string
 * @param cssClassArray - Array of strings and/or objects
 * @returns Space-separated class string
 */
function stringifyCssClassArray(cssClassArray: CssClassArray): string;

Usage Examples:

import { 
  stringifyCssClass,
  stringifyCssClassObject,
  stringifyCssClassArray 
} from "@opentiny/vue-common";

// Object to string conversion
const objectClasses = stringifyCssClassObject({
  'btn': true,
  'btn-primary': isPrimary,
  'btn-disabled': !enabled,
  'btn-large': size === 'large'
});

// Array to string conversion
const arrayClasses = stringifyCssClassArray([
  'flex',
  'items-center',
  { 'justify-between': spaceBetween },
  isVisible && 'opacity-100'
]);

// Mixed formats to string
const mixedClasses = stringifyCssClass([
  'container',
  { 'mx-auto': centered },
  ['px-4', 'py-2'],
  'shadow-md'
]);

Class Deduplication

Remove duplicate CSS classes while preserving order and handling complex class structures.

/**
 * Remove duplicate CSS classes
 * @param cssClasses - CSS classes in any supported format
 * @returns Deduplicated class string
 */
function deduplicateCssClass(cssClasses: CssClass[] | CssClass): string;

Usage Examples:

import { deduplicateCssClass } from "@opentiny/vue-common";

// Remove duplicates from mixed sources
const deduplicated = deduplicateCssClass([
  'btn btn-primary',
  { 'btn': true, 'hover:btn-hover': true },
  ['btn-primary', 'focus:outline-none'],
  'btn btn-primary' // duplicates will be removed
]);
// Result: "btn btn-primary hover:btn-hover focus:outline-none"

// Handle complex nested structures
const complex = deduplicateCssClass([
  'flex items-center',
  { 'flex': true, 'space-x-2': hasSpacing },
  ['items-center', 'justify-center'],
  spaced && 'space-x-2'
]);

Advanced Usage Patterns

Conditional Class Application

Patterns for applying classes based on component state and props.

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

export default {
  setup(props) {
    // Computed classes based on props
    const containerClasses = hooks.computed(() => mergeClass(
      'component-base',
      {
        'component-primary': props.type === 'primary',
        'component-secondary': props.type === 'secondary',
        'component-disabled': props.disabled,
        'component-loading': props.loading
      },
      props.size === 'small' && 'component-sm',
      props.size === 'large' && 'component-lg',
      props.customClass
    ));
    
    // Responsive classes
    const responsiveClasses = hooks.computed(() => mergeClass(
      'w-full',
      'sm:w-1/2 sm:max-w-md',
      'md:w-1/3 md:max-w-lg',
      'lg:w-1/4 lg:max-w-xl'
    ));
    
    return {
      containerClasses,
      responsiveClasses
    };
  }
};

Theme-Based Class Management

Integration with theme systems for dynamic styling.

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

export default {
  setup(props) {
    const theme = hooks.inject('theme', 'light');
    
    const themeClasses = hooks.computed(() => {
      const baseClasses = 'transition-colors duration-200';
      
      const themeMap = {
        light: 'bg-white text-gray-900 border-gray-200',
        dark: 'bg-gray-900 text-white border-gray-700',
        auto: 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white'
      };
      
      return mergeClass(
        baseClasses,
        themeMap[theme.value] || themeMap.light,
        props.variant === 'outlined' && 'border-2',
        props.variant === 'filled' && 'shadow-md'
      );
    });
    
    return {
      themeClasses
    };
  }
};

Form Control Class Patterns

Common patterns for form controls with validation states.

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

export default {
  setup(props) {
    const inputClasses = hooks.computed(() => mergeClass(
      // Base styles
      'block w-full rounded-md border-0 py-1.5 px-3',
      'text-gray-900 shadow-sm ring-1 ring-inset',
      'placeholder:text-gray-400 focus:ring-2 focus:ring-inset',
      'sm:text-sm sm:leading-6',
      
      // Size variants
      {
        'py-1 px-2 text-xs': props.size === 'small',
        'py-2 px-4 text-base': props.size === 'large'
      },
      
      // State-based styles
      {
        'ring-gray-300 focus:ring-indigo-600': !props.error && !props.success,
        'ring-red-300 focus:ring-red-600': props.error,
        'ring-green-300 focus:ring-green-600': props.success,
        'bg-gray-50 cursor-not-allowed': props.disabled
      }
    ));
    
    const labelClasses = hooks.computed(() => mergeClass(
      'block text-sm font-medium leading-6',
      {
        'text-gray-900': !props.error,
        'text-red-600': props.error,
        'text-green-600': props.success
      }
    ));
    
    return {
      inputClasses,
      labelClasses
    };
  }
};

Integration with Design Systems

Custom Design Tokens

Integration with custom design token systems.

import { mergeClass, customDesignConfig } from "@opentiny/vue-common";

// Configure custom design system
customDesignConfig.designConfig = {
  tokens: {
    colors: {
      primary: 'blue-600',
      secondary: 'gray-600'
    },
    spacing: {
      small: '0.5rem',
      medium: '1rem', 
      large: '2rem'
    }
  }
};

// Use design tokens in components
export default {
  setup(props) {
    const buttonClasses = hooks.computed(() => mergeClass(
      'inline-flex items-center justify-center',
      'rounded-md font-medium transition-colors',
      
      // Use design tokens
      props.variant === 'primary' && `bg-${customDesignConfig.designConfig.tokens.colors.primary}`,
      props.size === 'small' && `px-3 py-1.5 text-sm`,
      props.size === 'medium' && `px-4 py-2 text-sm`,
      props.size === 'large' && `px-6 py-3 text-base`
    ));
    
    return {
      buttonClasses
    };
  }
};

Performance Considerations

The CSS utilities are optimized for performance:

  • Lazy Evaluation: Class strings are only computed when needed
  • Memoization: Repeated class combinations are cached when used in computed properties
  • Efficient Deduplication: Uses Set-based deduplication for optimal performance
  • Memory Management: No memory leaks from class string accumulation

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