Spaces:
Sleeping
Sleeping
| """ | |
| Sistema de temas e personalizacao da UI. | |
| Suporta: | |
| - Dark mode | |
| - Custom CSS | |
| - Keyboard shortcuts | |
| """ | |
| import gradio as gr | |
| # CSS Customizado | |
| LIGHT_MODE_CSS = """ | |
| /* Light Mode */ | |
| :root { | |
| --primary-color: #1f77b4; | |
| --secondary-color: #ff7f0e; | |
| --background-color: #ffffff; | |
| --surface-color: #f5f5f5; | |
| --text-color: #333333; | |
| --border-color: #e0e0e0; | |
| } | |
| .gradio-container { | |
| background-color: var(--background-color); | |
| color: var(--text-color); | |
| } | |
| .tab-nav { | |
| background-color: var(--surface-color); | |
| border-bottom: 2px solid var(--primary-color); | |
| } | |
| .primary-btn { | |
| background-color: var(--primary-color) !important; | |
| color: white !important; | |
| border: none !important; | |
| } | |
| .secondary-btn { | |
| background-color: var(--secondary-color) !important; | |
| color: white !important; | |
| border: none !important; | |
| } | |
| .code-block { | |
| background-color: #f8f8f8; | |
| border: 1px solid var(--border-color); | |
| border-radius: 4px; | |
| padding: 10px; | |
| font-family: monospace; | |
| } | |
| """ | |
| DARK_MODE_CSS = """ | |
| /* Dark Mode */ | |
| :root { | |
| --primary-color: #4a9eff; | |
| --secondary-color: #ffa94d; | |
| --background-color: #1a1a1a; | |
| --surface-color: #2d2d2d; | |
| --text-color: #e0e0e0; | |
| --border-color: #404040; | |
| } | |
| body { | |
| background-color: var(--background-color) !important; | |
| color: var(--text-color) !important; | |
| } | |
| .gradio-container { | |
| background-color: var(--background-color) !important; | |
| color: var(--text-color) !important; | |
| } | |
| .tab-nav { | |
| background-color: var(--surface-color) !important; | |
| border-bottom: 2px solid var(--primary-color) !important; | |
| } | |
| .tab-nav button { | |
| color: var(--text-color) !important; | |
| } | |
| .tab-nav button.selected { | |
| background-color: var(--primary-color) !important; | |
| color: white !important; | |
| } | |
| input, textarea, select { | |
| background-color: var(--surface-color) !important; | |
| color: var(--text-color) !important; | |
| border: 1px solid var(--border-color) !important; | |
| } | |
| .markdown-text { | |
| color: var(--text-color) !important; | |
| } | |
| .primary-btn { | |
| background-color: var(--primary-color) !important; | |
| color: white !important; | |
| border: none !important; | |
| } | |
| .secondary-btn { | |
| background-color: var(--secondary-color) !important; | |
| color: #1a1a1a !important; | |
| border: none !important; | |
| } | |
| .code-block { | |
| background-color: #1e1e1e !important; | |
| border: 1px solid var(--border-color) !important; | |
| border-radius: 4px; | |
| padding: 10px; | |
| font-family: monospace; | |
| color: #d4d4d4 !important; | |
| } | |
| .warning { | |
| background-color: #332200 !important; | |
| border-left: 4px solid var(--secondary-color) !important; | |
| padding: 10px; | |
| margin: 10px 0; | |
| } | |
| .info { | |
| background-color: #002233 !important; | |
| border-left: 4px solid var(--primary-color) !important; | |
| padding: 10px; | |
| margin: 10px 0; | |
| } | |
| /* Scrollbars dark mode */ | |
| ::-webkit-scrollbar { | |
| width: 10px; | |
| height: 10px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: var(--surface-color); | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: var(--border-color); | |
| border-radius: 5px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: var(--primary-color); | |
| } | |
| """ | |
| # JavaScript para keyboard shortcuts | |
| KEYBOARD_SHORTCUTS_JS = """ | |
| function setupKeyboardShortcuts() { | |
| document.addEventListener('keydown', function(e) { | |
| // Ctrl/Cmd + K - Focus search | |
| if ((e.ctrlKey || e.metaKey) && e.key === 'k') { | |
| e.preventDefault(); | |
| const searchInput = document.querySelector('input[placeholder*="query"], input[placeholder*="pergunta"]'); | |
| if (searchInput) { | |
| searchInput.focus(); | |
| } | |
| } | |
| // Ctrl/Cmd + Enter - Submit form | |
| if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { | |
| const submitBtn = document.querySelector('button.primary-btn'); | |
| if (submitBtn) { | |
| submitBtn.click(); | |
| } | |
| } | |
| // Ctrl/Cmd + / - Show shortcuts help | |
| if ((e.ctrlKey || e.metaKey) && e.key === '/') { | |
| e.preventDefault(); | |
| alert( | |
| 'Atalhos de Teclado:\\n\\n' + | |
| 'Ctrl/Cmd + K - Focar na busca\\n' + | |
| 'Ctrl/Cmd + Enter - Enviar formulario\\n' + | |
| 'Ctrl/Cmd + D - Alternar dark mode\\n' + | |
| 'Ctrl/Cmd + / - Mostrar ajuda de atalhos\\n' + | |
| 'Esc - Limpar entrada' | |
| ); | |
| } | |
| // Ctrl/Cmd + D - Toggle dark mode | |
| if ((e.ctrlKey || e.metaKey) && e.key === 'd') { | |
| e.preventDefault(); | |
| const darkModeToggle = document.querySelector('#dark-mode-toggle'); | |
| if (darkModeToggle) { | |
| darkModeToggle.click(); | |
| } | |
| } | |
| // Esc - Clear input | |
| if (e.key === 'Escape') { | |
| const activeElement = document.activeElement; | |
| if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA') { | |
| activeElement.value = ''; | |
| } | |
| } | |
| }); | |
| } | |
| // Run on load | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', setupKeyboardShortcuts); | |
| } else { | |
| setupKeyboardShortcuts(); | |
| } | |
| """ | |
| def get_theme(dark_mode: bool = False) -> str: | |
| """ | |
| Retorna CSS do tema. | |
| Args: | |
| dark_mode: Se True, retorna dark mode | |
| Returns: | |
| String CSS | |
| """ | |
| base_css = DARK_MODE_CSS if dark_mode else LIGHT_MODE_CSS | |
| return base_css + "\n" + KEYBOARD_SHORTCUTS_JS | |
| def create_theme_toggle() -> tuple: | |
| """ | |
| Cria toggle de dark mode. | |
| Returns: | |
| Tuple (checkbox, css_component) | |
| """ | |
| dark_mode_toggle = gr.Checkbox( | |
| label="Dark Mode", | |
| value=False, | |
| elem_id="dark-mode-toggle" | |
| ) | |
| return dark_mode_toggle | |
| def apply_theme(dark_mode: bool) -> str: | |
| """ | |
| Aplica tema baseado no dark_mode. | |
| Args: | |
| dark_mode: Se True, aplica dark mode | |
| Returns: | |
| CSS string | |
| """ | |
| return get_theme(dark_mode=dark_mode) | |
| # Funcoes de exportacao | |
| def create_export_buttons() -> tuple: | |
| """ | |
| Cria botoes de exportacao. | |
| Returns: | |
| Tuple de botoes (json, csv, md, pdf) | |
| """ | |
| with gr.Row(): | |
| export_json_btn = gr.Button("Exportar JSON", size="sm") | |
| export_csv_btn = gr.Button("Exportar CSV", size="sm") | |
| export_md_btn = gr.Button("Exportar Markdown", size="sm") | |
| export_pdf_btn = gr.Button("Exportar PDF", size="sm") | |
| return export_json_btn, export_csv_btn, export_md_btn, export_pdf_btn | |
| def create_keyboard_shortcuts_help() -> gr.Markdown: | |
| """ | |
| Cria componente de ajuda de atalhos. | |
| Returns: | |
| Componente Markdown | |
| """ | |
| shortcuts_text = """ | |
| ### Atalhos de Teclado | |
| | Atalho | Acao | | |
| |--------|------| | |
| | `Ctrl/Cmd + K` | Focar na busca | | |
| | `Ctrl/Cmd + Enter` | Enviar formulario | | |
| | `Ctrl/Cmd + D` | Alternar dark mode | | |
| | `Ctrl/Cmd + /` | Mostrar ajuda | | |
| | `Esc` | Limpar entrada | | |
| """ | |
| return gr.Markdown(shortcuts_text, visible=False, elem_id="shortcuts-help") | |