Widget Taxonomy Design

Complete specification of the basic/composite widget taxonomy system

Widget Taxonomy Design Specification

🎯 Overview

This document defines the complete widget taxonomy for GoGrab Space's widget-builder system.

📊 Widget Hierarchy

┌─────────────────────────────────────────────────────────────┐
│                     WIDGET ECOSYSTEM                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────────────┐         ┌──────────────────────┐ │
│  │   BASIC WIDGETS      │         │  COMPOSITE WIDGETS   │ │
│  │  (GoGrab-managed)    │    →    │  (User-created)      │ │
│  └──────────────────────┘         └──────────────────────┘ │
│           │                                  │              │
│           │                                  │              │
│           ▼                                  ▼              │
│  ┌──────────────────────┐         ┌──────────────────────┐ │
│  │     VARIANTS         │         │   INSTANCES          │ │
│  │  (User-created)      │         │  (In Pages)          │ │
│  └──────────────────────┘         └──────────────────────┘ │
│                                                             │
└─────────────────────────────────────────────────────────────┘

🧱 Basic Widgets

Definition

Basic widgets are the fundamental building blocks of the platform. They:

Categories

1. Input & Forms

const BASIC_FORM_WIDGETS = [
  {
    type: 'input',
    name: 'Input Field',
    icon: 'fas fa-keyboard',
    variants: ['text', 'email', 'password', 'number', 'tel', 'url'],
    properties: ['label', 'placeholder', 'required', 'disabled', 'validation']
  },
  {
    type: 'select',
    name: 'Select Dropdown',
    icon: 'fas fa-list',
    properties: ['options', 'multiple', 'searchable', 'placeholder']
  },
  {
    type: 'checkbox',
    name: 'Checkbox',
    icon: 'fas fa-check-square',
    properties: ['label', 'checked', 'disabled']
  },
  {
    type: 'radio',
    name: 'Radio Button',
    icon: 'fas fa-dot-circle',
    properties: ['label', 'value', 'name', 'checked']
  },
  {
    type: 'button',
    name: 'Button',
    icon: 'fas fa-hand-pointer',
    variants: ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'link'],
    properties: ['text', 'type', 'disabled', 'loading', 'icon']
  }
] as const;

2. Content & Typography

const BASIC_CONTENT_WIDGETS = [
  {
    type: 'text',
    name: 'Text',
    icon: 'fas fa-font',
    variants: ['heading', 'paragraph', 'label', 'caption'],
    properties: ['content', 'fontSize', 'fontWeight', 'color', 'align']
  },
  {
    type: 'image',
    name: 'Image',
    icon: 'fas fa-image',
    properties: ['src', 'alt', 'width', 'height', 'fit', 'lazy']
  },
  {
    type: 'icon',
    name: 'Icon',
    icon: 'fas fa-star',
    properties: ['name', 'size', 'color', 'rotate']
  }
] as const;

3. Layout & Structure

const BASIC_LAYOUT_WIDGETS = [
  {
    type: 'container',
    name: 'Container',
    icon: 'fas fa-box',
    properties: ['direction', 'gap', 'padding', 'align', 'justify']
  },
  {
    type: 'card',
    name: 'Card',
    icon: 'fas fa-id-card',
    properties: ['padding', 'shadow', 'border', 'rounded']
  },
  {
    type: 'divider',
    name: 'Divider',
    icon: 'fas fa-grip-lines',
    properties: ['orientation', 'thickness', 'color']
  },
  {
    type: 'spacer',
    name: 'Spacer',
    icon: 'fas fa-arrows-alt-v',
    properties: ['size']
  }
] as const;

Basic Widget Properties

interface BasicWidget {
  // Identity
  type: string;              // e.g., 'button', 'input'
  name: string;              // Display name
  description: string;       // What it does
  icon: string;              // FontAwesome icon
  category: 'form' | 'content' | 'layout';
  
  // Configuration
  defaultConfig: Record<string, any>;  // Default properties
  availableVariants: WidgetVariant[];  // GoGrab-provided variants
  
  // Metadata
  version: string;
  author: 'gograb-team';
  isBasic: true;
  isEditable: false;         // Users cannot edit definition
  canCreateVariants: true;   // Users can create variants
  
  // Technical
  componentPath: string;     // Path to Angular component
  flutterComponent: string;  // Path to Flutter widget
}

🎨 Variants

Definition

Variants are pre-configured versions of basic widgets. They:

Examples

// GoGrab-provided variant
const PRIMARY_BUTTON_VARIANT: WidgetVariant = {
  id: 'button-primary',
  baseWidget: 'button',
  name: 'Primary Button',
  description: 'Primary action button with brand colors',
  author: 'gograb-team',
  isPublic: true,
  config: {
    backgroundColor: 'var(--color-primary)',
    color: 'white',
    padding: '12px 24px',
    borderRadius: '8px',
    fontWeight: 600,
    hoverEffect: 'scale'
  }
};

