Component Architecture: sketch-tool-card and Related Components

This document explains the relationship between LitElement subclasses in webui/src/web-components/ and the sketch-tool-card custom element, focusing on their containment relationship and CSS styling effects.

Containment Relationship

The component hierarchy and containment relationship is structured as follows:

  1. sketch-app-shell (the main application container)
    • Contains sketch-timeline (for displaying conversation history)
      • Contains sketch-timeline-message (for individual messages)
        • Contains sketch-tool-calls (collection of tool calls)
          • Contains specific tool card components like:
            • sketch-tool-card-bash
            • sketch-tool-card-think
            • sketch-tool-card-codereview
            • sketch-tool-card-done
            • sketch-tool-card-patch
            • sketch-tool-card-take-screenshot
            • sketch-tool-card-title
            • sketch-tool-card-precommit
            • sketch-tool-card-multiple-choice
            • sketch-tool-card-generic (fallback for unknown tools)
              • All of these specialized components contain or compose with the base sketch-tool-card

The key aspect is that the specialized tool card components do not inherit from SketchToolCard in a class hierarchy sense. Instead, they use composition by embedding a <sketch-tool-card> element within their render method and passing data to it.

For example, from sketch-tool-card-bash.ts:

render() {
  return html` <sketch-tool-card
    .open=${this.open}
    .toolCall=${this.toolCall}
  >
    <span slot="summary" class="summary-text">...</span>
    <div slot="input" class="input">...</div>
    <div slot="result" class="result">...</div>
  </sketch-tool-card>`;
}

CSS Styling and Effects

Regarding how CSS rules defined in sketch-tool-card affect elements that contain it:

  1. Shadow DOM Encapsulation:

    • Each Web Component has its own Shadow DOM, which encapsulates its styles
    • Styles defined in sketch-tool-card apply only within its shadow DOM, not to parent components
  2. Slot Content Styling:

    • The base sketch-tool-card defines three slots: "summary", "input", and "result"
    • Specialized tool cards provide content for these slots
    • The base component can style the slot containers, but cannot directly style the slotted content
  3. Style Inheritance and Sharing:

    • The code uses a commonStyles constant that is shared across some components
    • These common styles ensure consistent styling for elements like pre, code blocks
    • Each specialized component adds its own unique styles as needed
  4. Parent CSS Targeting:

    • In sketch-timeline-message.ts, there are styles that target the tool components using the ::slotted() pseudo-element:
    ::slotted(sketch-tool-calls) {
      max-width: 100%;
      width: 100%;
      overflow-wrap: break-word;
      word-break: break-word;
    }
    
    • This allows parent components to influence the layout of slotted components while preserving Shadow DOM encapsulation
  5. Host Element Styling:

    • The :host selector is used in sketch-tool-card for styling the component itself:
    :host {
      display: block;
      max-width: 100%;
      width: 100%;
      box-sizing: border-box;
      overflow: hidden;
    }
    
    • This affects how the component is displayed in its parent context

In summary, the architecture uses composition rather than inheritance, with specialized tool cards wrapping the base sketch-tool-card component and filling its slots with custom content. The CSS styling is carefully managed through Shadow DOM, with some targeted styling using ::slotted selectors to ensure proper layout and appearance throughout the component hierarchy.