diff --git a/ts_web/elements/dees-input-wysiwyg.demo.ts b/ts_web/elements/dees-input-wysiwyg.demo.ts index 2ad06d2..b6833bc 100644 --- a/ts_web/elements/dees-input-wysiwyg.demo.ts +++ b/ts_web/elements/dees-input-wysiwyg.demo.ts @@ -1,433 +1,642 @@ -import { html, css } from '@design.estate/dees-element'; +import { html, css, type TemplateResult } from '@design.estate/dees-element'; import '@design.estate/dees-wcctools/demotools'; +import type { DeesInputWysiwyg } from './dees-input-wysiwyg.js'; +import type { IBlock } from './wysiwyg/wysiwyg.types.js'; -export const demoFunc = () => html` - { - // Get editor instances - const programmaticEditor = elementArg.querySelector('#programmatic-demo') as any; - const articleEditor = elementArg.querySelector('#article-editor') as any; - const dragDemoEditor = elementArg.querySelector('#drag-demo') as any; - - // Programmatically set content for the article editor after render - if (articleEditor) { - const articleBlocks = [ +interface IDemoEditor { + basic: DeesInputWysiwyg; + article: DeesInputWysiwyg; + dragDrop: DeesInputWysiwyg; + tutorial: DeesInputWysiwyg; + meeting: DeesInputWysiwyg; + recipe: DeesInputWysiwyg; + technical: DeesInputWysiwyg; + formIntegration: DeesInputWysiwyg; + programmatic: DeesInputWysiwyg; + exportDemo: DeesInputWysiwyg; +} + +// Sample content generators +const generateReportBlocks = (): IBlock[] => { + const timestamp = Date.now(); + return [ + { + id: `title-${timestamp}`, + type: 'heading-1', + content: 'System Performance Report' + }, + { + id: `date-${timestamp + 1}`, + type: 'paragraph', + content: `Generated on: ${new Date().toLocaleString()}` + }, + { + id: `summary-heading-${timestamp + 2}`, + type: 'heading-2', + content: 'Executive Summary' + }, + { + id: `summary-${timestamp + 3}`, + type: 'paragraph', + content: 'This report provides an analysis of system performance metrics over the last 30 days.' + }, + { + id: `metrics-heading-${timestamp + 4}`, + type: 'heading-2', + content: 'Key Metrics' + }, + { + id: `metrics-list-${timestamp + 5}`, + type: 'list', + content: 'Average response time: 124ms\nUptime: 99.97%\nCPU utilization: 45%\nMemory usage: 2.3GB / 8GB', + metadata: { listType: 'bullet' } + }, + { + id: `analysis-heading-${timestamp + 6}`, + type: 'heading-2', + content: 'Performance Analysis' + }, + { + id: `analysis-quote-${timestamp + 7}`, + type: 'quote', + content: 'System performance remains within acceptable parameters with room for optimization in memory management.' + }, + { + id: `code-heading-${timestamp + 8}`, + type: 'heading-3', + content: 'Sample Query Performance' + }, + { + id: `code-block-${timestamp + 9}`, + type: 'code', + content: 'SELECT AVG(response_time) as avg_time,\n COUNT(*) as total_requests,\n DATE(created_at) as date\nFROM performance_logs\nWHERE created_at >= NOW() - INTERVAL 30 DAY\nGROUP BY DATE(created_at)\nORDER BY date DESC;', + metadata: { language: 'sql' } + }, + { + id: `divider-${timestamp + 10}`, + type: 'divider', + content: '' + }, + { + id: `footer-${timestamp + 11}`, + type: 'paragraph', + content: 'Report generated automatically by System Monitor v2.5.0' + } + ]; +}; + +const generateRecipeBlocks = (): IBlock[] => { + const timestamp = Date.now(); + return [ + { + id: `recipe-title-${timestamp}`, + type: 'heading-1', + content: 'Classic Margherita Pizza' + }, + { + id: `recipe-intro-${timestamp + 1}`, + type: 'paragraph', + content: 'A traditional Italian pizza with fresh basil, mozzarella, and tomato sauce.' + }, + { + id: `ingredients-heading-${timestamp + 2}`, + type: 'heading-2', + content: '🍕 Ingredients' + }, + { + id: `dough-heading-${timestamp + 3}`, + type: 'heading-3', + content: 'For the Dough:' + }, + { + id: `dough-list-${timestamp + 4}`, + type: 'list', + content: '500g tipo "00" flour\n325ml warm water\n10g salt\n7g active dry yeast\n2 tbsp olive oil', + metadata: { listType: 'bullet' } + }, + { + id: `toppings-heading-${timestamp + 5}`, + type: 'heading-3', + content: 'For the Toppings:' + }, + { + id: `toppings-list-${timestamp + 6}`, + type: 'list', + content: '400g canned San Marzano tomatoes\n250g fresh mozzarella\nFresh basil leaves\nExtra virgin olive oil\nSalt and pepper to taste', + metadata: { listType: 'bullet' } + }, + { + id: `instructions-heading-${timestamp + 7}`, + type: 'heading-2', + content: '👨‍🍳 Instructions' + }, + { + id: `steps-list-${timestamp + 8}`, + type: 'list', + content: 'Dissolve yeast in warm water and let stand for 5 minutes\nMix flour and salt, create a well in center\nAdd yeast mixture and olive oil\nKnead for 10 minutes until smooth\nLet rise for 1-2 hours until doubled\nPunch down and divide into portions\nRoll out each portion to 12-inch circles\nTop with crushed tomatoes, mozzarella, and basil\nBake at 475°F (245°C) for 10-12 minutes', + metadata: { listType: 'ordered' } + }, + { + id: `tip-${timestamp + 9}`, + type: 'quote', + content: 'Pro tip: For an authentic taste, use a pizza stone and preheat it in the oven for at least 30 minutes before baking.' + }, + { + id: `divider-${timestamp + 10}`, + type: 'divider', + content: '' + }, + { + id: `servings-${timestamp + 11}`, + type: 'paragraph', + content: 'Servings: 4 pizzas | Prep time: 2 hours | Cook time: 12 minutes' + } + ]; +}; + +const initializeEditors = (container: HTMLElement): IDemoEditor => { + const editors: Partial = {}; + + // Get all editor references + editors.basic = container.querySelector('#editor-basic') as DeesInputWysiwyg; + editors.article = container.querySelector('#editor-article') as DeesInputWysiwyg; + editors.dragDrop = container.querySelector('#editor-dragdrop') as DeesInputWysiwyg; + editors.tutorial = container.querySelector('#editor-tutorial') as DeesInputWysiwyg; + editors.meeting = container.querySelector('#editor-meeting') as DeesInputWysiwyg; + editors.recipe = container.querySelector('#editor-recipe') as DeesInputWysiwyg; + editors.technical = container.querySelector('#editor-technical') as DeesInputWysiwyg; + editors.formIntegration = container.querySelector('#editor-form-integration') as DeesInputWysiwyg; + editors.programmatic = container.querySelector('#editor-programmatic') as DeesInputWysiwyg; + editors.exportDemo = container.querySelector('#editor-export') as DeesInputWysiwyg; + + return editors as IDemoEditor; +}; + +const setupProgrammaticDemo = (container: HTMLElement, editor: DeesInputWysiwyg) => { + const reportBtn = container.querySelector('#btn-generate-report') as HTMLButtonElement; + const recipeBtn = container.querySelector('#btn-generate-recipe') as HTMLButtonElement; + const clearBtn = container.querySelector('#btn-clear-editor') as HTMLButtonElement; + + if (reportBtn) { + reportBtn.addEventListener('click', () => { + editor.importBlocks(generateReportBlocks()); + }); + } + + if (recipeBtn) { + recipeBtn.addEventListener('click', () => { + editor.importBlocks(generateRecipeBlocks()); + }); + } + + if (clearBtn) { + clearBtn.addEventListener('click', () => { + editor.importBlocks([]); + }); + } +}; + +const setupExportDemo = (container: HTMLElement, editor: DeesInputWysiwyg) => { + const exportBlocksBtn = container.querySelector('#btn-export-blocks') as HTMLButtonElement; + const exportHtmlBtn = container.querySelector('#btn-export-html') as HTMLButtonElement; + const exportMarkdownBtn = container.querySelector('#btn-export-markdown') as HTMLButtonElement; + const saveStateBtn = container.querySelector('#btn-save-state') as HTMLButtonElement; + const restoreStateBtn = container.querySelector('#btn-restore-state') as HTMLButtonElement; + + let savedState: any = null; + + if (exportBlocksBtn) { + exportBlocksBtn.addEventListener('click', () => { + const blocks = editor.exportBlocks(); + console.log('Exported blocks:', blocks); + alert(`Exported ${blocks.length} blocks to console. Check developer tools.`); + }); + } + + if (exportHtmlBtn) { + exportHtmlBtn.addEventListener('click', () => { + const html = editor.exportAsHtml(); + console.log('HTML Export:', html); + alert('HTML exported to console. Check developer tools.'); + }); + } + + if (exportMarkdownBtn) { + exportMarkdownBtn.addEventListener('click', () => { + const markdown = editor.exportAsMarkdown(); + console.log('Markdown Export:', markdown); + alert('Markdown exported to console. Check developer tools.'); + }); + } + + if (saveStateBtn) { + saveStateBtn.addEventListener('click', () => { + savedState = editor.exportState(); + console.log('Saved state:', savedState); + alert('Editor state saved!'); + }); + } + + if (restoreStateBtn) { + restoreStateBtn.addEventListener('click', () => { + if (savedState) { + editor.importState(savedState); + alert('Editor state restored!'); + } else { + alert('No saved state found. Save state first!'); + } + }); + } +}; + +const populateInitialContent = (editors: IDemoEditor) => { + // Article editor content + if (editors.article) { + setTimeout(() => { + const articleBlocks: IBlock[] = [ { id: 'intro-heading-' + Date.now(), - type: 'heading-2' as const, - content: 'Introduction' + type: 'heading-2', + content: 'Introduction to Modern Web Development' }, { id: 'intro-para-' + Date.now(), - type: 'paragraph' as const, + type: 'paragraph', content: 'Modern web development has evolved significantly over the past decade. In this article, we\'ll explore the key technologies and best practices that define web development in 2024.' }, { id: 'tech-heading-' + Date.now(), - type: 'heading-3' as const, + type: 'heading-3', content: 'Key Technologies' }, { id: 'tech-list-' + Date.now(), - type: 'list' as const, - content: 'TypeScript - Type-safe JavaScript development\nWeb Components - Native component model\nES Modules - Modern module system', + type: 'list', + content: 'TypeScript - Type-safe JavaScript development\nWeb Components - Native component model\nES Modules - Modern module system\nWebAssembly - High-performance computing', metadata: { listType: 'ordered' } }, - { - id: 'start-heading-' + Date.now(), - type: 'heading-3' as const, - content: 'Getting Started' - }, - { - id: 'start-para-' + Date.now(), - type: 'paragraph' as const, - content: 'To begin building modern web applications, you\'ll need:' - }, - { - id: 'req-list-' + Date.now(), - type: 'list' as const, - content: 'A solid understanding of JavaScript fundamentals\nFamiliarity with component-based architecture\nKnowledge of build tools and bundlers', - metadata: { listType: 'bullet' } - }, { id: 'quote-' + Date.now(), - type: 'quote' as const, + type: 'quote', content: 'The best way to predict the future is to invent it. - Alan Kay' }, { id: 'example-heading-' + Date.now(), - type: 'heading-3' as const, + type: 'heading-3', content: 'Code Example' }, { id: 'code-example-' + Date.now(), - type: 'code' as const, - content: 'class ModernWebApp extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: \'open\' });\n }\n \n connectedCallback() {\n this.render();\n }\n}' - }, - { - id: 'divider-' + Date.now(), - type: 'divider' as const, - content: ' ' - }, - { - id: 'conclusion-heading-' + Date.now(), - type: 'heading-3' as const, - content: 'Conclusion' - }, - { - id: 'conclusion-para-' + Date.now(), - type: 'paragraph' as const, - content: 'Embracing modern web standards and tools enables developers to build faster, more maintainable applications.' + type: 'code', + content: 'class ModernWebApp extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: \'open\' });\n }\n \n connectedCallback() {\n this.render();\n }\n}', + metadata: { language: 'javascript' } } ]; - - // Set the blocks instead of using .value with HTML - setTimeout(() => { - articleEditor.importBlocks(articleBlocks); - }, 500); - } - - // Initialize drag demo editor with sample content - if (dragDemoEditor) { - const dragDemoBlocks = [ + editors.article.importBlocks(articleBlocks); + }, 500); + } + + // Drag & Drop demo content + if (editors.dragDrop) { + setTimeout(() => { + const dragBlocks: IBlock[] = [ { id: 'drag-title-' + Date.now(), - type: 'heading-1' as const, + type: 'heading-1', content: 'Drag & Drop Demo' }, { id: 'drag-intro-' + Date.now(), - type: 'paragraph' as const, + type: 'paragraph', content: 'This editor demonstrates drag and drop functionality. Try dragging these blocks around!' }, { id: 'drag-heading-' + Date.now(), - type: 'heading-2' as const, + type: 'heading-2', content: 'How It Works' }, { id: 'drag-list-' + Date.now(), - type: 'list' as const, + type: 'list', content: 'Hover over any block to see the drag handle\nClick and hold the handle to start dragging\nDrag to reorder blocks\nRelease to drop in the new position', metadata: { listType: 'ordered' } }, { id: 'drag-quote-' + Date.now(), - type: 'quote' as const, + type: 'quote', content: 'The drag and drop feature makes it easy to reorganize your content without cutting and pasting.' }, - { - id: 'drag-code-' + Date.now(), - type: 'code' as const, - content: '// Example: The blocks can be reordered\nconst blocks = editor.exportBlocks();\n// Rearrange blocks array\neditor.importBlocks(blocks);' - }, { id: 'drag-divider-' + Date.now(), - type: 'divider' as const, - content: ' ' + type: 'divider', + content: '' }, { id: 'drag-footer-' + Date.now(), - type: 'paragraph' as const, + type: 'paragraph', content: 'Note: Divider blocks cannot be dragged, but other blocks can be moved around them.' } ]; - - setTimeout(() => { - dragDemoEditor.importBlocks(dragDemoBlocks); - }, 600); + editors.dragDrop.importBlocks(dragBlocks); + }, 600); + } +}; + +export const demoFunc = (): TemplateResult => html` + { + // Wait for elements to be ready + await new Promise(resolve => setTimeout(resolve, 500)); + + const editors = initializeEditors(elementArg); + + // Setup programmatic demo + if (editors.programmatic) { + setupProgrammaticDemo(elementArg, editors.programmatic); } - // Setup button handlers for programmatic demo - const generateReportBtn = elementArg.querySelector('#generate-report-btn'); - const generateRecipeBtn = elementArg.querySelector('#generate-recipe-btn'); - const clearEditorBtn = elementArg.querySelector('#clear-editor-btn'); - - if (generateReportBtn) { - generateReportBtn.addEventListener('click', () => { - const blocks = [ - { - id: 'title-' + Date.now(), - type: 'heading-1' as const, - content: 'System Performance Report' - }, - { - id: 'date-' + Date.now(), - type: 'paragraph' as const, - content: 'Generated on: ' + new Date().toLocaleString() - }, - { - id: 'summary-heading-' + Date.now(), - type: 'heading-2' as const, - content: 'Executive Summary' - }, - { - id: 'summary-' + Date.now(), - type: 'paragraph' as const, - content: 'This report provides an analysis of system performance metrics over the last 30 days.' - }, - { - id: 'metrics-heading-' + Date.now(), - type: 'heading-2' as const, - content: 'Key Metrics' - }, - { - id: 'metrics-list-' + Date.now(), - type: 'list' as const, - content: 'Average response time: 124ms\nUptime: 99.97%\nCPU utilization: 45%\nMemory usage: 2.3GB / 8GB', - metadata: { listType: 'bullet' } - }, - { - id: 'analysis-heading-' + Date.now(), - type: 'heading-2' as const, - content: 'Performance Analysis' - }, - { - id: 'analysis-quote-' + Date.now(), - type: 'quote' as const, - content: 'System performance remains within acceptable parameters with room for optimization in memory management.' - }, - { - id: 'code-heading-' + Date.now(), - type: 'heading-3' as const, - content: 'Sample Query Performance' - }, - { - id: 'code-block-' + Date.now(), - type: 'code' as const, - content: 'SELECT AVG(response_time) as avg_time,\n COUNT(*) as total_requests,\n DATE(created_at) as date\nFROM performance_logs\nWHERE created_at >= NOW() - INTERVAL 30 DAY\nGROUP BY DATE(created_at)\nORDER BY date DESC;' - }, - { - id: 'divider-' + Date.now(), - type: 'divider' as const, - content: ' ' - }, - { - id: 'footer-' + Date.now(), - type: 'paragraph' as const, - content: 'Report generated automatically by System Monitor v2.5.0' - } - ]; - - programmaticEditor.importBlocks(blocks); - }); + // Setup export demo + if (editors.exportDemo) { + setupExportDemo(elementArg, editors.exportDemo); } - if (generateRecipeBtn) { - generateRecipeBtn.addEventListener('click', () => { - const blocks = [ - { - id: 'recipe-title-' + Date.now(), - type: 'heading-1' as const, - content: 'Classic Margherita Pizza' - }, - { - id: 'recipe-intro-' + Date.now(), - type: 'paragraph' as const, - content: 'A traditional Italian pizza with fresh basil, mozzarella, and tomato sauce.' - }, - { - id: 'ingredients-heading-' + Date.now(), - type: 'heading-2' as const, - content: '🍕 Ingredients' - }, - { - id: 'dough-heading-' + Date.now(), - type: 'heading-3' as const, - content: 'For the Dough:' - }, - { - id: 'dough-list-' + Date.now(), - type: 'list' as const, - content: '500g tipo "00" flour\n325ml warm water\n10g salt\n7g active dry yeast\n2 tbsp olive oil', - metadata: { listType: 'bullet' } - }, - { - id: 'toppings-heading-' + Date.now(), - type: 'heading-3' as const, - content: 'For the Toppings:' - }, - { - id: 'toppings-list-' + Date.now(), - type: 'list' as const, - content: '400g canned San Marzano tomatoes\n250g fresh mozzarella\nFresh basil leaves\nExtra virgin olive oil\nSalt and pepper to taste', - metadata: { listType: 'bullet' } - }, - { - id: 'instructions-heading-' + Date.now(), - type: 'heading-2' as const, - content: '👨‍🍳 Instructions' - }, - { - id: 'steps-list-' + Date.now(), - type: 'list' as const, - content: 'Dissolve yeast in warm water and let stand for 5 minutes\nMix flour and salt, create a well in center\nAdd yeast mixture and olive oil\nKnead for 10 minutes until smooth\nLet rise for 1-2 hours until doubled\nPunch down and divide into portions\nRoll out each portion to 12-inch circles\nTop with crushed tomatoes, mozzarella, and basil\nBake at 475°F (245°C) for 10-12 minutes', - metadata: { listType: 'ordered' } - }, - { - id: 'tip-' + Date.now(), - type: 'quote' as const, - content: 'Pro tip: For an authentic taste, use a pizza stone and preheat it in the oven for at least 30 minutes before baking.' - }, - { - id: 'divider-2-' + Date.now(), - type: 'divider' as const, - content: ' ' - }, - { - id: 'servings-' + Date.now(), - type: 'paragraph' as const, - content: 'Servings: 4 pizzas | Prep time: 2 hours | Cook time: 12 minutes' - } - ]; - - programmaticEditor.importBlocks(blocks); - }); - } + // Populate initial content + populateInitialContent(editors); - if (clearEditorBtn) { - clearEditorBtn.addEventListener('click', () => { - programmaticEditor.importBlocks([]); - }); - } + // Log initialization + console.log('WYSIWYG Demo initialized with editors:', Object.keys(editors)); }}> - - -
- -

A powerful block-based editor with slash commands, keyboard shortcuts, and multiple output formats. Perfect for content creation, blog posts, documentation, and more.

-
+ .demo-button:hover { + background: #444; + border-color: #666; + } + } + + .export-info-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 16px; + margin-bottom: 24px; + } + + .export-info-card { + padding: 16px; + border-radius: 8px; + } + + .export-info-card.blocks { + background: rgba(0, 102, 204, 0.1); + } + + .export-info-card.html { + background: rgba(76, 175, 80, 0.1); + } + + .export-info-card.markdown { + background: rgba(255, 152, 0, 0.1); + } + + .export-info-card.state { + background: rgba(156, 39, 176, 0.1); + } + + .export-info-card strong { + display: block; + margin-bottom: 8px; + } + + .export-info-card.blocks strong { + color: #0066cc; + } + + .export-info-card.html strong { + color: #4CAF50; + } + + .export-info-card.markdown strong { + color: #FF9800; + } + + .export-info-card.state strong { + color: #9C27B0; + } + + .export-info-card p { + margin: 0; + font-size: 14px; + line-height: 1.5; + } + `} + + +
+ +

+ A powerful block-based editor with slash commands, keyboard shortcuts, and multiple output formats. + Perfect for content creation, blog posts, documentation, and more. +

+ +
Slash commands (/) @@ -459,68 +668,75 @@ export const demoFunc = () => html`
-
-

⌨️ Keyboard Shortcuts

-
-
- / Slash commands +
+

⌨️ Keyboard Shortcuts

+
+
+ / Slash commands
-
- # Heading 1 +
+ # Heading 1
-
- ## Heading 2 +
+ ## Heading 2
-
- ### Heading 3 +
+ ### Heading 3
-
- > Quote +
+ > Quote
-
- \`\`\` Code block +
+ \`\`\` Code block
-
- * or - Bullet list +
+ * or - Bullet list
-
- 1. Numbered list +
+ 1. Numbered list
-
- --- Divider +
+ --- Divider
- -

Perfect for creating rich content with multiple block types. The editor preserves formatting and provides a clean editing experience.

+ +

+ Perfect for creating rich content with multiple block types. + The editor preserves formatting and provides a clean editing experience. +

Welcome to Our Blog

This is an example blog post that demonstrates the capabilities of our WYSIWYG editor.

Features Overview

Our editor supports multiple block types including headings, paragraphs, quotes, and more.

The best way to predict the future is to invent it.

You can also create lists and code blocks for technical content.

'} - .outputFormat=${'html'} + id="editor-article" + label="Blog Post Content" + description="Write your article using various formatting options" + outputFormat="html" >
- -

Easily rearrange your content blocks by dragging them. Hover over any block to reveal the drag handle on the left side.

+ +

+ Easily rearrange your content blocks by dragging them. + Hover over any block to reveal the drag handle on the left side. +

-
+
💡 Tips: -
    +
    • Hover over any block to see the drag handle (⋮⋮) on the left
    • Click and hold the drag handle to start dragging
    • Blue indicators show where the block will be dropped
    • @@ -530,188 +746,321 @@ export const demoFunc = () => html`
- -

Create comprehensive tutorials and documentation with code examples, lists, and structured content.

+ +

+ Create comprehensive tutorials and documentation with code examples, lists, and structured content. +

README.md\ngit add README.md\n```\n\n#### Committing Changes\n\n```bash\ngit commit -m "Initial commit"\n```\n\n> **Best Practice:** Write clear, descriptive commit messages that explain what changes were made and why.\n\n### 4. Working with Branches\n\nBranches allow you to work on features independently:\n\n```bash\n# Create and switch to a new branch\ngit checkout -b feature-branch\n\n# Make changes and commit\ngit add .\ngit commit -m "Add new feature"\n\n# Switch back to main\ngit checkout main\n\n# Merge the feature\ngit merge feature-branch\n```\n\n---\n\n## Common Commands Reference\n\n| Command | Description |\n|---------|-------------|\n| `git status` | Check repository status |\n| `git log` | View commit history |\n| `git diff` | Show changes |\n| `git pull` | Fetch and merge changes |\n| `git push` | Upload changes to remote |\n\n## Next Steps\n\n1. Learn about remote repositories\n2. Explore advanced Git features\n3. Practice with real projects\n4. Contribute to open source\n\n**Happy coding!** 🚀'} + id="editor-tutorial" + label="Git Tutorial" + description="Step-by-step guide with commands and explanations" + outputFormat="markdown" + value="# Git Tutorial for Beginners + +Git is a distributed version control system that helps you track changes in your code over time. This tutorial will guide you through the basics. + +## Prerequisites + +Before starting, ensure you have: + +- Git installed on your system +- A text editor or IDE +- Basic command line knowledge + +## Getting Started + +### 1. Configure Git + +First, set up your identity: + +\`\`\`bash +git config --global user.name "Your Name" +git config --global user.email "your.email@example.com" +\`\`\` + +### 2. Initialize a Repository + +Create a new Git repository: + +\`\`\`bash +mkdir my-project +cd my-project +git init +\`\`\` + +### 3. Basic Git Workflow + +#### Adding Files + +Create a file and add it to staging: + +\`\`\`bash +echo "# My Project" > README.md +git add README.md +\`\`\` + +#### Committing Changes + +\`\`\`bash +git commit -m "Initial commit" +\`\`\` + +> **Best Practice:** Write clear, descriptive commit messages that explain what changes were made and why. + +### 4. Working with Branches + +Branches allow you to work on features independently: + +\`\`\`bash +# Create and switch to a new branch +git checkout -b feature-branch + +# Make changes and commit +git add . +git commit -m "Add new feature" + +# Switch back to main +git checkout main + +# Merge the feature +git merge feature-branch +\`\`\` + +--- + +## Common Commands Reference + +| Command | Description | +|---------|-------------| +| \`git status\` | Check repository status | +| \`git log\` | View commit history | +| \`git diff\` | Show changes | +| \`git pull\` | Fetch and merge changes | +| \`git push\` | Upload changes to remote | + +## Next Steps + +1. Learn about remote repositories +2. Explore advanced Git features +3. Practice with real projects +4. Contribute to open source + +**Happy coding!** 🚀" >
- -

Choose between HTML and Markdown output formats depending on your needs. Perfect for static site generators, documentation systems, or any content management workflow.

+ +

+ Choose between HTML and Markdown output formats depending on your needs. + Perfect for static site generators, documentation systems, or any content management workflow. +

-
+
Q4 Planning Meeting

Date: December 15, 2024
Attendees: Product Team, Engineering, Design

Agenda Items'}>
  1. Review Q3 achievements
  2. Set Q4 objectives
  3. Resource allocation
  4. Timeline discussion

Key Decisions'}>
  • Launch new dashboard feature by end of January
  • Increase engineering team by 2 developers
  • Implement weekly design reviews
"Focus on user experience improvements based on Q3 feedback" - Product Manager

Action Items'}>
  • Sarah: Create detailed project timeline
  • Mike: Draft technical requirements
  • Lisa: Schedule user research sessions

Next meeting: January 5, 2025

'} + id="editor-meeting" + label="Meeting Notes" + description="Structured meeting documentation" + outputFormat="html" + value="

Q4 Planning Meeting

Date: December 15, 2024
Attendees: Product Team, Engineering, Design

Agenda Items

  1. Review Q3 achievements
  2. Set Q4 objectives
  3. Resource allocation
  4. Timeline discussion

Key Decisions

  • Launch new dashboard feature by end of January
  • Increase engineering team by 2 developers
  • Implement weekly design reviews
"Focus on user experience improvements based on Q3 feedback" - Product Manager

Action Items

  • Sarah: Create detailed project timeline
  • Mike: Draft technical requirements
  • Lisa: Schedule user research sessions

Next meeting: January 5, 2025

" >
**Pro tip:** Room temperature ingredients mix better and create a more uniform dough.\n\n### Step 4: Add Wet Ingredients\n\nBeat in eggs one at a time, then add vanilla extract.\n\n### Step 5: Combine and Bake\n\nGradually blend in flour mixture, then stir in chocolate chips. Drop rounded tablespoons onto ungreased cookie sheets.\n\n---\n\n**Baking time:** 9-11 minutes or until golden brown\n\n**Yield:** About 5 dozen cookies'} + id="editor-recipe" + label="Recipe Blog Post" + description="Food blog with mixed content" + outputFormat="markdown" + value="# Ultimate Chocolate Chip Cookies + +There's nothing quite like the smell of freshly baked chocolate chip cookies. This recipe has been perfected over years of testing! + +## Ingredients + +- 2¼ cups all-purpose flour +- 1 tsp baking soda +- 1 tsp salt +- 1 cup butter, softened +- ¾ cup granulated sugar +- ¾ cup packed brown sugar +- 2 large eggs +- 2 tsp vanilla extract +- 2 cups chocolate chips + +## Instructions + +### Step 1: Preparation + +Preheat your oven to **375°F (190°C)**. This temperature is crucial for achieving the perfect texture. + +### Step 2: Mix Dry Ingredients + +In a medium bowl, whisk together: + +1. Flour +2. Baking soda +3. Salt + +### Step 3: Cream Butter and Sugars + +\`\`\` +Cream butter and sugars for 3-4 minutes +until light and fluffy +\`\`\` + +> **Pro tip:** Room temperature ingredients mix better and create a more uniform dough. + +### Step 4: Add Wet Ingredients + +Beat in eggs one at a time, then add vanilla extract. + +### Step 5: Combine and Bake + +Gradually blend in flour mixture, then stir in chocolate chips. Drop rounded tablespoons onto ungreased cookie sheets. + +--- + +**Baking time:** 9-11 minutes or until golden brown + +**Yield:** About 5 dozen cookies" >
- -

Create complex documents with mixed content types. The editor handles all formatting seamlessly.

+ +

+ Create complex documents with mixed content types. The editor handles all formatting seamlessly. +

API Documentation

Welcome to our API documentation. Below you\'ll find examples of how to use our endpoints.

Authentication

All API requests require authentication using an API key:

Authorization: Bearer YOUR_API_KEY

Endpoints

GET /users'}>

Retrieve a list of users from the system.

curl -X GET https://api.example.com/users \\\n  -H "Authorization: Bearer YOUR_API_KEY"
Note: Rate limiting applies to all endpoints. You can make up to 100 requests per minute.

POST /users'}>

Create a new user in the system.

{\n  "name": "John Doe",\n  "email": "john@example.com",\n  "role": "user"\n}

For more information, please refer to our complete documentation.

'} - .outputFormat=${'html'} + id="editor-technical" + label="Technical Documentation" + description="Create technical docs with code examples and structured content" + value="

API Documentation

Welcome to our API documentation. Below you'll find examples of how to use our endpoints.

Authentication

All API requests require authentication using an API key:

Authorization: Bearer YOUR_API_KEY

Endpoints

GET /users

Retrieve a list of users from the system.

curl -X GET https://api.example.com/users \\
+  -H "Authorization: Bearer YOUR_API_KEY"
Note: Rate limiting applies to all endpoints. You can make up to 100 requests per minute.

POST /users

Create a new user in the system.

{
+  "name": "John Doe",
+  "email": "john@example.com",
+  "role": "user"
+}

For more information, please refer to our complete documentation.

" + outputFormat="html" >
- -

Seamlessly integrates with dees-form for complete form solutions. All standard form features like validation, required fields, and data binding work out of the box.

+ +

+ Seamlessly integrates with dees-form for complete form solutions. + All standard form features like validation, required fields, and data binding work out of the box. +

- -

Create content programmatically using the block API for dynamic document generation.

+ +

+ Create content programmatically using the block API for dynamic document generation. +

-
- +
+ - + - +
- -

The WYSIWYG editor provides multiple export formats and lossless save/restore capabilities for maximum flexibility.

+ +

+ The WYSIWYG editor provides multiple export formats and lossless save/restore capabilities for maximum flexibility. +

-
-
- Lossless Blocks -

Export and import raw block structure for perfect round-trip editing

+
+
+ Lossless Blocks +

Export and import raw block structure for perfect round-trip editing

-
- HTML Export -

Get clean, semantic HTML regardless of output format setting

+
+ HTML Export +

Get clean, semantic HTML regardless of output format setting

-
- Markdown Export -

Export as Markdown for docs, READMEs, and static sites

+
+ Markdown Export +

Export as Markdown for docs, READMEs, and static sites

-
- State Management -

Save and restore complete editor state including settings

+
+ State Management +

Save and restore complete editor state including settings

Software Release Notes

Version 2.5.0 - Released December 15, 2024

🎉 New Features

  • Added dark mode support across all components
  • Implemented real-time collaboration features
  • New dashboard analytics widgets
  • Export functionality for all report types

🐛 Bug Fixes

  • Fixed memory leak in data processing module
  • Resolved authentication timeout issues
  • Corrected timezone handling in scheduled tasks

⚡ Performance Improvements

Page load times reduced by 40% through lazy loading and code splitting

🔧 Technical Details

// New API endpoint for batch operations\nPOST /api/v2/batch\n{\n  "operations": [\n    { "method": "GET", "path": "/users/123" },\n    { "method": "PUT", "path": "/settings", "body": {...} }\n  ]\n}

💡 Migration Guide

  1. Update your dependencies to the latest versions
  2. Run database migrations: npm run migrate
  3. Clear cache: npm run cache:clear
  4. Restart all services

For questions or issues, please contact the development team or file a ticket in our issue tracker.

'} + id="editor-export" + label="Export Demo Editor" + description="Try the export buttons below to see different output formats" + value="

Software Release Notes

Version 2.5.0 - Released December 15, 2024

🎉 New Features

  • Added dark mode support across all components
  • Implemented real-time collaboration features
  • New dashboard analytics widgets
  • Export functionality for all report types

🐛 Bug Fixes

  • Fixed memory leak in data processing module
  • Resolved authentication timeout issues
  • Corrected timezone handling in scheduled tasks

⚡ Performance Improvements

Page load times reduced by 40% through lazy loading and code splitting

🔧 Technical Details

// New API endpoint for batch operations
+POST /api/v2/batch
+{
+  "operations": [
+    { "method": "GET", "path": "/users/123" },
+    { "method": "PUT", "path": "/settings", "body": {...} }
+  ]
+}

💡 Migration Guide

  1. Update your dependencies to the latest versions
  2. Run database migrations: npm run migrate
  3. Clear cache: npm run cache:clear
  4. Restart all services

For questions or issues, please contact the development team or file a ticket in our issue tracker.

" >
-
- +
+ - + - + - + - +