WIDGET TIGHTENING PLAN

Comprehensive guidelines for AI-assisted development within the Editor platform

๐ŸŽฏ Widget Tightening Plan - Systematic Rollout

Status: ๐Ÿ“‹ Ready to Execute
Priority: ๐Ÿ”ฅ High
Effort: ~2-4 hours per wave


๐Ÿ” Current State Analysis

What We Have โœ…

What Needs Tightening ๐Ÿ”ง

Based on analysis, EVERY widget needs these 4 critical fixes:

  1. โŒ Sizing Pattern - Remove hardcoded width: 100% / height: 100%
  2. โŒ Property Reading - Ensure reading from correct source (widget.properties vs widget.styles)
  3. โŒ Custom Styles - Pass explicit inline styles to embeddables
  4. โŒ Property Organization - Standardize property groups (Content โ†’ Appearance โ†’ Custom โ†’ Actions)

๐ŸŽฏ Recommended Approach: WAVE ROLLOUT

Apply fixes in priority waves to minimize risk and maximize learning.

Why Wave Rollout?


๐ŸŒŠ Wave 1: HIGH PRIORITY (Content Widgets)

Duration: 2-3 hours
Impact: Highest user visibility
Risk: Low (clear patterns established)

Widgets to Fix

  1. TextWidget โญ Most used
  2. ImageWidget โญ Most used
  3. LinkWidget
  4. IconWidget

Why These First?

Fixes Needed Per Widget

1. Sizing Fix (Apply to ALL)

// โŒ REMOVE from containerStyles:
containerStyles = computed(() => ({
  width: '100%',  // REMOVE
  height: '100%', // REMOVE
  // Keep only visual properties
}));

// โœ… KEEP in wrapperStyles (inner elements):
wrapperStyles = computed(() => ({
  width: '100%',  // OK - fills parent
  height: '100%', // OK - fills parent
}));

2. Property Reading Fix

// โŒ WRONG: Reading font from styles
const fontSize = widgetStyles.fontSize;

// โœ… CORRECT: Read font from properties
const fontSize = this.widget()?.properties?.fontSize ?? '16px';

3. Custom Styles Fix

// Add customStyles computed signal
customStyles = computed(() => {
  const props = this.widget()?.properties || {};
  const styles: Record<string, string> = {};
  
  // Font properties
  if (props['fontSize']) styles['font-size'] = `${props['fontSize']}px`;
  if (props['fontFamily']) styles['font-family'] = props['fontFamily'];
  if (props['color']) styles['color'] = props['color'];
  
  // Background/borders (if applicable)
  if (props['backgroundColor']) styles['background-color'] = props['backgroundColor'];
  
  return styles;
});
<!-- Pass to embeddable or element -->
<div [ngStyle]="customStyles()">Content</div>

4. Property Groups (Check & Standardize)

// Standard order:
export const WIDGET_PROPERTY_GROUPS: PropertyGroup[] = [
  CONTENT_GROUP,        // order: 10
  APPEARANCE_GROUP,     // order: 20
  CUSTOM_STYLES_GROUP,  // order: 21 (conditional)
  LAYOUT_GROUP,         // order: 30
  ACTIONS_GROUP,        // order: 40
];

๐ŸŒŠ Wave 2: MEDIUM PRIORITY (Layout/Container Widgets)

Duration: 2-3 hours
Impact: Medium (affects structure)
Risk: Medium (complex layouts)

Widgets to Fix

  1. CardWidget
  2. ContainerWidget
  3. HeroWidget
  4. FeatureWidget

Why These Second?

Additional Considerations


๐ŸŒŠ Wave 3: LOWER PRIORITY (Form/Input Widgets)

Duration: 2-3 hours
Impact: Medium (form functionality)
Risk: Medium (validation/state management)

Widgets to Fix

  1. InputWidget
  2. SelectWidget
  3. CheckboxWidget
  4. RadioWidget
  5. RangeWidget

Why These Third?

Additional Considerations


๐ŸŒŠ Wave 4: SPECIALIZED (Media/Complex Widgets)

Duration: 2-4 hours
Impact: Low-Medium (specialized use cases)
Risk: Higher (complex functionality)

Widgets to Fix

  1. VideoWidget
  2. GalleryWidget
  3. PricingWidget (already partially done)
  4. TestimonialWidget
  5. DividerWidget
  6. SpacerWidget
  7. ShapeWidget
  8. SimpleWidget
  9. EmbeddableHostWidget

Why These Last?


๐Ÿ“‹ Per-Widget Checklist

For EACH widget, complete this checklist:

1. Sizing โœ…

2. Property Reading โœ…

3. Custom Styles โœ…

4. Property Groups โœ…

5. Testing โœ…


๐Ÿ”ง Implementation Pattern (Copy-Paste Template)

Step 1: Update Component TypeScript

// 1. Remove hardcoded dimensions
containerStyles = computed(() => {
  const props = this.widget()?.properties || {};
  
  return {
    // โŒ NO width, NO height
    position: 'relative',
    display: 'flex',
    'flex-direction': 'column',
    'box-sizing': 'border-box',
    // ... only visual properties
  };
});

