ninegrid2 6.1256.0 → 6.1257.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.
@@ -121838,49 +121838,33 @@ class nxTitle extends HTMLElement {
121838
121838
 
121839
121839
  customElements.define("nx-title", nxTitle);
121840
121840
 
121841
- class nxDiv extends HTMLElement {
121841
+ class nxDiv extends HTMLElement
121842
+ {
121842
121843
  originContents;
121843
121844
  #isInitialized = false;
121844
- #root; // 탐색 및 렌더링 대상 (shadowRoot 또는 this)
121845
121845
 
121846
- constructor() {
121846
+ constructor () {
121847
121847
  super();
121848
- // 1. 옵션 확인 (기본값은 shadow 사용하지 않는 기존 방식처럼 동작 가능하게 설정)
121849
- // 만약 기존 소스 그대로 shadow를 쓰고 싶다면 true로, 아니면 속성 체크
121850
- const useShadow = this.getAttribute("use-shadow") === "true";
121851
-
121852
- if (useShadow) {
121853
- this.attachShadow({ mode: 'open' });
121854
- this.#root = this.shadowRoot;
121855
- } else {
121856
- this.#root = this;
121857
- }
121848
+ this.attachShadow({ mode: 'open' });
121858
121849
  }
121859
121850
 
121860
121851
  connectedCallback() {
121861
121852
  if (!this.#isInitialized) {
121862
121853
  this.#init();
121863
- this.#isInitialized = true;
121854
+ this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
121864
121855
  return true;
121865
121856
  }
121866
- return false;
121867
- }
121868
121857
 
121869
- // 자식에서 접근 가능한 root getter
121870
- get root() {
121871
- return this.#root;
121872
- }
121873
-
121874
- // root에 따라 엘리먼트 탐색
121875
- #getElements() {
121876
- return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
121858
+ return false;
121877
121859
  }
121878
121860
 
121879
121861
  getData = () => {
121880
121862
  const jsonData = {};
121881
- this.#getElements().forEach(el => {
121863
+
121864
+ // Shadow DOM 내의 폼 요소만 선택
121865
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121882
121866
  const key = el.name;
121883
- if (!key) return;
121867
+ if (!key) return; // name이 없는 요소는 건너뜁니다.
121884
121868
 
121885
121869
  let value;
121886
121870
  if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
@@ -121889,30 +121873,39 @@ class nxDiv extends HTMLElement {
121889
121873
  value = el.value;
121890
121874
  }
121891
121875
 
121876
+ // 중복 name을 대비한 배열 처리
121892
121877
  if (jsonData[key]) {
121893
- if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
121878
+ if (!Array.isArray(jsonData[key])) {
121879
+ jsonData[key] = [jsonData[key]];
121880
+ }
121894
121881
  jsonData[key].push(value);
121895
121882
  } else {
121896
121883
  jsonData[key] = value;
121897
121884
  }
121898
121885
  });
121886
+
121899
121887
  return jsonData;
121900
121888
  };
121901
121889
 
121902
121890
  setData = (jsonData) => {
121903
- this.#getElements().forEach(el => {
121891
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121904
121892
  el.removeEventListener("input", this.#changeHandler);
121905
121893
  el.addEventListener("input", this.#changeHandler);
121906
121894
  });
121907
121895
 
121908
- if (!jsonData || typeof jsonData !== 'object') return;
121896
+ if (!jsonData || typeof jsonData !== 'object') {
121897
+ console.error("setData: Invalid data provided. Expected an object.");
121898
+ return;
121899
+ }
121909
121900
 
121910
121901
  let bChanged = false;
121911
- this.#getElements().forEach(el => {
121902
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121912
121903
  const key = el.name;
121913
121904
  if (!key || !jsonData.hasOwnProperty(key)) return;
121914
121905
 
121915
121906
  const value = jsonData[key];
121907
+
121908
+ // 폼 요소에만 데이터를 설정합니다.
121916
121909
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
121917
121910
  if (el.type === "checkbox" || el.type === "radio") {
121918
121911
  if (el.checked !== (el.value === String(value))) bChanged = true;
@@ -121922,10 +121915,12 @@ class nxDiv extends HTMLElement {
121922
121915
  el.value = value;
121923
121916
  }
121924
121917
  } else {
121918
+ // 폼 요소가 아닌 경우, textContent를 사용합니다.
121925
121919
  if (el.textContent !== value) bChanged = true;
121926
121920
  el.textContent = value;
121927
121921
  }
121928
121922
  });
121923
+
121929
121924
  if (bChanged) this.#changed(bChanged);
121930
121925
  };
121931
121926
 
@@ -121947,28 +121942,22 @@ class nxDiv extends HTMLElement {
121947
121942
  }
121948
121943
 
