CoolFace
Apppublic

uxoxo/eb2ab

sourceHugging Faceapache-2.0updated 11mo agoView on Hugging Face
0likes
ui_helpers.py380 linesDownload Raw Back to lib
1"""2UI Helper Functions - Design System Integration3 4Helper functions to create consistent UI components using the design system5throughout the ebook2audiobook application.6 7Author: Claude Code8Date: 2025-10-219"""10 11import gradio as gr12from typing import Optional, List, Dict, Any, Callable13 14# Import design system components15try:16    from design_system import (17        button, card, alert, tag, progress_bar,18        status_indicator, estimate_box, spinner, tokens19    )20    HAS_DESIGN_SYSTEM = True21except ImportError:22    HAS_DESIGN_SYSTEM = False23    # Fallback to standard Gradio if design system not available24    print("Warning: Design system not available, using standard Gradio components")25 26 27def create_primary_button(label: str, icon: Optional[str] = None, **kwargs) -> gr.Button:28    """Create a primary action button with consistent styling"""29    if HAS_DESIGN_SYSTEM:30        return button(label, variant="primary", size="lg", icon=icon, **kwargs)31    else:32        display_label = f"{icon} {label}" if icon else label33        return gr.Button(display_label, variant="primary", size="lg", **kwargs)34 35 36def create_secondary_button(label: str, icon: Optional[str] = None, **kwargs) -> gr.Button:37    """Create a secondary action button"""38    if HAS_DESIGN_SYSTEM:39        return button(label, variant="secondary", icon=icon, **kwargs)40    else:41        display_label = f"{icon} {label}" if icon else label42        return gr.Button(display_label, variant="secondary", **kwargs)43 44 45def create_outline_button(label: str, icon: Optional[str] = None, **kwargs) -> gr.Button:46    """Create an outline/ghost button for less prominent actions"""47    if HAS_DESIGN_SYSTEM:48        return button(label, variant="outline", icon=icon, **kwargs)49    else:50        display_label = f"{icon} {label}" if icon else label51        return gr.Button(display_label, **kwargs)52 53 54def create_destructive_button(label: str, icon: Optional[str] = None, **kwargs) -> gr.Button:55    """Create a destructive action button (delete, reset, etc.)"""56    if HAS_DESIGN_SYSTEM:57        return button(label, variant="destructive", icon=icon, **kwargs)58    else:59        display_label = f"{icon} {label}" if icon else label60        return gr.Button(display_label, variant="stop", **kwargs)61 62 63def create_section_card(title: str, **kwargs):64    """65    Create a card container for grouping related components66 67    Usage:68        with create_section_card("Upload Settings"):69            gr.File(...)70            gr.Dropdown(...)71    """72    if HAS_DESIGN_SYSTEM:73        return card(title=title, **kwargs)74    else:75        # Fallback: Use Group with markdown title76        col = gr.Column(**kwargs)77        col.__enter__()78        gr.Markdown(f"### {title}")79        return col80 81 82def create_status_tag(text: str, state: str = "pending") -> gr.HTML:83    """84    Create a status tag/badge85 86    States: pending, processing, modernized, approved, error87    """88    if HAS_DESIGN_SYSTEM:89        return tag(text, state=state)90    else:91        # Fallback: colored markdown92        colors = {93            "pending": "#A3A3A3",94            "processing": "#F5A623",95            "approved": "#2ECC71",96            "error": "#E74C3C"97        }98        color = colors.get(state, "#A3A3A3")99        html = f'<span style="background: {color}20; color: {color}; padding: 4px 12px; border-radius: 12px; font-size: 14px; font-weight: 500;">{text}</span>'100        return gr.HTML(html)101 102 103def create_alert_box(message: str, variant: str = "info", icon: Optional[str] = None) -> gr.HTML:104    """105    Create an alert/notification box106 107    Variants: info, success, warning, error108    """109    if HAS_DESIGN_SYSTEM:110        return alert(message, variant=variant, icon=icon)111    else:112        # Fallback: colored markdown113        colors = {114            "info": {"bg": "#E0F2FE", "border": "#0EA5E9", "text": "#0284C7"},115            "success": {"bg": "#D1FAE5", "border": "#2ECC71", "text": "#059669"},116            "warning": {"bg": "#FEF3C7", "border": "#F5A623", "text": "#D97706"},117            "error": {"bg": "#FEE2E2", "border": "#E74C3C", "text": "#DC2626"}118        }119        style = colors.get(variant, colors["info"])120 121        icons_default = {122            "info": "ℹ️",123            "success": "✅",124            "warning": "⚠️",125            "error": "❌"126        }127        display_icon = icon or icons_default.get(variant, "")128 129        html = f'''130        <div style="131            background: {style['bg']};132            border-left: 4px solid {style['border']};133            color: {style['text']};134            padding: 16px;135            border-radius: 8px;136            margin: 10px 0;137            display: flex;138            align-items: flex-start;139            gap: 12px;140        ">141            <span style="font-size: 20px;">{display_icon}</span>142            <div>{message}</div>143        </div>144        '''145        return gr.HTML(html)146 147 148def create_progress_indicator(value: float = 0, state: str = "default", **kwargs) -> gr.Slider:149    """150    Create a progress bar151 152    States: default, processing, complete, error153    """154    if HAS_DESIGN_SYSTEM:155        return progress_bar(value=value, state=state, **kwargs)156    else:157        return gr.Slider(158            minimum=0,159            maximum=100,160            value=value,161            label="Progress",162            interactive=False,163            **kwargs164        )165 166 167def create_status_display(label: str, state: str, progress: Optional[float] = None) -> gr.Column:168    """169    Create a status indicator with optional progress bar170 171    Usage:172        status_display = create_status_display("15/20 Approved", "processing", 75)173    """174    if HAS_DESIGN_SYSTEM:175        return status_indicator(label=label, state=state, progress=progress)176    else:177        col = gr.Column()178        with col:179            with gr.Row():180                create_status_tag(label, state)181                if progress is not None:182                    gr.Markdown(f"{progress:.0f}%")183            if progress is not None:184                create_progress_indicator(progress, state)185        return col186 187 188def create_cost_estimate_box(cost: str, time: str, details: Optional[str] = None) -> gr.Column:189    """190    Create an estimate display box for costs and time191 192    Usage:193        estimate = create_cost_estimate_box("$2.50", "~15 minutes", "Details...")194    """195    if HAS_DESIGN_SYSTEM:196        return estimate_box(cost=cost, time=time, details=details)197    else:198        col = gr.Column()199        with col:200            gr.Markdown(f"""201            <div style="background: linear-gradient(135deg, #E0F2FE 0%, #E8EDFF 100%);202                        border: 2px solid #0EA5E9;203                        border-radius: 16px;204                        padding: 24px;205                        margin: 16px 0;">206                <div style="font-size: 30px; font-weight: 700; color: #0284C7; margin-bottom: 8px;">207                    {cost}208                </div>209                <div style="font-size: 20px; font-weight: 600; color: #059669;">210                    {time}211                </div>212                {f'<div style="margin-top: 16px;">{details}</div>' if details else ''}213            </div>214            """)215        return col216 217 218def create_loading_spinner(size: int = 20) -> gr.HTML:219    """Create a loading spinner"""220    if HAS_DESIGN_SYSTEM:221        return spinner(size=size)222    else:223        html = f'''224        <div style="225            width: {size}px;226            height: {size}px;227            border: 3px solid #E5E5E5;228            border-top-color: #4A6FFF;229            border-radius: 50%;230            animation: spin 0.8s linear infinite;231        "></div>232        <style>233        @keyframes spin {{234            to {{ transform: rotate(360deg); }}235        }}236        </style>237        '''238        return gr.HTML(html)239 240 241def get_design_tokens():242    """243    Get design tokens for custom styling244 245    Returns dict with color, spacing, etc. tokens246    """247    if HAS_DESIGN_SYSTEM:248        return {249            'PRIMARY': tokens.PRIMARY,250            'SUCCESS': tokens.SUCCESS,251            'WARNING': tokens.WARNING,252            'ERROR': tokens.ERROR,253            'SPACE_2': tokens.SPACE_2,254            'SPACE_4': tokens.SPACE_4,255            'SPACE_6': tokens.SPACE_6,256            'RADIUS_LG': tokens.RADIUS_LG,257            'RADIUS_MD': tokens.RADIUS_MD,258        }259    else:260        return {261            'PRIMARY': '#4A6FFF',262            'SUCCESS': '#2ECC71',263            'WARNING': '#F5A623',264            'ERROR': '#E74C3C',265            'SPACE_2': '8px',266            'SPACE_4': '16px',267            'SPACE_6': '24px',268            'RADIUS_LG': '12px',269            'RADIUS_MD': '8px',270        }271 272 273def create_hero_section(title: str, subtitle: Optional[str] = None, icon: Optional[str] = None, **kwargs) -> gr.Markdown:274    """275    Create a hero section banner for tab headers276 277    Usage:278        create_hero_section(279            title="Convert Your Ebook to Audiobook",280            subtitle="Upload, configure, and generate high-quality narrated audiobooks",281            icon="📚"282        )283    """284    icon_display = f"{icon} " if icon else ""285    subtitle_display = f"\n\n{subtitle}" if subtitle else ""286 287    markdown_content = f"""288# {icon_display}{title}{subtitle_display}289"""290    return gr.Markdown(markdown_content, elem_id=kwargs.get('elem_id', 'hero-section'), elem_classes=['hero-section'])291 292 293def create_info_card(content: str, variant: str = "info", **kwargs) -> gr.Column:294    """295    Create an informational card (help text, tips, warnings)296 297    Variants: info, tip, warning298 299    Usage:300        with create_info_card("Voice cloning works best with 6-10 seconds of clear audio", variant="tip"):301            pass302    """303    icons = {304        "info": "ℹ️",305        "tip": "💡",306        "warning": "⚠️"307    }308    icon = icons.get(variant, "ℹ️")309 310    col = gr.Column(elem_classes=['info-card', f'info-card-{variant}'], **kwargs)311    col.__enter__()312    gr.Markdown(f"{icon} {content}")313    return col314 315 316def create_parameter_group(title: str, description: Optional[str] = None) -> gr.Group:317    """318    Create a visual group for related parameters within a card319 320    Usage:321        with create_parameter_group("Core Settings", "Adjust the main parameters"):322            gr.Slider(...)323            gr.Slider(...)324    """325    group = gr.Group(elem_classes=['parameter-group'])326    group.__enter__()327    if title:328        gr.Markdown(f"**{title}**", elem_classes=['parameter-group-title'])329    if description:330        gr.Markdown(f"*{description}*", elem_classes=['parameter-group-description'])331    return group332 333 334def create_action_row(**kwargs) -> gr.Row:335    """336    Create a standardized action row for buttons337 338    Usage:339        with create_action_row():340            reset_btn = create_destructive_button("Reset to Defaults", icon="↺")341            apply_btn = create_primary_button("Apply Settings", icon="✓")342    """343    return gr.Row(elem_classes=['action-button-row'], **kwargs)344 345 346def create_two_column_layout(**kwargs) -> gr.Row:347    """348    Create a responsive two-column layout349 350    Usage:351        with create_two_column_layout():352            with gr.Column(scale=1):353                # Left content354            with gr.Column(scale=1):355                # Right content356    """357    return gr.Row(elem_classes=['two-column-layout'], **kwargs)358 359 360# Convenience exports361__all__ = [362    'create_primary_button',363    'create_secondary_button',364    'create_outline_button',365    'create_destructive_button',366    'create_section_card',367    'create_status_tag',368    'create_alert_box',369    'create_progress_indicator',370    'create_status_display',371    'create_cost_estimate_box',372    'create_loading_spinner',373    'get_design_tokens',374    'create_hero_section',375    'create_info_card',376    'create_parameter_group',377    'create_action_row',378    'create_two_column_layout',379]380 
uxoxo/eb2ab · CoolFace