Cross-framework compatibility utilities and adapters for building Vue components that work seamlessly across Vue 2, Vue 2.7, and Vue 3
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Theme and Mode Resolution system provides dynamic theme switching and responsive mode detection for components. It supports multiple themes ('tiny', 'saas') and responsive modes ('pc', 'mobile', 'mobile-first') with hierarchical resolution from props, injection, and global configuration.
Automatic detection and resolution of component display modes based on device characteristics and user preferences.
/**
* Resolve component display mode from various sources
* @param props - Component props object
* @param context - Component context
* @returns Resolved mode string
*/
function resolveMode(props: any, context: any): 'pc' | 'mobile' | 'mobile-first';Mode Types:
'pc' - Desktop/PC optimized layout and interactions'mobile' - Mobile-specific layout with touch optimizations'mobile-first' - Mobile-first responsive design approachResolution Priority:
props.tiny_mode - Component-level propTinyMode - Parent component injection'pc'Usage Examples:
import { resolveMode, hooks } from "@opentiny/vue-common";
export default {
props: {
tiny_mode: String,
tiny_mode_root: Boolean
},
setup(props, context) {
// Resolve current mode
const currentMode = resolveMode(props, context);
// Mode-based component behavior
const componentConfig = hooks.computed(() => {
switch (currentMode) {
case 'mobile':
return {
itemSize: 'large',
touchOptimized: true,
gestureEnabled: true
};
case 'mobile-first':
return {
responsive: true,
breakpointBased: true,
adaptiveLayout: true
};
default: // 'pc'
return {
itemSize: 'medium',
hoverEffects: true,
keyboardNavigation: true
};
}
});
return {
currentMode,
componentConfig
};
}
};Dynamic theme switching supporting multiple design systems and theme variants.
/**
* Resolve component theme from various sources
* @param props - Component props object
* @param context - Component context
* @returns Resolved theme string
*/
function resolveTheme(props: any, context: any): 'tiny' | 'saas';Theme Types:
'tiny' - Default TinyVue theme with enterprise styling'saas' - SaaS-optimized theme with modern design patternsResolution Priority:
props.tiny_theme - Component-level propTinyTheme - Parent component injection'tiny'Usage Examples:
import { resolveTheme, hooks } from "@opentiny/vue-common";
export default {
props: {
tiny_theme: String
},
setup(props, context) {
// Resolve current theme
const currentTheme = resolveTheme(props, context);
// Theme-based styling
const themeClasses = hooks.computed(() => {
const baseClasses = 'component-base';
const themeStyles = {
tiny: 'tiny-theme border-gray-300 shadow-sm',
saas: 'saas-theme border-blue-200 shadow-md rounded-lg'
};
return `${baseClasses} ${themeStyles[currentTheme]}`;
});
// Theme-specific configuration
const themeConfig = hooks.computed(() => {
switch (currentTheme) {
case 'saas':
return {
borderRadius: '8px',
shadowLevel: 'medium',
colorScheme: 'modern',
animations: true
};
default: // 'tiny'
return {
borderRadius: '4px',
shadowLevel: 'subtle',
colorScheme: 'enterprise',
animations: false
};
}
});
return {
currentTheme,
themeClasses,
themeConfig
};
}
};Specialized theme resolution for chart and data visualization components.
/**
* Resolve chart theme configuration (internal function)
* @param props - Component props object
* @param context - Component context
* @returns Chart theme configuration object or null
*/
// resolveChartTheme(props: any, context: any): any | null;Usage Examples:
import { setup } from "@opentiny/vue-common";
export default {
props: {
tiny_chart_theme: Object
},
setup(props, context) {
return setup({
props,
context,
renderless: (props, hooks, utils) => {
// Chart theme is automatically resolved and available in utils.vm.chartTheme
const chartTheme = utils.vm.chartTheme;
const chartConfig = hooks.computed(() => ({
theme: chartTheme || {
backgroundColor: '#ffffff',
textColor: '#333333',
lineColor: '#e0e0e0'
}
}));
return {
chartConfig
};
},
api: ['chartConfig']
});
}
};Application-level mode configuration for consistent behavior across components.
Setting Global Mode:
import { createApp } from 'vue';
import { hooks } from "@opentiny/vue-common";
const app = createApp({});
// Set global mode configuration
app.config.globalProperties.tiny_mode = 'mobile-first';
// Or use provide/inject
app.provide('TinyMode', 'mobile-first');Root Mode Provider:
import { resolveMode } from "@opentiny/vue-common";
export default {
props: {
tiny_mode_root: Boolean,
tiny_mode: String
},
setup(props, context) {
// This component will provide mode to all children
const mode = resolveMode(props, context);
// Mode is automatically provided when tiny_mode_root is true
return {
mode
};
}
};Application-level theme configuration and switching.
Setting Global Theme:
import { createApp } from 'vue';
const app = createApp({});
// Global theme configuration
app.config.globalProperties.tiny_theme = { value: 'saas' };
// Or use provide/inject
app.provide('TinyTheme', 'saas');Dynamic Theme Switching:
import { hooks } from "@opentiny/vue-common";
export default {
setup() {
const globalTheme = hooks.ref('tiny');
const switchTheme = (newTheme) => {
globalTheme.value = newTheme;
// Update global configuration
app.config.globalProperties.tiny_theme = { value: newTheme };
};
// Provide theme to child components
hooks.provide('TinyTheme', globalTheme);
return {
globalTheme,
switchTheme
};
}
};Component that adapts to multiple theme systems.
import { resolveTheme, resolveMode, hooks } from "@opentiny/vue-common";
export default {
props: {
tiny_theme: String,
tiny_mode: String
},
setup(props, context) {
const theme = resolveTheme(props, context);
const mode = resolveMode(props, context);
// Combined theme and mode styling
const adaptiveClasses = hooks.computed(() => {
const base = 'adaptive-component';
// Theme-based classes
const themeClass = theme === 'saas' ? 'saas-styling' : 'tiny-styling';
// Mode-based classes
const modeClasses = {
'pc': 'desktop-layout hover-effects',
'mobile': 'mobile-layout touch-friendly',
'mobile-first': 'responsive-layout adaptive-spacing'
};
return `${base} ${themeClass} ${modeClasses[mode]}`;
});
// Theme and mode specific configuration
const componentConfig = hooks.computed(() => ({
// Layout configuration
layout: mode === 'mobile' ? 'vertical' : 'horizontal',
spacing: mode === 'mobile' ? 'compact' : 'comfortable',
// Visual configuration
borderRadius: theme === 'saas' ? '8px' : '4px',
elevation: theme === 'saas' ? 2 : 1,
// Interaction configuration
hoverEffects: mode === 'pc' && theme === 'saas',
touchOptimized: mode !== 'pc',
animations: theme === 'saas'
}));
return {
theme,
mode,
adaptiveClasses,
componentConfig
};
}
};Component that manages theme context for child components.
import { resolveTheme, hooks } from "@opentiny/vue-common";
export default {
props: {
tiny_theme: String,
themeOverride: Object
},
setup(props, context) {
const baseTheme = resolveTheme(props, context);
// Create enhanced theme context
const themeContext = hooks.computed(() => ({
name: baseTheme,
tokens: {
...getThemeTokens(baseTheme),
...props.themeOverride
},
utilities: {
getColor: (colorKey) => getThemeTokens(baseTheme).colors[colorKey],
getSpacing: (spaceKey) => getThemeTokens(baseTheme).spacing[spaceKey],
getComponent: (componentName) => getThemeTokens(baseTheme).components[componentName]
}
}));
// Provide enhanced theme context
hooks.provide('EnhancedTheme', themeContext);
return {
themeContext
};
}
};
function getThemeTokens(theme) {
const tokens = {
tiny: {
colors: { primary: '#1890ff', secondary: '#666666' },
spacing: { small: '8px', medium: '16px', large: '24px' },
components: { button: { height: '32px', padding: '4px 15px' } }
},
saas: {
colors: { primary: '#4f46e5', secondary: '#6b7280' },
spacing: { small: '6px', medium: '12px', large: '20px' },
components: { button: { height: '36px', padding: '8px 16px' } }
}
};
return tokens[theme] || tokens.tiny;
}The theme and mode resolution is automatically integrated with the component setup system:
import { setup } from "@opentiny/vue-common";
export default {
setup(props, context) {
return setup({
props,
context,
renderless: (props, hooks, utils) => {
// Theme and mode are automatically available in utils.vm
const theme = utils.vm.theme; // Result of resolveTheme()
const chartTheme = utils.vm.chartTheme; // Result of resolveChartTheme()
// Mode is available through utils.mode
return {
// Component logic using resolved theme and mode
};
},
api: []
});
}
};Install with Tessl CLI
npx tessl i tessl/npm-opentiny--vue-common