121949
121944
  #init = () => {
121950
- // 1. CSS Style 적용
121945
+
121946
+ //console.log(this);
121947
+ //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
121948
+
121949
+ /**
121950
+ * css style 적용
121951
+ */
121951
121952
  for (const attr of this.attributes) {
121952
121953
  if (attr.name.startsWith("css-")) {
121954
+ // "css-" 접두사를 제거하고 CSS 속성명으로 변환
121953
121955
  this.style.setProperty(attr.name.substring(4), attr.value);
121954
121956
  }
121955
121957
  }
121956
121958
 
121957
- // 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
121958
- if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
121959
-
121960
- // 3. 내부 HTML 보관
121961
121959
  this.originContents = this.innerHTML.trim();
121962
-
121963
- // 4. Shadow DOM 사용 시에만 비우고 옮기기
121964
- if (this.shadowRoot) {
121965
- // 자식 클래스(nxButtons 등)에서 내용을 직접 구성할 수 있도록
121966
- // 태그 종류에 따라 선별적으로 내용을 넣어줌
121967
- if (this.tagName.toLowerCase() === 'nx-div') {
121968
- this.shadowRoot.innerHTML = this.originContents;
121969
- }
121970
- this.innerHTML = ""; // Light DOM 비움
121971
- }
121960
+ this.innerHTML = ""; // 기존 내부 HTML 제거
121972
121961
  };
121973
121962
  }
121974
121963
 
@@ -122255,36 +122244,27 @@ class nxPanel extends nxDiv {
122255
122244
  customElements.define("nx-panel", nxPanel);
122256
122245
 
122257
122246
  class nxButtons extends nxDiv {
122247
+
122258
122248
  constructor() {
122259
122249
  super();
122260
122250
  }
122261
122251
 
122262
122252
  connectedCallback() {
122263
122253
  if (super.connectedCallback()) this.#init();
122264
- }
122254
+ };
122265
122255
 
122266
122256
  #init = () => {
122267
- // 1. 스타일과 내용을 합친 템플릿 생성
122268
- const styleContent = `
122269
- <style>
122270
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
122271
- ${ninegrid.getCustomPath(this, "nxButtons.css")}
122272
- </style>
122273
- `;
122274
-
122275
122257
  const htmlTmpl = document.createElement("template");
122258
+ htmlTmpl.innerHTML = `
122259
+ <style>
122260
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
122261
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
122262
+ </style>
122263
+
122264
+ ${this.originContents}
122265
+ `;
122276
122266
 
122277
- // Shadow DOM일 때는 originContents를 옮겨야 하고,
122278
- // Light DOM일 때는 이미 본문에 있으므로 스타일만 추가하면 됨
122279
- if (this.shadowRoot) {
122280
- htmlTmpl.innerHTML = `${styleContent}${this.originContents}`;
122281
- this.root.appendChild(htmlTmpl.content.cloneNode(true));
122282
- } else {
122283
- // Light DOM 모드일 때: 스타일만 상단에 추가
122284
- const styleDiv = document.createElement("div");
122285
- styleDiv.innerHTML = styleContent;
122286
- this.root.prepend(styleDiv);
122287
- }
122267
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
122288
122268
  }
122289
122269
  }
122290
122270
 
