or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-engine.mdcomponents.mdcontrollers.mddata-structures.mddebugging-development.mddestroyables-cleanup.mdindex.mdmodifiers.mdobject-model.mdreactivity-tracking.mdrouting.mdservices.mdtemplates-rendering.mdtesting.mdutilities.md
tile.json

components.mddocs/

Components

Component system supporting both modern Glimmer components and classic Ember components with lifecycle management and template integration.

Capabilities

Modern Glimmer Components

Modern component base class with simplified lifecycle and args-based API.

/**
 * Modern component base class with simplified lifecycle and args-based API
 */
class Component {
  /**
   * Component constructor
   * @param owner - DI container owner
   * @param args - Component arguments passed from template
   */
  constructor(owner: Owner, args: ComponentArgs);
  
  /**
   * Called when component is being destroyed for cleanup
   */
  willDestroy(): void;
  
  /** Component arguments passed from template - readonly */
  readonly args: ComponentArgs;
  
  /** Whether component is currently being destroyed */
  readonly isDestroying: boolean;
  
  /** Whether component has been destroyed */
  readonly isDestroyed: boolean;
}

Usage Examples:

import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";

export default class UserCard extends Component {
  @tracked isExpanded = false;
  
  @action
  toggleExpanded() {
    this.isExpanded = !this.isExpanded;
  }
  
  get displayName() {
    return this.args.user?.name || 'Unknown User';
  }
  
  willDestroy() {
    super.willDestroy();
    // Cleanup any resources
    this.cleanup?.();
  }
}

Template-Only Components

Template-only components have no backing class and are optimized for performance.

import templateOnly from "@ember/component/template-only";
/**
 * Creates a template-only component with no backing class
 * @param moduleName - Optional module name for debugging
 * @returns Template-only component instance
 */
function templateOnly<S = unknown>(moduleName?: string): TemplateOnlyComponent<S>;

interface TemplateOnlyComponent<S = unknown> {
  // Template-only component with no instance properties
  // Only template arguments ({{@arg}}) are accessible
}

Usage Examples:

import templateOnly from "@ember/component/template-only";

// Simple template-only component
export default templateOnly();

// With module name for debugging
export default templateOnly('my-app/components/user-avatar');

// Template would access only arguments:
// {{@user.name}} - ✓ Valid
// {{this.someProperty}} - ✗ Invalid (no backing class)

Classic Ember Components

Classic component class with full lifecycle hooks and two-way binding support.

/**
 * Classic component class with full lifecycle hooks and two-way binding support
 */
class EmberComponent {
  /**
   * Create a new component class
   * @param properties - Component properties and methods
   * @returns New component class
   */
  static extend(properties?: object): typeof EmberComponent;
  
  /**
   * Create component instance
   * @param properties - Initial properties
   * @returns Component instance
   */
  static create(properties?: object): EmberComponent;
  
  /**
   * Called when component DOM element is inserted
   */
  didInsertElement(): void;
  
  /**
   * Called when component DOM element is updated
   */
  didUpdateAttrs(): void;
  
  /**
   * Called when component is about to be destroyed
   */
  willDestroyElement(): void;
  
  /**
   * Called when component DOM element is destroyed
   */
  didDestroyElement(): void;
  
  /** Component's DOM element */
  readonly element: Element;
  
  /** Component element tag name */
  tagName: string;
  
  /** CSS classes for component element */
  classNames: string[];
  
  /** Dynamic CSS classes based on properties */
  classNameBindings: string[];
  
  /** HTML attributes for component element */
  attributeBindings: string[];
}

Built-in Components

Pre-built input components for common form elements.

/**
 * Built-in input component for form inputs
 */
class Input extends EmberComponent {
  /** Input type (text, email, password, etc.) */
  type: string;
  
  /** Input value */
  value: any;
  
  /** Placeholder text */
  placeholder: string;
  
  /** Whether input is disabled */
  disabled: boolean;
  
  /** Action to call when input changes */
  input: Function;
  
