Lifecycle Hooks for Angular Elements in Non-Angular Projects

Illustrate how to utilize Angular lifecycle hooks within custom Angular Elements to manage resources when they are attached or detached from the DOM in a non-Angular application.
class MyCustomElement extends HTMLElement {
  // Called when the element is inserted into the DOM
  connectedCallback() {
    this.innerHTML = '<p>I am a custom element!</p>';
    console.log('Custom element added to page.');
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `<style>p { color: blue; }</style><p>Styled with Shadow DOM</p>`;

  // Called when the element is removed from the DOM
  disconnectedCallback() {
    console.log('Custom element removed from page.');

  // Called when an attribute is changed, appended, removed, or replaced on the element.
  attributeChangedCallback(name, oldValue, newValue) {
    console.log(`Attribute: ${name} changed from ${oldValue} to ${newValue}`);

  // List of attributes to monitor
  static get observedAttributes() { return ['my-attribute']; }

// Define the new element
window.customElements.define('my-custom-element', MyCustomElement);
This JavaScript code defines a new custom element 'my-custom-element', using the class 'MyCustomElement' that extends the 'HTMLElement' class. It includes lifecycle hooks such as connectedCallback for when the element is attached to the DOM, disconnectedCallback for when the element is detached from the DOM, attributeChangedCallback for when an attribute changes, and a list of observed attributes. The shadow DOM is also used to encapsulate styles.