ninegrid2 6.1344.0 → 6.1345.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28533,6 +28533,12 @@ class nxDiv extends HTMLElement {
28533
28533
  if (bChanged) this.#changed(bChanged);
28534
28534
  };
28535
28535
 
28536
+ clearData = (bChanged) => {
28537
+
28538
+
28539
+ this.#changed(false);
28540
+ };
28541
+
28536
28542
  initData = (jsonData) => {
28537
28543
  this.setData(jsonData);
28538
28544
  this.#changed(false);
@@ -28872,7 +28878,7 @@ class nxPanel extends nxDiv {
28872
28878
 
28873
28879
  customElements.define("nx-panel", nxPanel);
28874
28880
 
28875
- class nxButtons extends nxDiv {
28881
+ class nxButtons extends nxDiv2 {
28876
28882
 
28877
28883
  constructor() {
28878
28884
  super();
@@ -28892,36 +28898,10 @@ class nxButtons extends nxDiv {
28892
28898
  @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
28893
28899
  ${ninegrid.getCustomPath(this,"nxButtons.css")}
28894
28900
  </style>
28895
-
28896
- ${this.originContents}
28901
+ <slot></slot>
28897
28902
  `;
28898
28903
 
28899
- //console.log(htmlTmpl);
28900
-
28901
28904
  target.appendChild(htmlTmpl.content.cloneNode(true));
28902
- /**
28903
- target.addEventListener('click', (e) => {
28904
-
28905
- const btn = e.target.closest('button');
28906
- if (!btn) return;
28907
-
28908
- //const actionName = btn.getAttribute('on-click') || btn.getAttribute('onClick') || btn.getAttribute('onclick');
28909
-
28910
- const actionName = btn.getAttribute('on-click');
28911
-
28912
- console.log(btn, actionName, this[actionName])
28913
- console.log(typeof this[actionName])
28914
- if (actionName) {
28915
- // 1. 먼저 엘리먼트 자체(this)에 해당 이름의 함수가 있는지 확인
28916
- if (typeof this[actionName] === 'function') {
28917
- this[actionName](e);
28918
- }
28919
- // 2. 없으면 전역 window에서 확인
28920
- else if (typeof window[actionName] === 'function') {
28921
- window[actionName](e);
28922
- }
28923
- }
28924
- }); */
28925
28905
  }
28926
28906
  }
28927
28907
 
@@ -28529,6 +28529,12 @@ class nxDiv extends HTMLElement {
28529
28529
  if (bChanged) this.#changed(bChanged);
28530
28530
  };
28531
28531
 
28532
+ clearData = (bChanged) => {
28533
+
28534
+
28535
+ this.#changed(false);
28536
+ };
28537
+
28532
28538
  initData = (jsonData) => {
28533
28539
  this.setData(jsonData);
28534
28540
  this.#changed(false);
@@ -28868,7 +28874,7 @@ class nxPanel extends nxDiv {
28868
28874
 
28869
28875
  customElements.define("nx-panel", nxPanel);
28870
28876
 
28871
- class nxButtons extends nxDiv {
28877
+ class nxButtons extends nxDiv2 {
28872
28878
 
28873
28879
  constructor() {
28874
28880
  super();
@@ -28888,36 +28894,10 @@ class nxButtons extends nxDiv {
28888
28894
  @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
28889
28895
  ${ninegrid.getCustomPath(this,"nxButtons.css")}
28890
28896
  </style>
28891
-
28892
- ${this.originContents}
28897
+ <slot></slot>
28893
28898
  `;
28894
28899
 
28895
- //console.log(htmlTmpl);
28896
-
28897
28900
  target.appendChild(htmlTmpl.content.cloneNode(true));
28898
- /**
28899
- target.addEventListener('click', (e) => {
28900
-
28901
- const btn = e.target.closest('button');
28902
- if (!btn) return;
28903
-
28904
- //const actionName = btn.getAttribute('on-click') || btn.getAttribute('onClick') || btn.getAttribute('onclick');
28905
-
28906
- const actionName = btn.getAttribute('on-click');
28907
-
28908
- console.log(btn, actionName, this[actionName])
28909
- console.log(typeof this[actionName])
28910
- if (actionName) {
28911
- // 1. 먼저 엘리먼트 자체(this)에 해당 이름의 함수가 있는지 확인
28912
- if (typeof this[actionName] === 'function') {
28913
- this[actionName](e);
28914
- }
28915
- // 2. 없으면 전역 window에서 확인
28916
- else if (typeof window[actionName] === 'function') {
28917
- window[actionName](e);
28918
- }
28919
- }
28920
- }); */
28921
28901
  }
28922
28902
  }
28923
28903
 
package/dist/nx/_nxDiv.js CHANGED
@@ -100,6 +100,12 @@ export class nxDiv extends HTMLElement {
100
100
  if (bChanged) this.#changed(bChanged);
101
101
  };
102
102
 
103
+ clearData = (bChanged) => {
104
+
105
+
106
+ this.#changed(false);
107
+ };
108
+
103
109
  initData = (jsonData) => {
104
110
  this.setData(jsonData);
105
111
  this.#changed(false);
@@ -1,32 +1,51 @@
1
1
  import ninegrid from "../index.js";
2
2
 
3
- export class nxDiv2 extends HTMLElement
4
- {
3
+ export class nxDiv2 extends HTMLElement {
5
4
  originContents;
6
5
  #isInitialized = false;
6
+ #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
7
7
 
8
- constructor () {
8
+ constructor() {
9
9
  super();
10
- this.attachShadow({ mode: 'open' });
10
+ // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
11
11
  }
12
12
 
13
13
  connectedCallback() {
14
14
  if (!this.#isInitialized) {
15
+ // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
16
+ // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
17
+ const useShadow = this.getAttribute("use-shadow") !== "false";
18
+
19
+ if (useShadow && !this.shadowRoot) {
20
+ this.attachShadow({ mode: 'open' });
21
+ this.#root = this.shadowRoot;
22
+ } else {
23
+ this.#root = this;
24
+ }
25
+
15
26
  this.#init();
16
- this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
27
+ this.#isInitialized = true;
17
28
  return true;
18
29
  }
19
-
20
30
  return false;
21
31
  }
22
32
 
33
+ // 자식 클래스에서 접근 가능하도록 getter 제공
34
+ get root() {
35
+ return this.#root || this;
36
+ }
37
+
38
+ // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
39
+ #getElements() {
40
+ // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
41
+ return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
42
+ }
43
+
23
44
  getData = () => {
24
45
  const jsonData = {};
25
-
26
- // Shadow DOM 내의 폼 요소만 선택
27
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
46
+ this.#getElements().forEach(el => {
28
47
  const key = el.name;
29
- if (!key) return; // name이 없는 요소는 건너뜁니다.
48
+ if (!key) return;
30
49
 
31
50
  let value;
32
51
  if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
@@ -35,57 +54,58 @@ export class nxDiv2 extends HTMLElement
35
54
  value = el.value;
36
55
  }
37
56
 
38
- // 중복 name을 대비한 배열 처리
39
57
  if (jsonData[key]) {
40
- if (!Array.isArray(jsonData[key])) {
41
- jsonData[key] = [jsonData[key]];
42
- }
58
+ if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
43
59
  jsonData[key].push(value);
44
60
  } else {
45
61
  jsonData[key] = value;
46
62
  }
47
63
  });
48
-
49
64
  return jsonData;
50
65
  };
51
66
 
52
67
  setData = (jsonData) => {
53
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
68
+ this.#getElements().forEach(el => {
54
69
  el.removeEventListener("input", this.#changeHandler);
55
70
  el.addEventListener("input", this.#changeHandler);
56
71
  });
57
72
 
58
- if (!jsonData || typeof jsonData !== 'object') {
59
- console.error("setData: Invalid data provided. Expected an object.");
60
- return;
61
- }
73
+ if (!jsonData || typeof jsonData !== 'object') return;
62
74
 
63
75
  let bChanged = false;
64
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
76
+ this.#getElements().forEach(el => {
65
77
  const key = el.name;
78
+ //console.log(el.tagName, key, el.name);
79
+
66
80
  if (!key || !jsonData.hasOwnProperty(key)) return;
67
81
 
68
82
  const value = jsonData[key];
69
83
 
70
- // 요소에만 데이터를 설정합니다.
71
- if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
84
+ const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
85
+
86
+ if (inputTags.includes(el.tagName)) {
72
87
  if (el.type === "checkbox" || el.type === "radio") {
73
- if (el.checked !== (el.value === String(value))) bChanged = true;
74
- el.checked = (el.value === String(value));
88
+ const isChecked = (String(el.value) === String(value));
89
+ if (el.checked !== isChecked) bChanged = true;
90
+ el.checked = isChecked;
75
91
  } else {
76
92
  if (el.value !== value) bChanged = true;
77
93
  el.value = value;
78
94
  }
79
95
  } else {
80
- // 폼 요소가 아닌 경우, textContent를 사용합니다.
81
96
  if (el.textContent !== value) bChanged = true;
82
97
  el.textContent = value;
83
98
  }
84
99
  });
85
-
86
100
  if (bChanged) this.#changed(bChanged);
87
101
  };
88
102
 
103
+ clearData = (bChanged) => {
104
+
105
+
106
+ this.#changed(false);
107
+ };
108
+
89
109
  initData = (jsonData) => {
90
110
  this.setData(jsonData);
91
111
  this.#changed(false);
@@ -104,21 +124,22 @@ export class nxDiv2 extends HTMLElement
104
124
  }
105
125
 
106
126
  #init = () => {
107
-
108
- //console.log(this);
109
- //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
110
-
111
- /**
112
- * css style 적용
113
- */
127
+ /** CSS style 적용 */
114
128
  for (const attr of this.attributes) {
115
129
  if (attr.name.startsWith("css-")) {
116
- // "css-" 접두사를 제거하고 CSS 속성명으로 변환
117
130
  this.style.setProperty(attr.name.substring(4), attr.value);
118
131
  }
119
132
  }
120
133
 
134
+ //console.log("=========");
135
+ //console.log(this.innerHTML.trim());
136
+
121
137
  this.originContents = this.innerHTML.trim();
122
- this.innerHTML = ""; // 기존 내부 HTML 제거
138
+ //this.innerHTML = ""; // 기존 내부 HTML 제거
139
+
140
+ // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
141
+ if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
142
+ this.shadowRoot.innerHTML = this.originContents;
143
+ }
123
144
  };