  /** Action to call when input receives focus */
  focusIn: Function;
  
  /** Action to call when input loses focus */
  focusOut: Function;
}

/**
 * Built-in textarea component for multi-line text input
 */
class Textarea extends EmberComponent {
  /** Textarea value */
  value: string;
  
  /** Placeholder text */
  placeholder: string;
  
  /** Number of rows */
  rows: number;
  
  /** Number of columns */
  cols: number;
  
  /** Whether textarea is disabled */
  disabled: boolean;
}

Component Template Management

Functions for associating templates with component classes.

/**
 * Associate a template with a component class
 * @param template - Compiled template function
 * @param component - Component class to associate template with
 */
function setComponentTemplate(template: Template, component: ComponentClass): void;

/**
 * Get the template associated with a component class
 * @param component - Component class to get template for
 * @returns Associated template or undefined
 */
function getComponentTemplate(component: ComponentClass): Template | undefined;

Component Manager System

Custom component manager API for advanced component behavior.

/**
 * Set a custom component manager for a component definition
 * @param manager - Component manager factory function
 * @param component - Component class or definition
 * @returns Component class with manager
 */
function setComponentManager(
  manager: (owner: Owner) => ComponentManager, 
  component: ComponentClass
): ComponentClass;

/**
 * Define capabilities for a component manager
 * @param version - Manager API version
 * @param options - Capability options
 * @returns Capabilities object
 */
function capabilities(version: string, options?: CapabilityOptions): Capabilities;

Component Lookup

Service for dynamically looking up component classes.

/**
 * Component lookup service for dynamic component resolution
 */
class ComponentLookup extends Service {
  /**
   * Look up a component class by name
   * @param name - Component name to look up
   * @param owner - DI container owner
   * @returns Component class or undefined
   */
  lookupFactory(name: string, owner: Owner): ComponentClass | undefined;
}

Usage Examples:

import { setComponentTemplate, setComponentManager } from "@ember/component";
import { precompileTemplate } from "@ember/template-compilation";

// Associate template with component
const template = precompileTemplate(`
  <div class="user-card {{if @isHighlighted "highlighted"}}">
    <h3>{{@user.name}}</h3>
    <button {{on "click" this.toggleDetails}}>
      {{if this.showDetails "Hide" "Show"}} Details
    </button>
    {{#if this.showDetails}}
      <p>{{@user.email}}</p>
    {{/if}}
  </div>
`);

setComponentTemplate(template, UserCardComponent);

// Custom component manager
class CustomManager {
  createComponent(factory, args) {
    return factory.create({ args });
  }
  
  updateComponent(instance, args) {
    instance.args = args;
  }
  
  destroyComponent(instance) {
    instance.destroy();
  }
}

setComponentManager(() => new CustomManager(), MyCustomComponent);

Types

interface ComponentArgs {
  /** Dynamic component arguments */
  [key: string]: any;
}

interface ComponentClass {
  /** Component constructor */
  new (owner: Owner, args: ComponentArgs): Component;
}

interface Template {
  /** Template rendering function */
  (context: object): string;
}

interface ComponentManager {
  /** Create component instance */
  createComponent(factory: Factory, args: ComponentArgs): any;
  
  /** Update component with new args */
  updateComponent(instance: any, args: ComponentArgs): void;
  
  /** Destroy component instance */
  destroyComponent(instance: any): void;
  
  /** Get component context for template */
  getContext(instance: any): object;
}

interface CapabilityOptions {
  /** Whether component creates DOM elements */
  createInstance?: boolean;
  
  /** Whether component uses args */
  useArgs?: boolean;
  
  /** Whether component has lifecycle hooks */
  hasLifecycle?: boolean;
  
  /** Whether component is async */
  asyncLifecycleCallbacks?: boolean;
  
  /** Whether component can be destroyed */
  destructor?: boolean;
}

interface Capabilities {
  /** Component manager capabilities */
  [key: string]: boolean;
}