| """ |
| HF-Master Shared Components |
| Reusable Gradio components for all projects |
| """ |
|
|
| import gradio as gr |
| from typing import List, Tuple, Optional, Dict, Any |
|
|
|
|
| class SharedComponents: |
| """Shared UI components for all HF-Master projects""" |
|
|
| @staticmethod |
| def create_header(title: str, description: str, emoji: str = "π") -> gr.Markdown: |
| """Create standardized project header""" |
| return gr.Markdown(f""" |
| <div style=" |
| background: linear-gradient(135deg, rgba(78,205,196,0.14), rgba(255,107,107,0.16)); |
| border: 1px solid rgba(255,255,255,0.12); |
| border-radius: 24px; |
| padding: 2rem 1.5rem; |
| margin-bottom: 1.25rem; |
| box-shadow: 0 18px 40px rgba(0,0,0,0.18); |
| backdrop-filter: blur(14px); |
| "> |
| <div style="display:flex; align-items:center; gap:0.75rem; justify-content:center; flex-wrap:wrap; margin-bottom:0.65rem;"> |
| <span style=" |
| display:inline-flex; |
| align-items:center; |
| justify-content:center; |
| width:3rem; |
| height:3rem; |
| border-radius:999px; |
| background: rgba(255,255,255,0.08); |
| border: 1px solid rgba(255,255,255,0.12); |
| font-size: 1.4rem; |
| ">{emoji}</span> |
| <h1 style="margin:0; font-size: clamp(2rem, 4vw, 3rem); letter-spacing:-0.03em;">{title}</h1> |
| </div> |
| <p style="margin:0; text-align:center; color:#cbd5e1; font-size:1.05rem; line-height:1.6;">{description}</p> |
| </div> |
| """) |
|
|
| @staticmethod |
| def create_footer(version: str = "1.0.0") -> gr.Markdown: |
| """Create standardized project footer""" |
| return gr.Markdown(f""" |
| <div style=" |
| margin-top: 1.5rem; |
| padding: 1rem 1.25rem; |
| border-top: 1px solid rgba(255,255,255,0.10); |
| color: #94a3b8; |
| text-align: center; |
| font-size: 0.95rem; |
| "> |
| <strong style="color:#e2e8f0;">HF-Master v{version}</strong> | Built with β€οΈ for the AI community |
| </div> |
| """) |
|
|
| @staticmethod |
| def create_premium_hero( |
| title: str, |
| description: str, |
| emoji: str = "π", |
| badge: str = "Featured Space", |
| highlights: Optional[List[str]] = None, |
| ) -> gr.HTML: |
| """Create a richer landing-page hero for Spaces.""" |
| highlights = highlights or [] |
| chips = "".join( |
| f""" |
| <span style=" |
| display:inline-flex; |
| align-items:center; |
| gap:0.4rem; |
| padding:0.45rem 0.8rem; |
| border-radius:999px; |
| background: rgba(255,255,255,0.08); |
| border: 1px solid rgba(255,255,255,0.10); |
| color:#e2e8f0; |
| font-size:0.88rem; |
| font-weight:600; |
| ">{item}</span> |
| """ |
| for item in highlights |
| ) |
|
|
| return gr.HTML(f""" |
| <div style=" |
| background: |
| linear-gradient(135deg, rgba(78,205,196,0.18), rgba(255,107,107,0.14)), |
| rgba(15, 23, 42, 0.88); |
| border: 1px solid rgba(255,255,255,0.12); |
| border-radius: 28px; |
| padding: 2rem; |
| margin-bottom: 1.25rem; |
| box-shadow: 0 22px 50px rgba(0,0,0,0.22); |
| backdrop-filter: blur(16px); |
| "> |
| <div style="display:flex; align-items:flex-start; gap:1rem; flex-wrap:wrap; justify-content:space-between;"> |
| <div style="display:flex; gap:1rem; align-items:flex-start; flex:1; min-width: 260px;"> |
| <div style=" |
| width:4rem; |
| height:4rem; |
| display:flex; |
| align-items:center; |
| justify-content:center; |
| border-radius:1.25rem; |
| background: rgba(255,255,255,0.09); |
| border: 1px solid rgba(255,255,255,0.12); |
| font-size:1.8rem; |
| flex-shrink:0; |
| ">{emoji}</div> |
| <div> |
| <div style=" |
| display:inline-flex; |
| align-items:center; |
| padding:0.35rem 0.75rem; |
| border-radius:999px; |
| background: rgba(255,255,255,0.08); |
| border: 1px solid rgba(255,255,255,0.10); |
| color:#cbd5e1; |
| font-size:0.8rem; |
| font-weight:700; |
| letter-spacing:0.08em; |
| text-transform:uppercase; |
| margin-bottom:0.8rem; |
| ">{badge}</div> |
| <h1 style="margin:0 0 0.35rem 0; font-size:clamp(2rem, 4vw, 3.35rem); line-height:1.05; letter-spacing:-0.04em; color:#f8fafc;">{title}</h1> |
| <p style="margin:0; color:#cbd5e1; font-size:1.05rem; line-height:1.65; max-width: 62ch;">{description}</p> |
| </div> |
| </div> |
| </div> |
| <div style="display:flex; gap:0.6rem; flex-wrap:wrap; margin-top:1.25rem;"> |
| {chips} |
| </div> |
| </div> |
| """) |
|
|
| @staticmethod |
| def create_status_badge(status: str) -> str: |
| """Create status badge""" |
| colors = { |
| "complete": "π’", |
| "in-progress": "π‘", |
| "planned": "βͺ", |
| "experimental": "π΄" |
| } |
| return colors.get(status.lower(), "βͺ") |
|
|
| @staticmethod |
| def create_project_card( |
| title: str, |
| description: str, |
| tech_stack: List[str], |
| difficulty: str, |
| viral_potential: str |
| ) -> str: |
| """Create markdown project card""" |
| tech_badges = " ".join([f"`{t}`" for t in tech_stack]) |
|
|
| return f""" |
| ## {title} |
| |
| {description} |
| |
| **Tech Stack:** {tech_badges} |
| |
| **Difficulty:** {difficulty} | **Viral Potential:** {viral_potential} |
| """ |
|
|
| @staticmethod |
| def create_risk_chart(risk_factors: Dict[str, float]) -> Any: |
| """Create risk factor visualization""" |
| import plotly.graph_objects as go |
|
|
| factors = list(risk_factors.keys()) |
| scores = [risk_factors[f] * 100 for f in factors] |
|
|
| fig = go.Figure(data=[ |
| go.Bar( |
| x=scores, |
| y=[f.replace('_', ' ').title() for f in factors], |
| orientation='h', |
| marker=dict( |
| color=scores, |
| colorscale='RdYlGn_r', |
| cmin=0, |
| cmax=100 |
| ) |
| ) |
| ]) |
|
|
| fig.update_layout( |
| title="Risk Factor Breakdown", |
| xaxis_title="Risk Score", |
| yaxis_title="Factor", |
| height=400, |
| template="plotly_white" |
| ) |
|
|
| return fig |
|
|
| @staticmethod |
| def create_comparison_chart(items: List[Dict], keys: List[str]) -> Any: |
| """Create comparison visualization""" |
| import plotly.graph_objects as go |
|
|
| fig = go.Figure() |
|
|
| for i, item in enumerate(items): |
| fig.add_trace(go.Bar( |
| name=item.get('name', f'Item {i+1}'), |
| x=keys, |
| y=[item.get(k, 0) for k in keys] |
| )) |
|
|
| fig.update_layout( |
| barmode='group', |
| height=400 |
| ) |
|
|
| return fig |
|
|
| @staticmethod |
| def create_metric_card(label: str, value: str, emoji: str = "π") -> gr.Markdown: |
| """Create metric display card""" |
| return gr.Markdown(f""" |
| ### {emoji} {label} |
| |
| **{value}** |
| """) |
|
|
| @staticmethod |
| def create_error_display(error: str) -> gr.Markdown: |
| """Create error message display""" |
| return gr.Markdown(f""" |
| β **Error** |
| |
| {error} |
| """) |
|
|
| @staticmethod |
| def create_success_display(message: str) -> gr.Markdown: |
| """Create success message display""" |
| return gr.Markdown(f""" |
| β
**Success** |
| |
| {message} |
| """) |
|
|
|
|
| class LoadingSpinner: |
| """Loading state display""" |
|
|
| @staticmethod |
| def create_spinner(message: str = "Loading...") -> gr.Markdown: |
| """Create loading spinner""" |
| return gr.Markdown(f""" |
| β³ **{message}** |
| |
| _This may take a moment..._ |
| """) |
|
|
| @staticmethod |
| def create_progress_bar(initial: float = 0) -> gr.Markdown: |
| """Create progress display""" |
| return gr.Markdown(f""" |
| βββββββββ **{initial}%** |
| """) |
|
|
|
|
| class TableFormatter: |
| """Format data as tables""" |
|
|
| @staticmethod |
| def format_dict_table(data: Dict[str, Any], headers: List[str] = None) -> List: |
| """Format dictionary as table rows""" |
| if not headers: |
| headers = ["Key", "Value"] |
|
|
| rows = [] |
| for key, value in data.items(): |
| rows.append([key, str(value)]) |
|
|
| return [headers] + rows |
|
|
| @staticmethod |
| def create_dataframe(data: List[Dict], columns: List[str] = None) -> List: |
| """Create dataframe-compatible data structure""" |
| if not data: |
| return [] |
|
|
| if columns: |
| headers = columns |
| else: |
| headers = list(data[0].keys()) if data else [] |
|
|
| rows = [[row.get(h, "") for h in headers] for row in data] |
|
|
| return [headers] + rows |
|
|
|
|
| class CodeHighlighter: |
| """Code display and highlighting""" |
|
|
| @staticmethod |
| def create_code_display(code: str, language: str = "python") -> gr.Code: |
| """Create code display block""" |
| return gr.Code( |
| value=code, |
| language=language, |
| lines=20 |
| ) |
|
|
| @staticmethod |
| def create_copy_button(code: str) -> gr.Button: |
| """Create copy-to-clipboard button""" |
| return gr.Button("π Copy Code") |
|
|
| @staticmethod |
| def create_diff_view(old_code: str, new_code: str) -> Tuple[gr.Code, gr.Code]: |
| """Create side-by-side diff view""" |
| return ( |
| gr.Code(value=old_code, language="python", lines=15, label="Before"), |
| gr.Code(value=new_code, language="python", lines=15, label="After") |
| ) |
|
|
|
|
| def create_header(title: str, description: str, emoji: str = "π") -> gr.Markdown: |
| return SharedComponents.create_header(title, description, emoji) |
|
|
|
|
| def create_footer(version: str = "1.0.0") -> gr.Markdown: |
| return SharedComponents.create_footer(version) |
|
|
|
|
| def create_premium_hero( |
| title: str, |
| description: str, |
| emoji: str = "π", |
| badge: str = "Featured Space", |
| highlights: Optional[List[str]] = None, |
| ) -> gr.HTML: |
| return SharedComponents.create_premium_hero(title, description, emoji, badge, highlights) |
|
|
|
|
| class ProgressTracker: |
| """Track multi-step progress""" |
|
|
| def __init__(self, steps: List[str]): |
| self.steps = steps |
| self.current = 0 |
|
|
| def get_status(self) -> str: |
| """Get current status""" |
| completed = "β
" + "\n".join(self.steps[:self.current]) |
| current = f"π {self.steps[self.current]}" if self.current < len(self.steps) else "" |
| remaining = "\n".join([f"β¬ {s}" for s in self.steps[self.current+1:]]) |
|
|
| return f""" |
| ## Progress |
| |
| {completed} |
| {current} |
| {remaining} |
| """ |
|
|
| def advance(self) -> bool: |
| """Move to next step""" |
| if self.current < len(self.steps): |
| self.current += 1 |
| return True |
| return False |
|
|
| def reset(self): |
| """Reset progress""" |
| self.current = 0 |
|
|
|
|
| def create_tabbed_interface(tabs: Dict[str, Any]) -> gr.Blocks: |
| """Create tabbed interface helper""" |
| with gr.Blocks() as demo: |
| with gr.Tabs(): |
| for tab_name, tab_content in tabs.items(): |
| with gr.Tab(tab_name): |
| tab_content |
|
|
| return demo |
|
|
|
|
| def create_side_by_side(left_content: Any, right_content: Any) -> Tuple[gr.Column, gr.Column]: |
| """Create side-by-side layout""" |
| with gr.Row(): |
| with gr.Column(): |
| left_content |
| with gr.Column(): |
| right_content |
|
|
| return left_content, right_content |
|
|
|
|
| def create_accordion(items: List[Tuple[str, Any]]) -> gr.Accordion: |
| """Create accordion-style expandable sections""" |
| with gr.Accordion("Click to expand") as accordion: |
| for title, content in items: |
| gr.Markdown(f"### {title}") |
| content |
|
|
| return accordion |
|
|