@@ -121834,49 +121834,33 @@ class nxTitle extends HTMLElement {
121834
121834
 
121835
121835
  customElements.define("nx-title", nxTitle);
121836
121836
 
121837
- class nxDiv extends HTMLElement {
121837
+ class nxDiv extends HTMLElement
121838
+ {
121838
121839
  originContents;
121839
121840
  #isInitialized = false;
121840
- #root; // 탐색 및 렌더링 대상 (shadowRoot 또는 this)
121841
121841
 
121842
- constructor() {
121842
+ constructor () {
121843
121843
  super();
121844
- // 1. 옵션 확인 (기본값은 shadow 사용하지 않는 기존 방식처럼 동작 가능하게 설정)
121845
- // 만약 기존 소스 그대로 shadow를 쓰고 싶다면 true로, 아니면 속성 체크
121846
- const useShadow = this.getAttribute("use-shadow") === "true";
121847
-
121848
- if (useShadow) {
121849
- this.attachShadow({ mode: 'open' });
121850
- this.#root = this.shadowRoot;
121851
- } else {
121852
- this.#root = this;
121853
- }
121844
+ this.attachShadow({ mode: 'open' });
121854
121845
  }
121855
121846
 
121856
121847
  connectedCallback() {
121857
121848
  if (!this.#isInitialized) {
121858
121849
  this.#init();
121859
- this.#isInitialized = true;
121850
+ this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
121860
121851
  return true;
121861
121852
  }
121862
- return false;
121863
- }
121864
121853
 
121865
- // 자식에서 접근 가능한 root getter
121866
- get root() {
121867
- return this.#root;
121868
- }
121869
-
121870
- // root에 따라 엘리먼트 탐색
121871
- #getElements() {
121872
- return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
121854
+ return false;
121873
121855
  }
121874
121856
 
121875
121857
  getData = () => {
121876
121858
  const jsonData = {};
121877
- this.#getElements().forEach(el => {
121859
+
121860
+ // Shadow DOM 내의 폼 요소만 선택
121861
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121878
121862
  const key = el.name;
121879
- if (!key) return;
121863
+ if (!key) return; // name이 없는 요소는 건너뜁니다.
121880
121864
 
121881
121865
  let value;
121882
121866
  if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
@@ -121885,30 +121869,39 @@ class nxDiv extends HTMLElement {
121885
121869
  value = el.value;
121886
121870
  }
121887
121871
 
121872
+ // 중복 name을 대비한 배열 처리
121888
121873
  if (jsonData[key]) {
121889
- if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
121874
+ if (!Array.isArray(jsonData[key])) {
121875
+ jsonData[key] = [jsonData[key]];
121876
+ }
121890
121877
  jsonData[key].push(value);
121891
121878
  } else {
121892
121879
  jsonData[key] = value;
121893
121880
  }
121894
121881
  });
121882
+
121895
121883
  return jsonData;
121896
121884
  };
121897
121885
 
121898
121886
  setData = (jsonData) => {
121899
- this.#getElements().forEach(el => {
121887
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121900
121888
  el.removeEventListener("input", this.#changeHandler);
121901
121889
  el.addEventListener("input", this.#changeHandler);
121902
121890
  });
121903
121891
 
121904
- if (!jsonData || typeof jsonData !== 'object') return;
121892
+ if (!jsonData || typeof jsonData !== 'object') {
121893
+ console.error("setData: Invalid data provided. Expected an object.");
121894
+ return;
121895
+ }
121905
121896
 
121906
121897
  let bChanged = false;
121907
- this.#getElements().forEach(el => {
121898
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
121908
121899
  const key = el.name;
121909
121900
  if (!key || !jsonData.hasOwnProperty(key)) return;
121910
121901
 
121911
121902
  const value = jsonData[key];
121903
+
121904
+ // 폼 요소에만 데이터를 설정합니다.
121912
121905
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
121913
121906
  if (el.type === "checkbox" || el.type === "radio") {
121914
121907
  if (el.checked !== (el.value === String(value))) bChanged = true;
@@ -121918,10 +121911,12 @@ class nxDiv extends HTMLElement {
121918
121911
  el.value = value;
121919
121912
  }
121920
121913
  } else {
121914
+ // 폼 요소가 아닌 경우, textContent를 사용합니다.
121921
121915
  if (el.textContent !== value) bChanged = true;
121922
121916
  el.textContent = value;
121923
121917
  }
121924
121918
  });
121919
+
121925
121920
  if (bChanged) this.#changed(bChanged);
121926
121921
  };
121927
121922
 
@@ -121943,28 +121938,22 @@ class nxDiv extends HTMLElement {
121943
121938
  }
121944
121939
 
121945
121940
  #init = () => {
121946
- // 1. CSS Style 적용
121941
+
121942
+ //console.log(this);
121943
+ //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
121944
+
121945
+ /**
121946
+ * css style 적용
121947
+ */
121947
121948
  for (const attr of this.attributes) {
121948
121949
  if (attr.name.startsWith("css-")) {
121950
+ // "css-" 접두사를 제거하고 CSS 속성명으로 변환
121949
121951
  this.style.setProperty(attr.name.substring(4), attr.value);
121950
121952
  }
121951
121953
  }
121952
121954
 
121953
- // 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
121954
- if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
121955
-
121956
- // 3. 내부 HTML 보관
121957
121955
  this.originContents = this.innerHTML.trim();
121958
-
121959
- // 4. Shadow DOM 사용 시에만 비우고 옮기기
121960
- if (this.shadowRoot) {
121961
- // 자식 클래스(nxButtons 등)에서 내용을 직접 구성할 수 있도록
121962
- // 태그 종류에 따라 선별적으로 내용을 넣어줌
121963
- if (this.tagName.toLowerCase() === 'nx-div') {
121964
- this.shadowRoot.innerHTML = this.originContents;
121965
- }
121966
- this.innerHTML = ""; // Light DOM 비움
121967
- }
121956
+ this.innerHTML = ""; // 기존 내부 HTML 제거
121968
121957
  };
121969
121958
  }
121970
121959
 
