Development
007-properties-panel-web-components - Claude MCP Skill
<objective>
SEO Guide: Enhance your AI agent with the 007-properties-panel-web-components tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to <objective>... Download and configure this skill to unlock new capabilities for your AI workflow.
π1 stars β’ 0 forks
π₯0 downloads
Documentation
SKILL.md<objective>
Build the interactive Properties Panel UI using Web Components with 2-way data binding between the schema-driven form and Monaco editor.
This phase creates the client-side interactivity layer: custom elements (<prop-editor>, <prop-field>) that handle form state, real-time Monaco synchronization, and dirty state trackingβall without requiring a JavaScript framework.
This enables users to edit Block properties via both the visual form and raw JSON, with changes instantly reflected in both views.
</objective>
<context>
**Previous Phase Deliverables:**
- Schema-driven form renderer exists (schema_form.rs)
- Forms are server-rendered with data-path attributes on each field
- Test route at /admin/schema-test/header displays HeaderProps form
**Current State:**
- Monaco editor exists and is integrated (from git history: admin-index.css, monaco.js)
- Forms are static HTML (no interactivity yet)
- No connection between form fields and Monaco JSON
**End Goal (This Phase):**
Web Components that provide:
- Form field state management
- 2-way binding: Form changes β Monaco JSON, Monaco changes β Form fields
- Dirty state tracking (unsaved changes indicator)
- Foundation for Phase 3's publish workflow
**Why This Matters:**
This creates a professional editor experience where users can work in their preferred mode (visual form or code) while maintaining a single source of truth. Changes propagate instantly without page reloads.
</context>
<requirements>
**Agent Invocation:**
Use @agent-graydon-rust-engineer with ALL available skills:
- web-components-architecture (Custom Elements v1, Declarative Shadow DOM, handleEvent)
- javascript-pragmatic-rules (async operations, V8 optimization, memory management)
- maud-components-patterns (server-side rendering with Web Components)
- rust-core-patterns (type-safe component architecture)
**CRITICAL:** Use Web Components architecture skill for ALL JavaScript. Follow these patterns:
- Custom Elements v1 API with Declarative Shadow DOM
- Attribute-driven state (no props drilling)
- handleEvent pattern for event handling
- Zero DOM selection (NO querySelector, NO innerHTML)
- Pure web platform APIs only (NO external libraries)
**Technical Requirements:**
1. **Web Component: `<prop-editor>`**
- Container component that manages the entire properties panel
- Attributes:
- `schema` - JSON Schema (from schemars)
- `initial-value` - Current Block props as JSON string
- State:
- Current form values (object matching schema structure)
- Dirty flag (has unsaved changes)
- Responsibilities:
- Initialize Monaco editor in JSON mode
- Sync form β Monaco on field changes
- Sync Monaco β form on editor changes
- Emit custom events: `prop-change`, `prop-dirty`, `prop-clean`
- Methods:
- `getValue()` - Return current props as JSON
- `setValue(json)` - Update both form and Monaco
- `reset()` - Revert to initial value
2. **Web Component: `<prop-field>`**
- Individual form field wrapper
- Attributes:
- `path` - Property path (e.g., "button.text")
- `type` - Schema type ("string", "boolean", "number")
- `value` - Current value
- Responsibilities:
- Wrap existing input/checkbox components
- Listen for user input events
- Dispatch change event to parent <prop-editor>
- Update own value when parent calls setValue()
- Use handleEvent pattern for all event listeners
3. **2-Way Binding Architecture**
```
User types in form input
β
<prop-field> dispatches 'field-change' event
β
<prop-editor> updates internal state
β
<prop-editor> updates Monaco JSON
β
Monaco editor displays updated JSON
User edits Monaco JSON
β
Monaco onChange event
β
<prop-editor> parses JSON
β
<prop-editor> updates form fields via setValue()
β
<prop-field> elements reflect new values
```
4. **Dirty State Tracking**
- Compare current value with initial-value attribute
- Add visual indicator (e.g., orange border, "Unsaved changes" text)
- Emit `prop-dirty` event when changes detected
- Emit `prop-clean` event when reverted to initial
5. **Server Integration**
- Update schema_form.rs to wrap rendered form in <prop-editor>
- Inject schema and initial-value attributes server-side
- Render <prop-field> wrappers around input/checkbox components
- Include Web Component JavaScript in page <head>
6. **Monaco Integration**
- Reuse existing Monaco editor setup
- Configure for JSON editing mode
- Add schema validation (use the generated JSON Schema)
- Pretty-print JSON formatting
- Syntax highlighting for properties
</requirements>
<implementation>
**Design Principles:**
1. **Web Components Best Practices:**
- Extend HTMLElement, NOT framework components
- Use attributeChangedCallback for reactive updates
- Implement connectedCallback/disconnectedCallback for lifecycle
- Use handleEvent pattern for memory-efficient event handling
- Declarative Shadow DOM for encapsulation (if needed)
2. **State Management Pattern:**
```javascript
class PropEditor extends HTMLElement {
#state = { values: {}, dirty: false };
handleEvent(event) {
switch(event.type) {
case 'field-change': this.#handleFieldChange(event);
case 'monaco-change': this.#handleMonacoChange(event);
}
}
#syncFormToMonaco() { /* update Monaco JSON */ }
#syncMonacoToForm() { /* update form fields */ }
}
```
3. **Data Flow:**
- Single source of truth: <prop-editor>'s internal state
- Form fields are "controlled components" (React pattern in vanilla JS)
- Monaco editor is also controlled by <prop-editor>
- Deep equality check prevents infinite update loops
4. **Why This Approach:**
- Web Components: Native, no build step, framework-agnostic
- handleEvent: Memory-efficient, better performance than arrow functions
- Attribute-driven: Server can hydrate initial state easily
- Custom events: Loose coupling, easy to extend
**What to Avoid:**
- β NO React/Vue/Angular (Web Components only)
- β NO npm/webpack (vanilla ES modules)
- β NO querySelector inside components (pass refs via attributes if needed)
- β NO innerHTML (security risk, breaks existing components)
- β NO global state (encapsulate in <prop-editor>)
</implementation>
<output>
Create/modify these files:
1. `./website/assets/components/prop-editor.js` - Main editor component
2. `./website/assets/components/prop-field.js` - Field wrapper component
3. `./website/assets/components/index.js` - Register all components
4. `./website/src/core/schema_form.rs` - Update to wrap form in Web Components
5. `./website/src/pages/admin/schema_test.rs` - Include component scripts
6. `./website/assets/components/prop-editor.css` - Styling for dirty states, layout
All JavaScript must follow the web-components-architecture skill patterns.
All files should follow existing project conventions from @CLAUDE.md
</output>
<verification>
Before declaring complete, verify:
1. **Component Registration:**
- Custom elements are registered: `customElements.define('prop-editor', PropEditor)`
- No console errors on page load
- Components appear in browser DevTools as custom elements
2. **Form β Monaco Sync:**
- Type in a form input field
- Monaco editor JSON updates in real-time
- JSON structure matches schema (nested objects preserved)
- No lag or debouncing issues
3. **Monaco β Form Sync:**
- Edit JSON directly in Monaco (e.g., change "headline": "New Text")
- Form field updates to show "New Text"
- Works for nested properties (button.text)
- Invalid JSON shows validation error (doesn't crash)
4. **Dirty State:**
- Initially shows "No unsaved changes"
- After editing, shows "Unsaved changes" indicator
- Visual feedback (e.g., orange border on form)
- Reverts to clean when reset() is called
5. **Browser Compatibility:**
- Test in Chrome/Safari (Web Components support)
- No framework dependencies in network tab
- JavaScript follows javascript-pragmatic-rules (no memory leaks)
6. **Integration with Existing UI:**
- Existing input/checkbox components still render correctly
- Styles don't conflict
- Server-rendered HTML hydrates properly
</verification>
<success_criteria>
- β
Web Components defined using Custom Elements v1 API
- β
2-way binding works: Form β Monaco JSON sync in real-time
- β
Dirty state tracking with visual indicator
- β
Zero framework dependencies (vanilla JS only)
- β
Follows web-components-architecture patterns (handleEvent, no querySelector)
- β
Test route demonstrates full interactivity with HeaderProps
- β
Code follows javascript-pragmatic-rules (memory-safe, performant)
</success_criteria>Signals
Avg ratingβ 0.0
Reviews0
Favorites0
Information
- Repository
- matthewharwood/engmanager.xyz
- Author
- matthewharwood
- Last Sync
- 9/4/2026
- Repo Updated
- 6/28/2026
- Created
- 1/17/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.
Mastering the Oracle CLI: A Complete Guide to the Claude Skill for Database Professionals
Learn how to use the oracle Claude skill. Complete guide with installation instructions and examples.