Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Example API Usage for Editable MarkdownLabel Component | |
| Shows the recommended event handling pattern to avoid infinite loops. | |
| """ | |
| import gradio as gr | |
| from gradio_markdownlabel import MarkdownLabel | |
| def main(): | |
| # Sample document with highlights | |
| document = { | |
| "markdown_content": """# Project Documentation | |
| ## Overview | |
| This is an **editable document** that demonstrates the MarkdownLabel component's capabilities. | |
| ## Features | |
| - Interactive editing with save/cancel workflow | |
| - Position-based and term-based highlighting | |
| - Live preview during editing | |
| - Manual save to prevent accidental changes | |
| ## Instructions | |
| Click "Edit" to modify this content, then "Save" to apply changes. | |
| """, | |
| "highlights": [ | |
| { | |
| "term": "editable document", | |
| "title": "Editable Document", | |
| "content": "Documents that can be modified by users through the interface.", | |
| "category": "feature", | |
| "color": "#e3f2fd" | |
| }, | |
| { | |
| "position": [200, 220], # "MarkdownLabel component" | |
| "title": "MarkdownLabel Component", | |
| "content": "The custom Gradio component for displaying markdown with interactive highlights.", | |
| "category": "technical", | |
| "color": "#f3e5f5" | |
| } | |
| ] | |
| } | |
| # Event handlers - NO change handler to prevent loops | |
| def on_edit_start(data): | |
| """Called when user clicks Edit button""" | |
| print(f"π User started editing document") | |
| # Could initialize editing session, backup content, etc. | |
| return gr.update() # No changes to component | |
| def on_save(data): | |
| """Called when user clicks Save button""" | |
| print(f"πΎ Document saved with {len(data['markdown_content'])} characters") | |
| # Here you could: | |
| # - Validate the content | |
| # - Save to database | |
| # - Update version history | |
| # - Send notifications | |
| gr.Info("Document saved successfully!") | |
| return data # Return the saved data | |
| def on_cancel(data): | |
| """Called when user clicks Cancel button""" | |
| print(f"β Edit cancelled") | |
| gr.Info("Changes discarded") | |
| return gr.update() # No changes needed | |
| def on_highlight_select(selection_data): | |
| """Called when user clicks a highlight""" | |
| print(f"π― Highlight selected: {selection_data}") | |
| return gr.update() | |
| # Create the interface | |
| with gr.Blocks(title="MarkdownLabel API Example") as demo: | |
| gr.Markdown("# MarkdownLabel API Usage Example") | |
| gr.Markdown("Demonstrates proper event handling without infinite loops.") | |
| # The component | |
| editor = MarkdownLabel( | |
| value=document, | |
| interactive=True, # Enable editing | |
| edit_mode="split", # Split view: editor + preview | |
| show_preview=True, # Show live preview | |
| show_side_panel=True, # Show highlight details | |
| panel_width="350px", | |
| label="Interactive Document Editor" | |
| ) | |
| # Event handlers - IMPORTANT: No .change() handler during editing! | |
| editor.edit( | |
| fn=on_edit_start, | |
| inputs=[editor] | |
| # No outputs = no component update | |
| ) | |
| editor.submit( # This is the "Save" button | |
| fn=on_save, | |
| inputs=[editor], | |
| outputs=[editor] # Update component with saved data | |
| ) | |
| editor.clear( # This is the "Cancel" button | |
| fn=on_cancel, | |
| inputs=[editor] | |
| # No outputs = revert handled internally | |
| ) | |
| editor.select( # Highlight selection | |
| fn=on_highlight_select, | |
| inputs=[editor] | |
| ) | |
| # Status display | |
| gr.Markdown(""" | |
| ### Event Flow: | |
| 1. **Edit**: User clicks edit β `on_edit_start()` called | |
| 2. **Type**: User types β Only visual preview updates (no events) | |
| 3. **Save**: User clicks save β `on_save()` called β Changes applied | |
| 4. **Cancel**: User clicks cancel β `on_cancel()` called β Changes reverted | |
| ### Key Points: | |
| - β **DON'T** use `.change()` handlers during editing (causes loops) | |
| - β **DO** use `.submit()` for save actions | |
| - β **DO** use `.clear()` for cancel actions | |
| - β **DO** use `.edit()` for edit start actions | |
| - β **DO** use `.select()` for highlight interactions | |
| """) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = main() | |
| demo.launch() |