// User-created variant
const CUSTOM_BUTTON_VARIANT: WidgetVariant = {
  id: 'button-my-brand',
  baseWidget: 'button',
  name: 'My Brand Button',
  description: 'Custom button matching my brand',
  author: 'user-123',
  universeId: 'universe-abc',
  spaceId: 'space-xyz',
  isPublic: false,
  config: {
    backgroundColor: '#FF6B6B',
    color: '#FFFFFF',
    padding: '16px 32px',
    borderRadius: '24px',
    boxShadow: '0 4px 12px rgba(255, 107, 107, 0.3)'
  }
};

🏗️ Composite Widgets

Definition

Composite widgets are user-created combinations of basic widgets. They:

Examples

// Login Form Composite Widget
const LOGIN_FORM_COMPOSITE: CompositeWidget = {
  id: 'composite-login-form',
  name: 'Login Form',
  description: 'Complete login form with email and password',
  category: 'form',
  icon: 'fas fa-sign-in-alt',
  author: 'user-123',
  universeId: 'universe-abc',
  
  // Structure (basic widgets used)
  structure: {
    children: [
      {
        type: 'text',
        variant: 'heading',
        properties: { content: 'Login', fontSize: 24 }
      },
      {
        type: 'input',
        variant: 'email',
        properties: { label: 'Email', placeholder: 'Enter your email', required: true }
      },
      {
        type: 'input',
        variant: 'password',
        properties: { label: 'Password', placeholder: 'Enter password', required: true }
      },
      {
        type: 'button',
        variant: 'primary',
        properties: { text: 'Login', type: 'submit' }
      }
    ],
    layout: 'vertical',
    gap: 16
  },
  
  // Inputs (can be configured when used)
  inputs: [
    { name: 'title', type: 'string', default: 'Login' },
    { name: 'submitButtonText', type: 'string', default: 'Login' }
  ],
  
  // Outputs (events)
  outputs: [
    { name: 'onSubmit', type: 'event', payload: { email: 'string', password: 'string' } }
  ],
  
  // Variants
  variants: [
    {
      id: 'login-form-dark',
      name: 'Dark Mode Login',
      config: { backgroundColor: '#1a1a1a', color: '#ffffff' }
    }
  ]
};

🗄️ Storage Strategy

Storage Keys

// Basic Widgets Registry (Read-only for users)
const BASIC_WIDGETS_KEY = 'platform:widgets:basic';

// User-Created Variants (Universe-scoped)
const VARIANTS_KEY = (universeId: string) => 
  `universe:${universeId}:widgets:variants`;

// Composite Widgets (Universe-scoped)
const COMPOSITE_WIDGETS_KEY = (universeId: string) => 
  `universe:${universeId}:widgets:composite`;

// Widget Instances (Page-specific)
const WIDGET_INSTANCES_KEY = (spaceId: string, pageId: string) => 
  `space:${spaceId}:page:${pageId}:widgets`;

Data Structure

interface WidgetStorageStructure {
  // Platform level (managed by GoGrab)
  'platform:widgets:basic': {
    version: string;
    widgets: BasicWidget[];
    lastUpdated: Date;
  };
  
  // Universe level (user data)
  [`universe:${string}:widgets:variants`]: {
    universeId: string;
    variants: WidgetVariant[];
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };
  
  [`universe:${string}:widgets:composite`]: {
    universeId: string;
    widgets: CompositeWidget[];
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };
  
  // Space level (page instances)
  [`space:${string}:page:${string}:widgets`]: {
    spaceId: string;
    pageId: string;
    instances: WidgetInstance[];
    lastModified: Date;
  };
}

🎯 Widget Builder User Flow

Step 1: Choose Widget Level

┌─────────────────────────────────────────────────────┐
│         What do you want to create?                 │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌──────────────────┐     ┌──────────────────┐    │
│  │  Create Variant  │     │ Create Composite │    │
│  │                  │     │     Widget       │    │
│  │  Based on basic  │     │  Combine basic   │    │
│  │  widget          │     │  widgets         │    │
│  └──────────────────┘     └──────────────────┘    │
│                                                     │
└─────────────────────────────────────────────────────┘

Step 2A: Create Variant

1. Select base widget (button, input, etc.)
2. Configure properties
3. Preview across breakpoints
4. Save variant

Step 2B: Create Composite

1. Open visual designer
2. Drag & drop basic widgets
3. Configure layout
4. Define inputs/outputs
5. Preview
6. Export/Save

✅ Next Steps

  1. Implement basic widget registry service
  2. Create variant builder UI
  3. Create composite widget builder UI
  4. Implement storage integration
  5. Add export functionality
  6. Test with real-world scenarios

Session: 1.2.1
Status: ✅ Design Complete
Next: Implementation (see progress/IMPLEMENTATION_LOG.md)