@@ -122251,36 +122240,27 @@ class nxPanel extends nxDiv {
122251
122240
  customElements.define("nx-panel", nxPanel);
122252
122241
 
122253
122242
  class nxButtons extends nxDiv {
122243
+
122254
122244
  constructor() {
122255
122245
  super();
122256
122246
  }
122257
122247
 
122258
122248
  connectedCallback() {
122259
122249
  if (super.connectedCallback()) this.#init();
122260
- }
122250
+ };
122261
122251
 
122262
122252
  #init = () => {
122263
- // 1. 스타일과 내용을 합친 템플릿 생성
122264
- const styleContent = `
122265
- <style>
122266
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
122267
- ${ninegrid.getCustomPath(this, "nxButtons.css")}
122268
- </style>
122269
- `;
122270
-
122271
122253
  const htmlTmpl = document.createElement("template");
122254
+ htmlTmpl.innerHTML = `
122255
+ <style>
122256
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
122257
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
122258
+ </style>
122259
+
122260
+ ${this.originContents}
122261
+ `;
122272
122262
 
122273
- // Shadow DOM일 때는 originContents를 옮겨야 하고,
122274
- // Light DOM일 때는 이미 본문에 있으므로 스타일만 추가하면 됨
122275
- if (this.shadowRoot) {
122276
- htmlTmpl.innerHTML = `${styleContent}${this.originContents}`;
122277
- this.root.appendChild(htmlTmpl.content.cloneNode(true));
122278
- } else {
122279
- // Light DOM 모드일 때: 스타일만 상단에 추가
122280
- const styleDiv = document.createElement("div");
122281
- styleDiv.innerHTML = styleContent;
122282
- this.root.prepend(styleDiv);
122283
- }
122263
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
122284
122264
  }
122285
122265
  }
122286
122266
 
package/dist/nx/_nxDiv.js CHANGED
@@ -1,48 +1,32 @@
1
1
  import ninegrid from "../index.js";
2
2
 
3
- export class nxDiv extends HTMLElement {
3
+ export class nxDiv extends HTMLElement
4
+ {
4
5
  originContents;
5
6
  #isInitialized = false;
6
- #root; // 탐색 및 렌더링 대상 (shadowRoot 또는 this)
7
7
 
8
- constructor() {
8
+ constructor () {
9
9
  super();
10
- // 1. 옵션 확인 (기본값은 shadow 사용하지 않는 기존 방식처럼 동작 가능하게 설정)
11
- // 만약 기존 소스 그대로 shadow를 쓰고 싶다면 true로, 아니면 속성 체크
12
- const useShadow = this.getAttribute("use-shadow") === "true";
13
-
14
- if (useShadow) {
15
- this.attachShadow({ mode: 'open' });
16
- this.#root = this.shadowRoot;
17
- } else {
18
- this.#root = this;
19
- }
10
+ this.attachShadow({ mode: 'open' });
20
11
  }
21
12
 
22
13
  connectedCallback() {
23
14
  if (!this.#isInitialized) {
24
15
  this.#init();
25
- this.#isInitialized = true;
16
+ this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
26
17
  return true;
27
18
  }
28
- return false;
29
- }
30
-
31
- // 자식에서 접근 가능한 root getter
32
- get root() {
33
- return this.#root;
34
- }
35
19
 
36
- // root에 따라 엘리먼트 탐색
37
- #getElements() {
38
- return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
20
+ return false;
39
21
  }
40
22
 
41
23
  getData = () => {
42
24
  const jsonData = {};
43
- this.#getElements().forEach(el => {
25
+
26
+ // Shadow DOM 내의 폼 요소만 선택
27
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
44
28
  const key = el.name;
45
- if (!key) return;
29
+ if (!key) return; // name이 없는 요소는 건너뜁니다.
46
30
 
47
31
  let value;
48
32
  if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
@@ -51,30 +35,39 @@ export class nxDiv extends HTMLElement {
51
35
  value = el.value;
52
36
  }
53
37
 
38
+ // 중복 name을 대비한 배열 처리
54
39
  if (jsonData[key]) {
55
- if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
40
+ if (!Array.isArray(jsonData[key])) {
41
+ jsonData[key] = [jsonData[key]];
42
+ }
56
43
  jsonData[key].push(value);
57
44
  } else {
58
45
  jsonData[key] = value;
59
46
  }
60
47
  });
48
+
61
49
  return jsonData;
62
50
  };
63
51
 