124
145
  }
@@ -1,7 +1,7 @@
1
1
  import ninegrid from "../index.js";
2
- import {nxDiv} from "./_nxDiv.js";
2
+ import {nxDiv} from "./_nxDiv2.js";
3
3
 
4
- class nxButtons extends nxDiv {
4
+ class nxButtons extends nxDiv2 {
5
5
 
6
6
  constructor() {
7
7
  super();
@@ -21,36 +21,10 @@ class nxButtons extends nxDiv {
21
21
  @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
22
22
  ${ninegrid.getCustomPath(this,"nxButtons.css")}
23
23
  </style>
24
-
25
- ${this.originContents}
24
+ <slot></slot>
26
25
  `;
27
26
 
28
- //console.log(htmlTmpl);
29
-
30
27
  target.appendChild(htmlTmpl.content.cloneNode(true));
31
- /**
32
- target.addEventListener('click', (e) => {
33
-
34
- const btn = e.target.closest('button');
35
- if (!btn) return;
36
-
37
- //const actionName = btn.getAttribute('on-click') || btn.getAttribute('onClick') || btn.getAttribute('onclick');
38
-
39
- const actionName = btn.getAttribute('on-click');
40
-
41
- console.log(btn, actionName, this[actionName])
42
- console.log(typeof this[actionName])
43
- if (actionName) {
44
- // 1. 먼저 엘리먼트 자체(this)에 해당 이름의 함수가 있는지 확인
45
- if (typeof this[actionName] === 'function') {
46
- this[actionName](e);
47
- }
48
- // 2. 없으면 전역 window에서 확인
49
- else if (typeof window[actionName] === 'function') {
50
- window[actionName](e);
51
- }
52
- }
53
- }); */
54
28
  }
55
29
  }
56
30
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ninegrid2",
3
3
  "type": "module",
4
- "version": "6.1344.0",
4
+ "version": "6.1345.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
package/src/nx/_nxDiv.js CHANGED
@@ -100,6 +100,12 @@ export class nxDiv extends HTMLElement {
100
100
  if (bChanged) this.#changed(bChanged);
101
101
  };
102
102
 
103
+ clearData = (bChanged) => {
104
+
105
+
106
+ this.#changed(false);
107
+ };
108
+
103
109
  initData = (jsonData) => {
104
110
  this.setData(jsonData);
105
111
  this.#changed(false);
@@ -0,0 +1,145 @@
1
+ import ninegrid from "../index.js";
2
+
3
+ export class nxDiv2 extends HTMLElement {
4
+ originContents;
5
+ #isInitialized = false;
6
+ #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
7
+
8
+ constructor() {
9
+ super();
10
+ // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
11
+ }
12
+
13
+ connectedCallback() {
14
+ if (!this.#isInitialized) {
15
+ // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
16
+ // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
17
+ const useShadow = this.getAttribute("use-shadow") !== "false";
18
+
19
+ if (useShadow && !this.shadowRoot) {
20
+ this.attachShadow({ mode: 'open' });
21
+ this.#root = this.shadowRoot;
22
+ } else {
23
+ this.#root = this;
24
+ }
25
+
26
+ this.#init();
27
+ this.#isInitialized = true;
28
+ return true;
29
+ }
30
+ return false;
31
+ }
32
+
33
+ // 자식 클래스에서 접근 가능하도록 getter 제공
34
+ get root() {
35
+ return this.#root || this;
36
+ }
37
+
38
+ // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
39
+ #getElements() {
40
+ // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
41
+ return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
42
+ }
43
+
44
+ getData = () => {
45
+ const jsonData = {};
46
+ this.#getElements().forEach(el => {
47
+ const key = el.name;
48
+ if (!key) return;
49
+
50
+ let value;
51
+ if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
52
+ value = el.checked;
53
+ } else {
54
+ value = el.value;
55
+ }
56
+
57
+ if (jsonData[key]) {
58
+ if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
59
+ jsonData[key].push(value);
60
+ } else {
61
+ jsonData[key] = value;
62
+ }
63
+ });
64
+ return jsonData;
65
+ };
66
+
67
+ setData = (jsonData) => {
68
+ this.#getElements().forEach(el => {
69
+ el.removeEventListener("input", this.#changeHandler);
70
+ el.addEventListener("input", this.#changeHandler);
71
+ });
72
+
73
+ if (!jsonData || typeof jsonData !== 'object') return;
74
+
75
+ let bChanged = false;
76
+ this.#getElements().forEach(el => {
77
+ const key = el.name;
78
+ //console.log(el.tagName, key, el.name);
79
+
80
+ if (!key || !jsonData.hasOwnProperty(key)) return;
81
+
82
+ const value = jsonData[key];
83
+
84
+ const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
85
+
86
+ if (inputTags.includes(el.tagName)) {
87
+ if (el.type === "checkbox" || el.type === "radio") {
88
+ const isChecked = (String(el.value) === String(value));
89
+ if (el.checked !== isChecked) bChanged = true;
90
+ el.checked = isChecked;
91
+ } else {
92
+ if (el.value !== value) bChanged = true;
93
+ el.value = value;
94
+ }
95
+ } else {
96
+ if (el.textContent !== value) bChanged = true;
97
+ el.textContent = value;
98
+ }
99
+ });
100
+ if (bChanged) this.#changed(bChanged);
101
+ };
102
+
103
+ clearData = (bChanged) => {
104
+
105
+
106
+ this.#changed(false);
107
+ };
108
+
109
+ initData = (jsonData) => {
110
+ this.setData(jsonData);
111
+ this.#changed(false);
112
+ };
113
+
114
+ #changed = (v) => {
115
+ const parent = this.closest(".detail-wrapper");
116
+ if (parent) {
117
+ const el = parent.querySelector("nx-title2");
118
+ if (el) el.changed = v;
119
+ }
120
+ }
121
+
122
+ #changeHandler = (e) => {
123
+ this.#changed(true);
124
+ }
125
+
126
+ #init = () => {
127
+ /** CSS style 적용 */
128
+ for (const attr of this.attributes) {
129
+ if (attr.name.startsWith("css-")) {
130
+ this.style.setProperty(attr.name.substring(4), attr.value);
131
+ }
132
+ }
133
+
134
+ //console.log("=========");
135
+ //console.log(this.innerHTML.trim());
136
+
137
+ this.originContents = this.innerHTML.trim();
138
+ //this.innerHTML = ""; // 기존 내부 HTML 제거
139
+
140
+ // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
141
+ if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
142
+ this.shadowRoot.innerHTML = this.originContents;
143
+ }
144
+ };
145
+ }
@@ -1,7 +1,7 @@
1
1
  import ninegrid from "../index.js";
2
- import {nxDiv} from "./_nxDiv.js";
2
+ import {nxDiv} from "./_nxDiv2.js";
3
3
 
4
- class nxButtons extends nxDiv {
4
+ class nxButtons extends nxDiv2 {
5
5
 
6
6
  constructor() {
7
7
  super();
@@ -21,36 +21,10 @@ class nxButtons extends nxDiv {
21
21
  @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
22
22
  ${ninegrid.getCustomPath(this,"nxButtons.css")}
23
23
  </style>
24
-
25
- ${this.originContents}
24
+ <slot></slot>
26
25
  `;
27
26
 
28
- //console.log(htmlTmpl);
29
-
30
27
  target.appendChild(htmlTmpl.content.cloneNode(true));
31
- /**
32
- target.addEventListener('click', (e) => {
33
-
34
- const btn = e.target.closest('button');
35
- if (!btn) return;
36
-
37
- //const actionName = btn.getAttribute('on-click') || btn.getAttribute('onClick') || btn.getAttribute('onclick');
38
-
39
- const actionName = btn.getAttribute('on-click');
40
-
41
- console.log(btn, actionName, this[actionName])
42
- console.log(typeof this[actionName])
43
- if (actionName) {
44
- // 1. 먼저 엘리먼트 자체(this)에 해당 이름의 함수가 있는지 확인
45
- if (typeof this[actionName] === 'function') {
46
- this[actionName](e);
47
- }
48
- // 2. 없으면 전역 window에서 확인
49
- else if (typeof window[actionName] === 'function') {
50
- window[actionName](e);
51
- }
52
- }
53
- }); */
54
28
  }
55
29
  }
56
30