vlibras-player-webjs
Version:
Biblioteca JavaScript moderna para integração do VLibras Player com React, Vue, Angular e vanilla JS
516 lines (499 loc) • 16.6 kB
JavaScript
;
/**
* Sistema de Temas Integrado para VLibras
* Permite personalização visual completa da interface
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.VLibrasThemes = exports.vlibrasThemeManager = exports.VLibrasThemeManager = exports.compactTheme = exports.highContrastTheme = exports.darkTheme = exports.lightTheme = void 0;
const VLibrasGlobalConfig_1 = require("../../core/config/VLibrasGlobalConfig");
/**
* Tema claro padrão
*/
exports.lightTheme = {
name: 'light',
displayName: 'Claro',
description: 'Tema claro padrão com alta legibilidade',
colors: {
primary: '#2563eb',
secondary: '#64748b',
background: '#ffffff',
surface: '#f8fafc',
error: '#dc2626',
success: '#16a34a',
warning: '#d97706',
info: '#0284c7',
text: '#1e293b',
textSecondary: '#64748b',
border: '#e2e8f0',
shadow: 'rgba(0, 0, 0, 0.1)'
},
spacing: {
xs: '0.25rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem'
},
typography: {
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
md: '1rem',
lg: '1.125rem',
xl: '1.25rem'
},
fontWeight: {
light: 300,
normal: 400,
medium: 500,
bold: 700
},
lineHeight: {
tight: 1.25,
normal: 1.5,
relaxed: 1.75
}
},
borderRadius: {
none: '0',
sm: '0.25rem',
md: '0.5rem',
lg: '0.75rem',
full: '9999px'
},
shadows: {
none: 'none',
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)'
},
animation: {
duration: {
fast: '150ms',
normal: '300ms',
slow: '500ms'
},
easing: {
ease: 'ease',
easeIn: 'ease-in',
easeOut: 'ease-out',
easeInOut: 'ease-in-out'
}
},
vlibras: {
playerBackground: '#ffffff',
controlsBackground: '#f8fafc',
progressBarColor: '#2563eb',
loadingSpinnerColor: '#2563eb',
errorColor: '#dc2626',
successColor: '#16a34a'
}
};
/**
* Tema escuro
*/
exports.darkTheme = {
...exports.lightTheme,
name: 'dark',
displayName: 'Escuro',
description: 'Tema escuro para reduzir fadiga visual',
colors: {
primary: '#3b82f6',
secondary: '#94a3b8',
background: '#0f172a',
surface: '#1e293b',
error: '#ef4444',
success: '#22c55e',
warning: '#f59e0b',
info: '#06b6d4',
text: '#f1f5f9',
textSecondary: '#94a3b8',
border: '#334155',
shadow: 'rgba(0, 0, 0, 0.25)'
},
vlibras: {
playerBackground: '#1e293b',
controlsBackground: '#0f172a',
progressBarColor: '#3b82f6',
loadingSpinnerColor: '#3b82f6',
errorColor: '#ef4444',
successColor: '#22c55e'
}
};
/**
* Tema de alto contraste
*/
exports.highContrastTheme = {
...exports.lightTheme,
name: 'high-contrast',
displayName: 'Alto Contraste',
description: 'Tema com alto contraste para acessibilidade',
colors: {
primary: '#000000',
secondary: '#333333',
background: '#ffffff',
surface: '#f0f0f0',
error: '#cc0000',
success: '#008800',
warning: '#ff8800',
info: '#0066cc',
text: '#000000',
textSecondary: '#333333',
border: '#000000',
shadow: 'rgba(0, 0, 0, 0.5)'
},
vlibras: {
playerBackground: '#ffffff',
controlsBackground: '#f0f0f0',
progressBarColor: '#000000',
loadingSpinnerColor: '#000000',
errorColor: '#cc0000',
successColor: '#008800'
}
};
/**
* Tema compacto para espaços reduzidos
*/
exports.compactTheme = {
...exports.lightTheme,
name: 'compact',
displayName: 'Compacto',
description: 'Tema otimizado para espaços reduzidos',
spacing: {
xs: '0.125rem',
sm: '0.25rem',
md: '0.5rem',
lg: '0.75rem',
xl: '1rem'
},
typography: {
...exports.lightTheme.typography,
fontSize: {
xs: '0.625rem',
sm: '0.75rem',
md: '0.875rem',
lg: '1rem',
xl: '1.125rem'
}
},
borderRadius: {
none: '0',
sm: '0.125rem',
md: '0.25rem',
lg: '0.375rem',
full: '9999px'
}
};
/**
* Gerenciador de temas do VLibras
*/
class VLibrasThemeManager {
constructor() {
this.themes = new Map();
this.currentTheme = exports.lightTheme;
this.styleElement = null;
// Registrar temas padrão
this.registerTheme(exports.lightTheme);
this.registerTheme(exports.darkTheme);
this.registerTheme(exports.highContrastTheme);
this.registerTheme(exports.compactTheme);
// Auto-detectar preferência do sistema
this.detectSystemPreference();
}
static getInstance() {
if (!VLibrasThemeManager.instance) {
VLibrasThemeManager.instance = new VLibrasThemeManager();
}
return VLibrasThemeManager.instance;
}
/**
* Registra um novo tema
*/
registerTheme(theme) {
this.themes.set(theme.name, theme);
console.log(`🎨 Tema '${theme.displayName}' registrado`);
}
/**
* Lista todos os temas disponíveis
*/
getAvailableThemes() {
return Array.from(this.themes.values());
}
/**
* Obtém um tema por nome
*/
getTheme(name) {
return this.themes.get(name);
}
/**
* Obtém o tema atual
*/
getCurrentTheme() {
return this.currentTheme;
}
/**
* Aplica um tema
*/
applyTheme(themeName) {
const theme = this.themes.get(themeName);
if (!theme) {
console.error(`Tema '${themeName}' não encontrado`);
return;
}
this.currentTheme = theme;
this.injectCSS(theme);
// Salvar preferência
if (['light', 'dark', 'high-contrast', 'auto'].includes(themeName)) {
VLibrasGlobalConfig_1.VLibrasGlobalConfig.configure({ theme: themeName });
}
localStorage.setItem('vlibras-theme', themeName);
// Emitir evento
document.dispatchEvent(new CustomEvent('vlibras:theme-changed', {
detail: { theme }
}));
console.log(`🎨 Tema '${theme.displayName}' aplicado`);
}
/**
* Auto-detecta preferência do sistema
*/
detectSystemPreference() {
// Verificar se estamos em ambiente browser
if (typeof window === 'undefined' || !window.matchMedia) {
// Em ambiente servidor/Node.js, usar tema light como padrão
return;
}
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
this.applyTheme('dark');
}
else {
this.applyTheme('light');
}
// Detectar preferência de alto contraste
if (window.matchMedia('(prefers-contrast: high)').matches) {
this.applyTheme('high-contrast');
}
// Detectar preferência reduzida de movimento
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
this.updateAnimations(false);
}
// Escutar mudanças nas preferências
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (e.matches) {
this.applyTheme('dark');
}
else {
this.applyTheme('light');
}
});
}
/**
* Injeta CSS do tema no documento
*/
injectCSS(theme) {
// Remover estilo anterior
if (this.styleElement) {
this.styleElement.remove();
}
// Criar novo elemento de estilo
this.styleElement = document.createElement('style');
this.styleElement.id = 'vlibras-theme';
const css = this.generateCSS(theme);
this.styleElement.textContent = css;
document.head.appendChild(this.styleElement);
}
/**
* Gera CSS a partir do tema
*/
generateCSS(theme) {
return `
:root {
/* Cores */
--vlibras-primary: ${theme.colors.primary};
--vlibras-secondary: ${theme.colors.secondary};
--vlibras-background: ${theme.colors.background};
--vlibras-surface: ${theme.colors.surface};
--vlibras-error: ${theme.colors.error};
--vlibras-success: ${theme.colors.success};
--vlibras-warning: ${theme.colors.warning};
--vlibras-info: ${theme.colors.info};
--vlibras-text: ${theme.colors.text};
--vlibras-text-secondary: ${theme.colors.textSecondary};
--vlibras-border: ${theme.colors.border};
--vlibras-shadow: ${theme.colors.shadow};
/* Espaçamentos */
--vlibras-spacing-xs: ${theme.spacing.xs};
--vlibras-spacing-sm: ${theme.spacing.sm};
--vlibras-spacing-md: ${theme.spacing.md};
--vlibras-spacing-lg: ${theme.spacing.lg};
--vlibras-spacing-xl: ${theme.spacing.xl};
/* Tipografia */
--vlibras-font-family: ${theme.typography.fontFamily};
--vlibras-font-size-xs: ${theme.typography.fontSize.xs};
--vlibras-font-size-sm: ${theme.typography.fontSize.sm};
--vlibras-font-size-md: ${theme.typography.fontSize.md};
--vlibras-font-size-lg: ${theme.typography.fontSize.lg};
--vlibras-font-size-xl: ${theme.typography.fontSize.xl};
/* Border radius */
--vlibras-radius-none: ${theme.borderRadius.none};
--vlibras-radius-sm: ${theme.borderRadius.sm};
--vlibras-radius-md: ${theme.borderRadius.md};
--vlibras-radius-lg: ${theme.borderRadius.lg};
--vlibras-radius-full: ${theme.borderRadius.full};
/* Sombras */
--vlibras-shadow-none: ${theme.shadows.none};
--vlibras-shadow-sm: ${theme.shadows.sm};
--vlibras-shadow-md: ${theme.shadows.md};
--vlibras-shadow-lg: ${theme.shadows.lg};
--vlibras-shadow-xl: ${theme.shadows.xl};
/* Animações */
--vlibras-duration-fast: ${theme.animation.duration.fast};
--vlibras-duration-normal: ${theme.animation.duration.normal};
--vlibras-duration-slow: ${theme.animation.duration.slow};
/* VLibras específico */
--vlibras-player-bg: ${theme.vlibras.playerBackground};
--vlibras-controls-bg: ${theme.vlibras.controlsBackground};
--vlibras-progress-color: ${theme.vlibras.progressBarColor};
--vlibras-loading-color: ${theme.vlibras.loadingSpinnerColor};
--vlibras-error-color: ${theme.vlibras.errorColor};
--vlibras-success-color: ${theme.vlibras.successColor};
}
.vlibras-player {
font-family: var(--vlibras-font-family);
background-color: var(--vlibras-player-bg);
color: var(--vlibras-text);
border: 1px solid var(--vlibras-border);
border-radius: var(--vlibras-radius-md);
box-shadow: var(--vlibras-shadow-md);
}
.vlibras-controls {
background-color: var(--vlibras-controls-bg);
border-top: 1px solid var(--vlibras-border);
padding: var(--vlibras-spacing-sm);
border-radius: 0 0 var(--vlibras-radius-md) var(--vlibras-radius-md);
}
.vlibras-button {
background-color: var(--vlibras-primary);
color: white;
border: none;
padding: var(--vlibras-spacing-sm) var(--vlibras-spacing-md);
border-radius: var(--vlibras-radius-sm);
font-size: var(--vlibras-font-size-sm);
cursor: pointer;
transition: background-color var(--vlibras-duration-normal);
}
.vlibras-button:hover {
background-color: color-mix(in srgb, var(--vlibras-primary) 80%, black);
}
.vlibras-button:disabled {
background-color: var(--vlibras-secondary);
cursor: not-allowed;
opacity: 0.6;
}
.vlibras-progress {
width: 100%;
height: 4px;
background-color: var(--vlibras-border);
border-radius: var(--vlibras-radius-full);
overflow: hidden;
}
.vlibras-progress-bar {
height: 100%;
background-color: var(--vlibras-progress-color);
transition: width var(--vlibras-duration-normal);
}
.vlibras-loading {
display: flex;
align-items: center;
justify-content: center;
color: var(--vlibras-loading-color);
padding: var(--vlibras-spacing-lg);
}
.vlibras-error {
color: var(--vlibras-error-color);
background-color: color-mix(in srgb, var(--vlibras-error-color) 10%, transparent);
border: 1px solid var(--vlibras-error-color);
border-radius: var(--vlibras-radius-sm);
padding: var(--vlibras-spacing-md);
}
.vlibras-success {
color: var(--vlibras-success-color);
background-color: color-mix(in srgb, var(--vlibras-success-color) 10%, transparent);
border: 1px solid var(--vlibras-success-color);
border-radius: var(--vlibras-radius-sm);
padding: var(--vlibras-spacing-md);
}
@media (prefers-reduced-motion: reduce) {
.vlibras-player * {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
`;
}
/**
* Atualiza configurações de animação
*/
updateAnimations(enabled) {
document.documentElement.style.setProperty('--vlibras-animations-enabled', enabled ? '1' : '0');
}
/**
* Cria um tema personalizado
*/
createCustomTheme(baseTheme, customizations) {
const base = this.themes.get(baseTheme);
if (!base) {
throw new Error(`Tema base '${baseTheme}' não encontrado`);
}
const customTheme = {
...base,
...customizations,
name: customizations.name || `custom-${Date.now()}`,
colors: { ...base.colors, ...customizations.colors },
spacing: { ...base.spacing, ...customizations.spacing },
typography: {
...base.typography,
...customizations.typography,
fontSize: { ...base.typography.fontSize, ...customizations.typography?.fontSize }
},
vlibras: { ...base.vlibras, ...customizations.vlibras }
};
this.registerTheme(customTheme);
return customTheme;
}
/**
* Remove um tema customizado
*/
removeTheme(themeName) {
if (['light', 'dark', 'high-contrast', 'compact'].includes(themeName)) {
console.warn('Não é possível remover temas padrão');
return;
}
this.themes.delete(themeName);
console.log(`🗑️ Tema '${themeName}' removido`);
}
}
exports.VLibrasThemeManager = VLibrasThemeManager;
VLibrasThemeManager.instance = null;
/**
* Instância singleton do gerenciador de temas
*/
exports.vlibrasThemeManager = VLibrasThemeManager.getInstance();
/**
* API simplificada para uso direto
*/
exports.VLibrasThemes = {
apply: (themeName) => exports.vlibrasThemeManager.applyTheme(themeName),
get current() { return exports.vlibrasThemeManager.getCurrentTheme(); },
get available() { return exports.vlibrasThemeManager.getAvailableThemes(); },
register: (theme) => exports.vlibrasThemeManager.registerTheme(theme),
createCustom: (baseTheme, customizations) => exports.vlibrasThemeManager.createCustomTheme(baseTheme, customizations),
// Temas pré-definidos
light: exports.lightTheme,
dark: exports.darkTheme,
highContrast: exports.highContrastTheme,
compact: exports.compactTheme
};
//# sourceMappingURL=VLibrasThemes.js.map