64
52
  setData = (jsonData) => {
65
- this.#getElements().forEach(el => {
53
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
66
54
  el.removeEventListener("input", this.#changeHandler);
67
55
  el.addEventListener("input", this.#changeHandler);
68
56
  });
69
57
 
70
- if (!jsonData || typeof jsonData !== 'object') return;
58
+ if (!jsonData || typeof jsonData !== 'object') {
59
+ console.error("setData: Invalid data provided. Expected an object.");
60
+ return;
61
+ }
71
62
 
72
63
  let bChanged = false;
73
- this.#getElements().forEach(el => {
64
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
74
65
  const key = el.name;
75
66
  if (!key || !jsonData.hasOwnProperty(key)) return;
76
67
 
77
68
  const value = jsonData[key];
69
+
70
+ // 폼 요소에만 데이터를 설정합니다.
78
71
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
79
72
  if (el.type === "checkbox" || el.type === "radio") {
80
73
  if (el.checked !== (el.value === String(value))) bChanged = true;
@@ -84,10 +77,12 @@ export class nxDiv extends HTMLElement {
84
77
  el.value = value;
85
78
  }
86
79
  } else {
80
+ // 폼 요소가 아닌 경우, textContent를 사용합니다.
87
81
  if (el.textContent !== value) bChanged = true;
88
82
  el.textContent = value;
89
83
  }
90
84
  });
85
+
91
86
  if (bChanged) this.#changed(bChanged);
92
87
  };
93
88
 
@@ -109,27 +104,21 @@ export class nxDiv extends HTMLElement {
109
104
  }
110
105
 
111
106
  #init = () => {
112
- // 1. CSS Style 적용
107
+
108
+ //console.log(this);
109
+ //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
110
+
111
+ /**
112
+ * css style 적용
113
+ */
113
114
  for (const attr of this.attributes) {
114
115
  if (attr.name.startsWith("css-")) {
116
+ // "css-" 접두사를 제거하고 CSS 속성명으로 변환
115
117
  this.style.setProperty(attr.name.substring(4), attr.value);
116
118
  }
117
119
  }
118
120
 
119
- // 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
120
- if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
121
-
122
- // 3. 내부 HTML 보관
123
121
  this.originContents = this.innerHTML.trim();
124
-
125
- // 4. Shadow DOM 사용 시에만 비우고 옮기기
126
- if (this.shadowRoot) {
127
- // 자식 클래스(nxButtons 등)에서 내용을 직접 구성할 수 있도록
128
- // 태그 종류에 따라 선별적으로 내용을 넣어줌
129
- if (this.tagName.toLowerCase() === 'nx-div') {
130
- this.shadowRoot.innerHTML = this.originContents;
131
- }
132
- this.innerHTML = ""; // Light DOM 비움
133
- }
122
+ this.innerHTML = ""; // 기존 내부 HTML 제거
134
123
  };
135
124
  }
@@ -7,9 +7,9 @@ export class nxDiv2 extends HTMLElement
7
7
 
8
8
  constructor () {
9
9
  super();
10
- //this.attachShadow({ mode: 'open' });
10
+ this.attachShadow({ mode: 'open' });
11
11
  }