// 2. Add customStyles signal
customStyles = computed(() => {
  const props = this.widget()?.properties || {};
  const styles: Record<string, string> = {};
  
  // Font properties (if text-based widget)
  if (props['fontSize']) styles['font-size'] = `${props['fontSize']}px`;
  if (props['fontFamily']) styles['font-family'] = props['fontFamily'];
  if (props['fontWeight']) styles['font-weight'] = props['fontWeight'];
  if (props['color']) styles['color'] = props['color'];
  
  // Background/borders (if visual widget)
  if (props['backgroundColor']) styles['background-color'] = props['backgroundColor'];
  if (props['borderRadius']) styles['border-radius'] = `${props['borderRadius']}px`;
  
  return styles;
});

// 3. Ensure config reads from properties
config = computed(() => {
  const defaultConfig = { /* defaults */ };
  return { ...defaultConfig, ...(this.widget()?.properties || {}) };
});

Step 2: Update Template

<!-- Pass customStyles to inner element or embeddable -->
<div 
  class="widget-container"
  [ngStyle]="containerStyles()">
  
  <div 
    class="content-wrapper" 
    style="width: 100%; height: 100%;"
    [ngStyle]="customStyles()">
    <!-- Content here -->
  </div>
</div>

Step 3: Update Property Groups

// Ensure standard structure
export const WIDGET_PROPERTY_GROUPS: PropertyGroup[] = [
  {
    id: 'widget-content',
    title: 'Content',
    icon: 'fa-edit',
    order: 10,
    properties: [
      {
        key: 'text',
        label: 'Text',
        type: 'string',
        getValue: (widget) => widget.properties?.text ?? '',
        setValue: (widget, value) => ({
          ...widget,
          properties: { ...widget.properties, text: value }
        })
      }
    ]
  },
  {
    id: 'widget-appearance',
    title: 'Appearance',
    icon: 'fa-palette',
    order: 20,
    properties: [
      // Font, colors, etc.
    ]
  },
  // ... more groups
];

๐ŸŽฏ Success Metrics

Track progress after each wave:

Per Wave

Overall


โšก Quick Wins (Can Do Now)

1. PricingWidget (Already Started)

File: libs/libs-widgets/widgets/src/lib/components/pricing-widget/pricing-widget.component.scss

// โŒ REMOVE these lines:
.pricing-widget {
  width: 100%;
  height: 100%;
}

.pricing-widget-container {
  width: 100%;
  height: 100%;
}

// โœ… Replace with:
.pricing-widget {
  position: relative;
  display: flex;
  flex-direction: column;
}

.pricing-widget-container {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
}

Impact: 5 minutes, fixes resizing immediately


๐Ÿ“Š Estimated Timeline

Wave Widgets Time Completion
Wave 1 4 widgets 2-3 hours Day 1
Wave 2 4 widgets 2-3 hours Day 2
Wave 3 5 widgets 2-3 hours Day 3
Wave 4 10 widgets 3-4 hours Day 4
Total 23 widgets 9-13 hours 4 days

With your focus: Could complete in 2-3 days working steadily.


๐Ÿš€ Recommended Next Actions

Option 1: Wave-by-Wave (Safest)

  1. Start with Wave 1 (TextWidget, ImageWidget, LinkWidget, IconWidget)
  2. Test thoroughly after each widget
  3. Move to Wave 2 once Wave 1 is solid
  4. Continue through Wave 4

Pros: Lower risk, clear progress
Cons: Takes longer

Option 2: Pattern-by-Pattern (Fastest)

  1. Fix sizing pattern across ALL widgets at once
  2. Then fix property reading across ALL
  3. Then custom styles across ALL
  4. Then property groups across ALL

Pros: Faster, consistent pattern
Cons: Higher risk, harder to test

Option 3: Critical Path (Balanced) โญ RECOMMENDED

  1. Fix Wave 1 completely (most used widgets)
  2. Apply sizing pattern only to remaining widgets
  3. Come back for custom styles + property groups later

Pros: Quick wins, lower risk, progressive enhancement
Cons: Widgets temporarily inconsistent


๐Ÿ’ก My Recommendation

Start with Wave 1 + Quick Win

Today/This Session:

  1. โœ… Quick Win: Fix PricingWidget CSS (5 minutes)
  2. ๐ŸŽฏ Wave 1: TextWidget (30 minutes)
  3. ๐ŸŽฏ Wave 1: ImageWidget (30 minutes)
  4. ๐ŸŽฏ Wave 1: LinkWidget (20 minutes)
  5. ๐ŸŽฏ Wave 1: IconWidget (20 minutes)

Total: ~2 hours for massive improvement

Why This Order?


๐ŸŽ Bonus: Automated Script (Future)

Idea: Create a script to automate the repetitive parts:

#!/bin/bash
# auto-tighten-widget.sh
# Automatically applies sizing pattern to widget

WIDGET_NAME=$1

echo "๐Ÿ”ง Tightening $WIDGET_NAME..."
# Remove width/height from containerStyles
# Add customStyles template
# Update property groups
echo "โœ… $WIDGET_NAME tightened!"

When: After Wave 2 (once patterns are 100% clear)


๐Ÿ“š Documentation to Reference

As you work through each wave, reference these docs:

  1. WIDGET_SIZING_FIX.md - Sizing pattern
  2. FONT_PROPERTIES_FIX.md - Property reading pattern
  3. INTELLIGENT_PROPERTY_ORGANIZATION.md - Property groups
  4. button-widget.component.ts - Reference implementation

โœ… Final Checklist: Widget Perfection

Once all waves complete, verify:


Status: ๐Ÿ“‹ Plan Ready
Next: Execute Wave 1
Goal: Widget Perfection

LET'S TIGHTEN IT UP! ๐Ÿ”งโœจ