1. 基本元件實作 (Button 元件)

請使用 純 JavaScript (ES6 Class) 建立一個 MyButton 元件,這個元件應該具備以下功能:

class MyBtn {
  constructor(label, color) {
    this.label = label;
    this.color = color;

    this.button = document.createElement("button");
    this.button.textContent = this.label;
    this.button.style.backgroundColor = this.color;
    this.button.style.color = "white";
    this.button.style.border = "none";
    this.button.style.padding = "10px 20px";
    this.button.style.cursor = "pointer";

    this.button.addEventListener("click", () => console.log("click my btn"));
  }

  render(parent) {
    parent.appendChild(this.button);
  }
}

const btn = new MyBtn("Click My Btn", "#F69542");
btn.render(document.body);

2. 可折疊面板 (Accordion 元件)

請用 純 JavaScript (ES6 Class) 實作一個 MyAccordion 元件:

class MyAccordion {
  constructor(title, content) {
    this.title = title;
    this.content = content;

    this.container = document.createElement("div");
    this.header = document.createElement("div");
    this.body = document.createElement("div");

    this.header.textContent = this.title;
    this.body.textContent = this.content;

    this.container.appendChild(this.header);
    this.container.appendChild(this.body);

    this.header.style.backgroundColor = "#f96543";
    this.header.style.color = "white";
    this.body.style.display = "none";
    this.body.style.border = "1px solid #ddd";

    this.header.addEventListener(
      "click",
      () =>
        (this.body.style.display =
          this.body.style.display === "none" ? "block" : "none")
    );
  }

  render(parent) {
    parent.appendChild(this.container);
  }
}

const acc = new MyAccordion("Click Me To Open", "Something Here");
acc.render(document.body);

3. 可輸入的標籤系統 (TagInput)

請實作 TagInput 元件,滿足以下需求:

class TagInput {
  constructor() {
    this.tags = [];

    this.container = document.createElement("div");
    this.input = document.createElement("input");
    this.tagList = document.createElement("div");

    this.container.appendChild(this.tagList);
    this.container.appendChild(this.input);

    this.input.addEventListener("keydown", (e) => {
      if (e.key === "Enter" && this.input.value.trim()) {
        this.addTag(this.input.value.trim());
        this.input.value = "";
      }
    });
  }

  addTag(tag) {
    this.tags.push(tag);
    console.log(this.tags);
    this.renderTag();
  }

  removeTag(index) {
    this.tags.splice(index, 1);
    this.renderTag();
  }

  renderTag() {
    this.tagList.innerHTML = "";
    this.tags.forEach((tag, index) => {
      const tagElement = document.createElement("span");
      tagElement.textContent = tag; //重要
      tagElement.style.backgroundColor = "#f69543";
      tagElement.style.color = "white";
      tagElement.style.margin = "2px";
      tagElement.style.padding = "2px";
      this.tagList.appendChild(tagElement);

      const removeBtn = document.createElement("span");
      removeBtn.textContent = " x"; //重要
      removeBtn.style.cursor = "pointer";
      removeBtn.addEventListener("click", () => this.removeTag(index));
      tagElement.appendChild(removeBtn);
    });
  }

  render(parent) {
    parent.appendChild(this.container);
  }
}

const tagInput = new TagInput();
tagInput.render(document.body);