12
-
12
+
13
13
  connectedCallback() {
14
14
  if (!this.#isInitialized) {
15
15
  this.#init();
@@ -24,7 +24,7 @@ export class nxDiv2 extends HTMLElement
24
24
  const jsonData = {};
25
25
 
26
26
  // Shadow DOM 내의 폼 요소만 선택
27
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this).forEach(el => {
27
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
28
28
  const key = el.name;
29
29
  if (!key) return; // name이 없는 요소는 건너뜁니다.
30
30
 
@@ -50,8 +50,7 @@ export class nxDiv2 extends HTMLElement
50
50
  };
51
51
 
52
52
  setData = (jsonData) => {
53
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this).forEach(el => {
54
- console.log("------", el);
53
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
55
54
  el.removeEventListener("input", this.#changeHandler);
56
55
  el.addEventListener("input", this.#changeHandler);
57
56
  });
@@ -62,7 +61,7 @@ export class nxDiv2 extends HTMLElement
62
61
  }
63
62
 
64
63
  let bChanged = false;
65
- ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this).forEach(el => {
64
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
66
65
  const key = el.name;
67
66
  if (!key || !jsonData.hasOwnProperty(key)) return;
68
67
 
@@ -1,38 +1,29 @@
1
1
  import ninegrid from "../index.js";
2
- import { nxDiv } from "./_nxDiv.js";
2
+ import {nxDiv} from "./_nxDiv.js";
3
3
 
4
4
  class nxButtons extends nxDiv {
5
+
5
6
  constructor() {
6
7
  super();
7
8
  }
8
9
 
9
10
  connectedCallback() {
10
11
  if (super.connectedCallback()) this.#init();
11
- }
12
+ };
12
13
 
13
14
  #init = () => {
14
- // 1. 스타일과 내용을 합친 템플릿 생성
15
- const styleContent = `
16
- <style>
17
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
18
- ${ninegrid.getCustomPath(this, "nxButtons.css")}
19
- </style>
20
- `;
21
-
22
15
  const htmlTmpl = document.createElement("template");
16
+ htmlTmpl.innerHTML = `
17
+ <style>
18
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
19
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
20
+ </style>
21
+
22
+ ${this.originContents}
23
+ `;
23
24
 
24
- // Shadow DOM일 때는 originContents를 옮겨야 하고,
25
- // Light DOM일 때는 이미 본문에 있으므로 스타일만 추가하면 됨
26
- if (this.shadowRoot) {
27
- htmlTmpl.innerHTML = `${styleContent}${this.originContents}`;
28
- this.root.appendChild(htmlTmpl.content.cloneNode(true));
29
- } else {
30
- // Light DOM 모드일 때: 스타일만 상단에 추가
31
- const styleDiv = document.createElement("div");
32
- styleDiv.innerHTML = styleContent;
33
- this.root.prepend(styleDiv);
34
- }
25
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
35
26
  }
36
27
  }
37
28
 
38
- customElements.define("nx-buttons", nxButtons);
29
+ customElements.define("nx-buttons", nxButtons);
@@ -0,0 +1,29 @@
1
+ import ninegrid from "../index.js";
2
+ import {nxDiv} from "./_nxDiv2.js";
3
+
4
+ class nxButtons extends nxDiv2 {
5
+
6
+ constructor() {
7
+ super();
8
+ }
9
+
10
+ connectedCallback() {
11
+ if (super.connectedCallback()) this.#init();
12
+ };
13
+
14
+ #init = () => {
15
+ const htmlTmpl = document.createElement("template");
16
+ htmlTmpl.innerHTML = `
17
+ <style>
18
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
19
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
20
+ </style>
21
+
22
+ ${this.originContents}
23
+ `;
24
+
25
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
26
+ }
27
+ }
28
+
29
+ customElements.define("nx-buttons", nxButtons);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ninegrid2",
3
3
  "type": "module",
4
- "version": "6.1256.0",
4
+ "version": "6.1257.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
package/src/nx/_nxDiv.js CHANGED
@@ -1,48 +1,32 @@
1
1
  import ninegrid from "../index.js";
2
2
 
3
- export class nxDiv extends HTMLElement {
3
+ export class nxDiv extends HTMLElement
4
+ {
4
5
  originContents;
5
6
  #isInitialized = false;
6
- #root; // 탐색 및 렌더링 대상 (shadowRoot 또는 this)
7
7
 
8
- constructor() {
8
+ constructor () {
9
9
  super();
10
- // 1. 옵션 확인 (기본값은 shadow 사용하지 않는 기존 방식처럼 동작 가능하게 설정)
11
- // 만약 기존 소스 그대로 shadow를 쓰고 싶다면 true로, 아니면 속성 체크
12
- const useShadow = this.getAttribute("use-shadow") === "true";
13
-
14
- if (useShadow) {
15
- this.attachShadow({ mode: 'open' });
16
- this.#root = this.shadowRoot;
17
- } else {
18
- this.#root = this;
19
- }
10
+ this.attachShadow({ mode: 'open' });
20
11
  }
21
12
 
22
13
  connectedCallback() {
23
14
  if (!this.#isInitialized) {
24
15
  this.#init();
25
- this.#isInitialized = true;
16
+ this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
26
17
  return true;
27
18
  }
28
- return false;
29
- }
30
-
31
- // 자식에서 접근 가능한 root getter
32
- get root() {
33
- return this.#root;
34
- }
35
19
 
36
- // root에 따라 엘리먼트 탐색
37
- #getElements() {
38
- return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
20
+ return false;
39
21
  }
40
22
 
41
23
  getData = () => {
42
24
  const jsonData = {};
43
- this.#getElements().forEach(el => {
25
+
26
+ // Shadow DOM 내의 폼 요소만 선택
27
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
44
28
  const key = el.name;
45
- if (!key) return;
29
+ if (!key) return; // name이 없는 요소는 건너뜁니다.
46
30
 
47
31
  let value;
48
32
  if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
@@ -51,30 +35,39 @@ export class nxDiv extends HTMLElement {
51
35
  value = el.value;
52
36
  }
53
37
 
38
+ // 중복 name을 대비한 배열 처리
54
39
  if (jsonData[key]) {
55
- if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
40
+ if (!Array.isArray(jsonData[key])) {
41
+ jsonData[key] = [jsonData[key]];
42
+ }
56
43
  jsonData[key].push(value);
57
44
  } else {
58
45
  jsonData[key] = value;
59
46
  }
60
47
  });
48
+
61
49
  return jsonData;
62
50
  };
63
51
 
64
52
  setData = (jsonData) => {
65
- this.#getElements().forEach(el => {
53
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
66
54
  el.removeEventListener("input", this.#changeHandler);
67
55
  el.addEventListener("input", this.#changeHandler);
68
56
  });
69
57
 
70
- if (!jsonData || typeof jsonData !== 'object') return;
58
+ if (!jsonData || typeof jsonData !== 'object') {
59
+ console.error("setData: Invalid data provided. Expected an object.");
60
+ return;
61
+ }
71
62
 
72
63
  let bChanged = false;
73
- this.#getElements().forEach(el => {
64
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
74
65
  const key = el.name;
75
66
  if (!key || !jsonData.hasOwnProperty(key)) return;
76
67
 
77
68
  const value = jsonData[key];
69
+
70
+ // 폼 요소에만 데이터를 설정합니다.
78
71
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
79
72
  if (el.type === "checkbox" || el.type === "radio") {
80
73
  if (el.checked !== (el.value === String(value))) bChanged = true;
@@ -84,10 +77,12 @@ export class nxDiv extends HTMLElement {
84
77
  el.value = value;
85
78
  }
86
79
  } else {
80
+ // 폼 요소가 아닌 경우, textContent를 사용합니다.
87
81
  if (el.textContent !== value) bChanged = true;
88
82
  el.textContent = value;
89
83
  }
90
84
  });
