diff --git a/example07/index.html b/example07/index.html
new file mode 100644
index 0000000..a9ed056
--- /dev/null
+++ b/example07/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Simple Component 7
+
+
+Example #7
+
+
+
+
\ No newline at end of file
diff --git a/example07/src/app.js b/example07/src/app.js
new file mode 100644
index 0000000..3aa76ed
--- /dev/null
+++ b/example07/src/app.js
@@ -0,0 +1,10 @@
+import Items from "./components/Items.js";
+
+class App {
+ constructor() {
+ const $app = document.querySelector('#app');
+ new Items($app);
+ }
+}
+
+new App();
diff --git a/example07/src/components/Items.js b/example07/src/components/Items.js
new file mode 100644
index 0000000..65f65d9
--- /dev/null
+++ b/example07/src/components/Items.js
@@ -0,0 +1,69 @@
+import Component from "../core/Component.js";
+
+export default class Items extends Component {
+ setup() {
+ this.$state = {
+ items: [
+ {
+ seq: 1,
+ contents: 'item1',
+ active: false,
+ },
+ {
+ seq: 2,
+ contents: 'item2',
+ active: true,
+ }
+ ]
+ };
+ }
+
+ template() {
+ const {items} = this.$state;
+ return `
+
+ ${items.map(({contents, active, seq}) => `
+ -
+ ${contents}
+
+
+
+ `).join('')}
+
+
+ `
+ }
+
+ setEvent() {
+ this.addEvent('click', '.addBtn', ({target}) => {
+ const {items} = this.$state;
+ const seq = Math.max(0, ...items.map(v => v.seq)) + 1;
+ const contents = `item${seq}`;
+ const active = false;
+ this.setState({
+ items: [
+ ...items,
+ {seq, contents, active}
+ ]
+ });
+ });
+
+ this.addEvent('click', '.deleteBtn', ({target}) => {
+ const items = [ ...this.$state.items ];;
+ const seq = Number(target.closest('[data-seq]').dataset.seq);
+ items.splice(items.findIndex(v => v.seq === seq), 1);
+ this.setState({items});
+ });
+
+ this.addEvent('click', '.toggleBtn', ({target}) => {
+ const items = [ ...this.$state.items ];
+ const seq = Number(target.closest('[data-seq]').dataset.seq);
+ const index = items.findIndex(v => v.seq === seq);
+ items[index].active = !items[index].active;
+ this.setState({items});
+ });
+ }
+}
+
diff --git a/example07/src/core/Component.js b/example07/src/core/Component.js
new file mode 100644
index 0000000..c218bde
--- /dev/null
+++ b/example07/src/core/Component.js
@@ -0,0 +1,28 @@
+export default class Component {
+ $target;
+ $state;
+ constructor ($target) {
+ this.$target = $target;
+ this.setup();
+ this.setEvent();
+ this.render();
+ }
+ setup () {};
+ template () { return ''; }
+ render () {
+ this.$target.innerHTML = this.template();
+ }
+ setEvent () {}
+ setState (newState) {
+ this.$state = { ...this.$state, ...newState };
+ this.render();
+ }
+ addEvent (eventType, selector, callback) {
+ const children = [ ...this.$target.querySelectorAll(selector) ];
+ const isTarget = (target) => children.includes(target) || target.closest(selector);
+ this.$target.addEventListener(eventType, event => {
+ if (!isTarget(event.target)) return false;
+ callback(event);
+ })
+ }
+}