Legacy Polymer 1.x/2.x compatibility APIs for existing applications that need to migrate gradually to Polymer 3.x.
The Polymer() function for creating elements using the 1.x/2.x API pattern.
/**
* Legacy element factory and registration helper for defining Polymer elements
* @param info - Element configuration object or constructor function
* @returns Generated element constructor
*/
function Polymer(info: PolymerInit | Function): PolymerElementConstructor;
/**
* Legacy element configuration object
*/
interface PolymerInit {
/** Element tag name for registration */
is: string;
/** Template for the element (HTML string or template element) */
template?: HTMLTemplateElement | string;
/** Property configuration object */
properties?: PropertyDeclarations;
/** Array of observer method names and their dependencies */
observers?: string[];
/** Array of behavior objects to mix into element */
behaviors?: Behavior[];
/** Host attributes to set on element instances */
hostAttributes?: {[attribute: string]: string | number | boolean};
/** Event listeners to attach */
listeners?: {[event: string]: string};
// Lifecycle methods
/** Called when element prototype is created (once per element type) */
created?(): void;
/** Called when element is ready (after properties initialized) */
ready?(): void;
/** Called when element is attached to document */
attached?(): void;
/** Called when element is detached from document */
detached?(): void;
/** Called when attribute changes */
attributeChanged?(name: string, oldValue: string, newValue: string): void;
}Usage Examples:
import { Polymer } from '@polymer/polymer/polymer-legacy.js';
// Basic legacy element
Polymer({
is: 'my-legacy-element',
properties: {
name: String,
count: {
type: Number,
value: 0,
observer: 'countChanged'
}
},
ready() {
console.log('Element ready');
},
attached() {
console.log('Element attached');
},
countChanged(newValue, oldValue) {
console.log(`Count: ${oldValue} → ${newValue}`);
}
});
// Legacy element with behaviors
Polymer({
is: 'behavior-element',
behaviors: [
// Custom behaviors would be imported and referenced here
],
properties: {
active: Boolean
}
});Base prototype object for extending legacy elements.
/**
* Legacy element base prototype with all Polymer 1.x/2.x methods
*/
const Base: PolymerLegacyElementBase;
interface PolymerLegacyElementBase {
/** Element tag name */
is: string;
/** Whether element is currently attached to document */
isAttached: boolean;
/** Root node (shadowRoot or element itself) */
root: ShadowRoot | HTMLElement;
/** Map of id->element for template elements with id attributes */
$: {[id: string]: Element};
// Lifecycle callbacks
created(): void;
ready(): void;
attached(): void;
detached(): void;
attributeChanged(name: string, oldValue: string, newValue: string): void;
// Data binding and properties
get(path: string): any;
set(path: string, value: any): void;
notifyPath(path: string, value?: any): void;
// DOM utilities
$$(selector: string): Element;
fire(type: string, detail?: any, options?: EventOptions): Event;
listen(node: EventTarget, eventName: string, methodName: string): void;
unlisten(node: EventTarget, eventName: string, methodName: string): void;
// Array mutation
push(path: string, ...items: any[]): number;
pop(path: string): any;
splice(path: string, start: number, deleteCount?: number, ...items: any[]): any[];
shift(path: string): any;
unshift(path: string, ...items: any[]): number;
// Async operations
async(callback: Function, waitTime?: number): number;
cancelAsync(handle: number): void;
debounce(jobName: string, callback: Function, wait?: number): object;
flushDebouncer(jobName: string): void;
cancelDebouncer(jobName: string): void;
isDebouncerActive(jobName: string): boolean;
// Element utilities
create(tag: string, props?: object): Element;
elementMatches(selector: string, node?: Element): boolean;
toggleAttribute(name: string, bool?: boolean): boolean;
toggleClass(name: string, bool?: boolean, node?: Element): void;
transform(transformText: string, node?: Element): void;
translate3d(x: string|number, y: string|number, z: string|number, node?: Element): void;
// Content distribution (Polymer 1.x/2.x)
getContentChildren(selector?: string): HTMLElement[];
getContentChildNodes(selector?: string): Node[];
getEffectiveChildren(): Node[];
getEffectiveChildNodes(): Node[];
getEffectiveTextContent(): string;
queryDistributedElements(selector: string): Node[];
queryEffectiveChildren(selector: string): Node;
queryAllEffectiveChildren(selector: string): Node[];
// Styling
updateStyles(properties?: {[property: string]: string}): void;
getComputedStyleValue(property: string): string;
scopeSubtree(container: Element, shouldObserve?: boolean): MutationObserver;
// Legacy DOM API
domHost: Node;
distributeContent(): void;
isLightDescendant(node: Node): boolean;
isLocalDescendant(node: Element): boolean;
}Usage Examples:
import { Polymer, Base } from '@polymer/polymer/polymer-legacy.js';
// Extending Base prototype
const MyMixin = {
customMethod() {
console.log('Custom method called');
}
};
// Create element by extending Base
Polymer({
is: 'extended-base-element',
// Base methods are automatically available
ready() {
this.customMethod(); // From mixin
this.async(() => {
console.log('Async operation');
}, 100);
},
handleClick() {
this.fire('custom-event', { data: 'example' });
}
});Legacy-compatible mixins that provide Polymer 1.x/2.x behavior.
/**
* Legacy element mixin that provides backward-compatible API
*/
function LegacyElementMixin<T extends Constructor<HTMLElement>>(base: T): T & LegacyElementMixinConstructor;
interface LegacyElementMixinConstructor {
new(): LegacyElementMixin;
importMeta: object;
}
interface LegacyElementMixin {
isAttached: boolean;
created(): void;
attached(): void;
detached(): void;
attributeChanged(name: string, oldValue: string, newValue: string): void;
// All methods from PolymerLegacyElementBase
}Event firing options for legacy compatibility.
interface EventOptions {
/** Whether event bubbles (default: true) */
bubbles?: boolean;
/** Whether event is cancelable (default: false) */
cancelable?: boolean;
/** Whether event is composed (default: true) */
composed?: boolean;
/** Node to fire event on (default: this) */
node?: HTMLElement;
}Legacy behavior system for code reuse (replaced by mixins in 3.x).
/**
* Legacy behavior interface (for reference only - use mixins in new code)
*/
interface Behavior {
/** Properties to add to element */
properties?: PropertyDeclarations;
/** Observers to add to element */
observers?: string[];
/** Listeners to add to element */
listeners?: {[event: string]: string};
/** Lifecycle methods */
created?(): void;
ready?(): void;
attached?(): void;
detached?(): void;
/** Custom methods and properties */
[key: string]: any;
}Migration Example:
// Legacy 1.x/2.x code
import { Polymer } from '@polymer/polymer/polymer-legacy.js';
Polymer({
is: 'legacy-element',
properties: {
name: String,
items: {
type: Array,
value: () => []
}
},
observers: [
'itemsChanged(items.splices)'
],
ready() {
console.log('Legacy element ready');
},
addItem(item) {
this.push('items', item);
},
itemsChanged(changeRecord) {
if (changeRecord) {
console.log('Items changed');
}
}
});
// Modern 3.x equivalent
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
class ModernElement extends PolymerElement {
static get is() { return 'modern-element'; }
static get properties() {
return {
name: String,
items: {
type: Array,
value: () => []
}
};
}
static get observers() {
return ['itemsChanged(items.splices)'];
}
ready() {
super.ready();
console.log('Modern element ready');
}
addItem(item) {
this.push('items', item);
}
itemsChanged(changeRecord) {
if (changeRecord) {
console.log('Items changed');
}
}
}
customElements.define(ModernElement.is, ModernElement);type Constructor<T = {}> = new (...args: any[]) => T;
interface PolymerElementConstructor {
new(): PolymerLegacyElementBase;
is: string;
}
interface PropertyDeclarations {
[property: string]: PropertyType | PropertyDeclaration;
}
interface PropertyDeclaration {
type?: PropertyType;
value?: any | (() => any);
reflectToAttribute?: boolean;
readOnly?: boolean;
notify?: boolean;
computed?: string;
observer?: string;
}
type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;