85
+
91
86
  if (bChanged) this.#changed(bChanged);
92
87
  };
93
88
 
@@ -109,27 +104,21 @@ export class nxDiv extends HTMLElement {
109
104
  }
110
105
 
111
106
  #init = () => {
112
- // 1. CSS Style 적용
107
+
108
+ //console.log(this);
109
+ //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
110
+
111
+ /**
112
+ * css style 적용
113
+ */
113
114
  for (const attr of this.attributes) {
114
115
  if (attr.name.startsWith("css-")) {
116
+ // "css-" 접두사를 제거하고 CSS 속성명으로 변환
115
117
  this.style.setProperty(attr.name.substring(4), attr.value);
116
118
  }
117
119
  }
118
120
 
119
- // 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
120
- if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
121
-
122
- // 3. 내부 HTML 보관
123
121
  this.originContents = this.innerHTML.trim();
124
-
125
- // 4. Shadow DOM 사용 시에만 비우고 옮기기
126
- if (this.shadowRoot) {
127
- // 자식 클래스(nxButtons 등)에서 내용을 직접 구성할 수 있도록
128
- // 태그 종류에 따라 선별적으로 내용을 넣어줌
129
- if (this.tagName.toLowerCase() === 'nx-div') {
130
- this.shadowRoot.innerHTML = this.originContents;
131
- }
132
- this.innerHTML = ""; // Light DOM 비움
133
- }
122
+ this.innerHTML = ""; // 기존 내부 HTML 제거
134
123
  };
135
124
  }
