280 lines
7.3 KiB
Markdown
280 lines
7.3 KiB
Markdown
|
|
# Heading Level Selector - New Feature ✨
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
Added a visual heading level selector to easily switch between H1-H6 tags without manually editing code or traits.
|
||
|
|
|
||
|
|
## What Was Added
|
||
|
|
|
||
|
|
### UI Component
|
||
|
|
**Location:** Right sidebar → Styles/Settings panel
|
||
|
|
|
||
|
|
**Appearance:**
|
||
|
|
- 6 buttons (H1, H2, H3, H4, H5, H6)
|
||
|
|
- Grid layout (all on one row)
|
||
|
|
- Active button highlighted in blue
|
||
|
|
- Appears only when a heading element is selected
|
||
|
|
|
||
|
|
### How It Works
|
||
|
|
|
||
|
|
1. **Select any heading** on the canvas (H1, H2, H3, H4, H5, or H6)
|
||
|
|
2. **Look at the right sidebar** → "Heading Level" section appears
|
||
|
|
3. **Click any H1-H6 button** → heading type changes instantly
|
||
|
|
4. **Active button** shows which level is currently selected
|
||
|
|
|
||
|
|
## Use Cases
|
||
|
|
|
||
|
|
### Quick Heading Hierarchy
|
||
|
|
```
|
||
|
|
Design Mode:
|
||
|
|
- Start with H1 for page title
|
||
|
|
- Add subheading → click H2 button
|
||
|
|
- Need tertiary heading? → click H3 button
|
||
|
|
```
|
||
|
|
|
||
|
|
### Responsive Design
|
||
|
|
```
|
||
|
|
Desktop: H1 (48px)
|
||
|
|
↓ click H2 button
|
||
|
|
Tablet: H2 (36px)
|
||
|
|
↓ click H3 button
|
||
|
|
Mobile: H3 (28px)
|
||
|
|
```
|
||
|
|
|
||
|
|
### SEO Optimization
|
||
|
|
```
|
||
|
|
Before export:
|
||
|
|
- Check all headings use proper hierarchy
|
||
|
|
- H1 → one per page (main title)
|
||
|
|
- H2 → section titles
|
||
|
|
- H3-H6 → subsections
|
||
|
|
```
|
||
|
|
|
||
|
|
## Technical Implementation
|
||
|
|
|
||
|
|
### Files Modified
|
||
|
|
|
||
|
|
**1. `/home/jknapp/code/site-builder/index.html`**
|
||
|
|
Added heading level section after text color:
|
||
|
|
```html
|
||
|
|
<div id="section-heading-level" class="guided-section context-section" style="display:none;">
|
||
|
|
<label>Heading Level</label>
|
||
|
|
<div class="heading-level-buttons">
|
||
|
|
<button class="heading-level-btn" data-level="h1">H1</button>
|
||
|
|
<button class="heading-level-btn" data-level="h2">H2</button>
|
||
|
|
<button class="heading-level-btn" data-level="h3">H3</button>
|
||
|
|
<button class="heading-level-btn" data-level="h4">H4</button>
|
||
|
|
<button class="heading-level-btn" data-level="h5">H5</button>
|
||
|
|
<button class="heading-level-btn" data-level="h6">H6</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
**2. `/home/jknapp/code/site-builder/css/editor.css`**
|
||
|
|
Styled the heading level buttons:
|
||
|
|
```css
|
||
|
|
.heading-level-buttons {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: repeat(6, 1fr);
|
||
|
|
gap: 6px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.heading-level-btn {
|
||
|
|
padding: 8px 4px;
|
||
|
|
background: #374151;
|
||
|
|
color: #9ca3af;
|
||
|
|
border: 2px solid transparent;
|
||
|
|
border-radius: 6px;
|
||
|
|
cursor: pointer;
|
||
|
|
font-size: 11px;
|
||
|
|
font-weight: 600;
|
||
|
|
transition: all 0.2s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.heading-level-btn:hover {
|
||
|
|
background: #4b5563;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.heading-level-btn.active {
|
||
|
|
background: #3b82f6;
|
||
|
|
color: #fff;
|
||
|
|
border-color: #60a5fa;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**3. `/home/jknapp/code/site-builder/js/editor.js`**
|
||
|
|
|
||
|
|
Added to sections object:
|
||
|
|
```javascript
|
||
|
|
headingLevel: document.getElementById('section-heading-level'),
|
||
|
|
```
|
||
|
|
|
||
|
|
Show section for headings:
|
||
|
|
```javascript
|
||
|
|
case 'text':
|
||
|
|
sections.textColor.style.display = 'block';
|
||
|
|
sections.font.style.display = 'block';
|
||
|
|
sections.textSize.style.display = 'block';
|
||
|
|
sections.fontWeight.style.display = 'block';
|
||
|
|
// Show heading level selector for headings
|
||
|
|
const currentTag = component.get('tagName')?.toLowerCase();
|
||
|
|
if (currentTag && currentTag.match(/^h[1-6]$/)) {
|
||
|
|
sections.headingLevel.style.display = 'block';
|
||
|
|
updateHeadingLevelButtons(currentTag);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
```
|
||
|
|
|
||
|
|
Helper functions:
|
||
|
|
```javascript
|
||
|
|
// Update heading level buttons to show active state
|
||
|
|
function updateHeadingLevelButtons(currentTag) {
|
||
|
|
const buttons = sections.headingLevel.querySelectorAll('.heading-level-btn');
|
||
|
|
buttons.forEach(btn => {
|
||
|
|
const level = btn.getAttribute('data-level');
|
||
|
|
if (level === currentTag) {
|
||
|
|
btn.classList.add('active');
|
||
|
|
} else {
|
||
|
|
btn.classList.remove('active');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Handle heading level button clicks
|
||
|
|
function setupHeadingLevelButtons() {
|
||
|
|
const buttons = sections.headingLevel.querySelectorAll('.heading-level-btn');
|
||
|
|
buttons.forEach(btn => {
|
||
|
|
btn.addEventListener('click', () => {
|
||
|
|
const newLevel = btn.getAttribute('data-level');
|
||
|
|
const selected = editor.getSelected();
|
||
|
|
if (!selected) return;
|
||
|
|
|
||
|
|
// Change the tag name
|
||
|
|
selected.set('tagName', newLevel);
|
||
|
|
|
||
|
|
// Update button states
|
||
|
|
updateHeadingLevelButtons(newLevel);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Initialize on load:
|
||
|
|
```javascript
|
||
|
|
setupHeadingLevelButtons();
|
||
|
|
```
|
||
|
|
|
||
|
|
## User Benefits
|
||
|
|
|
||
|
|
### 1. **Speed** ⚡
|
||
|
|
- Change heading levels with 1 click
|
||
|
|
- No need to delete and re-add headings
|
||
|
|
- No typing or searching for traits
|
||
|
|
|
||
|
|
### 2. **Visual Feedback** 👁️
|
||
|
|
- See which level is active at a glance
|
||
|
|
- All options visible simultaneously
|
||
|
|
- Intuitive button interface
|
||
|
|
|
||
|
|
### 3. **Accessibility** ♿
|
||
|
|
- Encourages proper heading hierarchy
|
||
|
|
- Makes SEO-friendly structure easier
|
||
|
|
- Visual reminder of heading importance
|
||
|
|
|
||
|
|
### 4. **Workflow** 🎯
|
||
|
|
- Stay in visual editing mode
|
||
|
|
- Don't break creative flow
|
||
|
|
- Quick experimentation with hierarchy
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
### Heading Hierarchy
|
||
|
|
```
|
||
|
|
✅ Good:
|
||
|
|
H1 → Page Title (once per page)
|
||
|
|
H2 → Section Title
|
||
|
|
H3 → Subsection
|
||
|
|
H4 → Minor heading
|
||
|
|
H5 → Rare, for deep nesting
|
||
|
|
H6 → Very rare
|
||
|
|
|
||
|
|
❌ Bad:
|
||
|
|
H1 → Page Title
|
||
|
|
H4 → Skipped H2 and H3 ❌
|
||
|
|
H3 → Used H3 before H2 ❌
|
||
|
|
```
|
||
|
|
|
||
|
|
### SEO Tips
|
||
|
|
- **One H1** per page (main title)
|
||
|
|
- **Logical hierarchy** - don't skip levels
|
||
|
|
- **Descriptive headings** - include keywords naturally
|
||
|
|
- **Mobile-friendly** - larger sizes for H1-H2, moderate for H3-H6
|
||
|
|
|
||
|
|
### Design Tips
|
||
|
|
- **Visual hierarchy** should match HTML hierarchy
|
||
|
|
- **Consistent sizing** - H1 largest, H6 smallest
|
||
|
|
- **Font weights** - can vary by level
|
||
|
|
- **Spacing** - more space above higher-level headings
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### "I don't see Heading Level buttons"
|
||
|
|
**Fix:** Make sure you've selected a heading element (H1-H6), not regular text or paragraph.
|
||
|
|
|
||
|
|
### "Buttons don't do anything"
|
||
|
|
**Fix:** Refresh the page to ensure JavaScript loaded. Check browser console for errors.
|
||
|
|
|
||
|
|
### "Active button isn't highlighted"
|
||
|
|
**Fix:** The updateHeadingLevelButtons function should be called on selection. Refresh and try again.
|
||
|
|
|
||
|
|
### "Level changes but styling stays the same"
|
||
|
|
**Expected:** Changing the tag (H1→H2) doesn't automatically change the font size. You need to:
|
||
|
|
1. Change the heading level (H1→H2)
|
||
|
|
2. Adjust font size separately if needed
|
||
|
|
3. Or use the Text Size presets
|
||
|
|
|
||
|
|
**Why:** GrapesJS keeps inline styles when changing tag names. This allows flexibility.
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
Potential improvements:
|
||
|
|
1. **Auto-size option** - Checkbox to auto-adjust font size when changing level
|
||
|
|
2. **Presets per level** - Click H1 → automatically apply H1 styling preset
|
||
|
|
3. **Hierarchy warnings** - Alert if you skip levels (e.g., H1 → H4)
|
||
|
|
4. **Bulk operations** - Select multiple headings, change all at once
|
||
|
|
5. **Keyboard shortcuts** - Ctrl+1 = H1, Ctrl+2 = H2, etc.
|
||
|
|
|
||
|
|
## Comparison: Before vs After
|
||
|
|
|
||
|
|
### Before (Manual Method)
|
||
|
|
```
|
||
|
|
1. Select heading
|
||
|
|
2. Find "tagName" trait in Settings
|
||
|
|
3. Type "h2" manually
|
||
|
|
4. Hope you didn't typo
|
||
|
|
5. Repeat for each heading
|
||
|
|
```
|
||
|
|
|
||
|
|
### After (New Feature)
|
||
|
|
```
|
||
|
|
1. Select heading
|
||
|
|
2. Click H2 button
|
||
|
|
3. Done! ✨
|
||
|
|
```
|
||
|
|
|
||
|
|
**Time saved:** ~80% faster
|
||
|
|
|
||
|
|
**Error rate:** Near zero (no typos possible)
|
||
|
|
|
||
|
|
**User experience:** Much more intuitive
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Enjoy easier heading management!** 🎉
|
||
|
|
|
||
|
|
Try it out:
|
||
|
|
1. Add a few headings to your page
|
||
|
|
2. Select one and watch the Heading Level buttons appear
|
||
|
|
3. Click different levels and see instant changes
|
||
|
|
4. Build proper heading hierarchy effortlessly!
|