@@ -0,0 +1,124 @@
1
+ import ninegrid from "../index.js";
2
+
3
+ export class nxDiv2 extends HTMLElement
4
+ {
5
+ originContents;
6
+ #isInitialized = false;
7
+
8
+ constructor () {
9
+ super();
10
+ this.attachShadow({ mode: 'open' });
11
+ }
12
+
13
+ connectedCallback() {
14
+ if (!this.#isInitialized) {
15
+ this.#init();
16
+ this.#isInitialized = true; // 3. 초기화 후 플래그를 true로 변경합니다.
17
+ return true;
18
+ }
19
+
20
+ return false;
21
+ }
22
+
23
+ getData = () => {
24
+ const jsonData = {};
25
+
26
+ // Shadow DOM 내의 폼 요소만 선택
27
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
28
+ const key = el.name;
29
+ if (!key) return; // name이 없는 요소는 건너뜁니다.
30
+
31
+ let value;
32
+ if (el.tagName === "INPUT" && (el.type === "checkbox" || el.type === "radio")) {
33
+ value = el.checked;
34
+ } else {
35
+ value = el.value;
36
+ }
37
+
38
+ // 중복 name을 대비한 배열 처리
39
+ if (jsonData[key]) {
40
+ if (!Array.isArray(jsonData[key])) {
41
+ jsonData[key] = [jsonData[key]];
42
+ }
43
+ jsonData[key].push(value);
44
+ } else {
45
+ jsonData[key] = value;
46
+ }
47
+ });
48
+
49
+ return jsonData;
50
+ };
51
+
52
+ setData = (jsonData) => {
53
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
54
+ el.removeEventListener("input", this.#changeHandler);
55
+ el.addEventListener("input", this.#changeHandler);
56
+ });
57
+
58
+ if (!jsonData || typeof jsonData !== 'object') {
59
+ console.error("setData: Invalid data provided. Expected an object.");
60
+ return;
61
+ }
62
+
63
+ let bChanged = false;
64
+ ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.shadowRoot).forEach(el => {
65
+ const key = el.name;
66
+ if (!key || !jsonData.hasOwnProperty(key)) return;
67
+
68
+ const value = jsonData[key];
69
+
70
+ // 폼 요소에만 데이터를 설정합니다.
71
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
72
+ if (el.type === "checkbox" || el.type === "radio") {
73
+ if (el.checked !== (el.value === String(value))) bChanged = true;
74
+ el.checked = (el.value === String(value));
75
+ } else {
76
+ if (el.value !== value) bChanged = true;
77
+ el.value = value;
78
+ }
79
+ } else {
80
+ // 폼 요소가 아닌 경우, textContent를 사용합니다.
81
+ if (el.textContent !== value) bChanged = true;
82
+ el.textContent = value;
83
+ }
84
+ });
85
+
86
+ if (bChanged) this.#changed(bChanged);
87
+ };
88
+
89
+ initData = (jsonData) => {
90
+ this.setData(jsonData);
91
+ this.#changed(false);
92
+ };
93
+
94
+ #changed = (v) => {
95
+ const parent = this.closest(".detail-wrapper");
96
+ if (parent) {
97
+ const el = parent.querySelector("nx-title2");
98
+ if (el) el.changed = v;
99
+ }
100
+ }
101
+
102
+ #changeHandler = (e) => {
103
+ this.#changed(true);
104
+ }
105
+
106
+ #init = () => {
107
+
108
+ //console.log(this);
109
+ //console.log(this.querySelectorAll("input[name], textarea[name], select[name]"));
110
+
111
+ /**
112
+ * css style 적용
113
+ */
114
+ for (const attr of this.attributes) {
115
+ if (attr.name.startsWith("css-")) {
116
+ // "css-" 접두사를 제거하고 CSS 속성명으로 변환
117
+ this.style.setProperty(attr.name.substring(4), attr.value);
118
+ }
119
+ }
120
+
121
+ this.originContents = this.innerHTML.trim();
122
+ this.innerHTML = ""; // 기존 내부 HTML 제거
123
+ };
124
+ }
@@ -1,38 +1,29 @@
1
1
  import ninegrid from "../index.js";
2
- import { nxDiv } from "./_nxDiv.js";
2
+ import {nxDiv} from "./_nxDiv.js";
3
3
 
4
4
  class nxButtons extends nxDiv {
5
+
5
6
  constructor() {
6
7
  super();
7
8
  }
8
9
 
9
10
  connectedCallback() {
10
11
  if (super.connectedCallback()) this.#init();
11
- }
12
+ };
12
13
 
13
14
  #init = () => {
14
- // 1. 스타일과 내용을 합친 템플릿 생성
15
- const styleContent = `
16
- <style>
17
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
18
- ${ninegrid.getCustomPath(this, "nxButtons.css")}
19
- </style>
20
- `;
21
-
22
15
  const htmlTmpl = document.createElement("template");
16
+ htmlTmpl.innerHTML = `
17
+ <style>
18
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
19
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
20
+ </style>
21
+
22
+ ${this.originContents}
23
+ `;
23
24
 
24
- // Shadow DOM일 때는 originContents를 옮겨야 하고,
25
- // Light DOM일 때는 이미 본문에 있으므로 스타일만 추가하면 됨
26
- if (this.shadowRoot) {
27
- htmlTmpl.innerHTML = `${styleContent}${this.originContents}`;
28
- this.root.appendChild(htmlTmpl.content.cloneNode(true));
29
- } else {
30
- // Light DOM 모드일 때: 스타일만 상단에 추가
31
- const styleDiv = document.createElement("div");
32
- styleDiv.innerHTML = styleContent;
33
- this.root.prepend(styleDiv);
34
- }
25
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
35
26
  }
36
27
  }
37
28
 
38
- customElements.define("nx-buttons", nxButtons);
29
+ customElements.define("nx-buttons", nxButtons);
@@ -0,0 +1,29 @@
1
+ import ninegrid from "../index.js";
2
+ import {nxDiv} from "./_nxDiv2.js";
3
+
4
+ class nxButtons extends nxDiv2 {
5
+
6
+ constructor() {
7
+ super();
8
+ }
9
+
10
+ connectedCallback() {
11
+ if (super.connectedCallback()) this.#init();
12
+ };
13
+
14
+ #init = () => {
15
+ const htmlTmpl = document.createElement("template");
16
+ htmlTmpl.innerHTML = `
17
+ <style>
18
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
19
+ ${ninegrid.getCustomPath(this,"nxButtons.css")}
20
+ </style>
21
+
22
+ ${this.originContents}
23
+ `;
24
+
25
+ this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
26
+ }
27
+ }
28
+
29
+ customElements.define("nx-buttons", nxButtons);