ninegrid2 6.1256.0 → 6.1258.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.
- package/dist/bundle.cjs.js +40 -45
- package/dist/bundle.esm.js +40 -45
- package/dist/nx/_nxDiv.js +29 -25
- package/dist/nx/_nxDiv2.js +5 -6
- package/dist/nx/nxButtons.js +13 -22
- package/dist/nx/nxButtons2.js +29 -0
- package/package.json +1 -1
- package/src/nx/_nxDiv.js +29 -25
- package/src/nx/nxButtons.js +13 -22
package/dist/bundle.cjs.js
CHANGED
|
@@ -121841,24 +121841,26 @@ customElements.define("nx-title", nxTitle);
|
|
|
121841
121841
|
class nxDiv extends HTMLElement {
|
|
121842
121842
|
originContents;
|
|
121843
121843
|
#isInitialized = false;
|
|
121844
|
-
#root; //
|
|
121844
|
+
#root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
|
|
121845
121845
|
|
|
121846
121846
|
constructor() {
|
|
121847
121847
|
super();
|
|
121848
|
-
//
|
|
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
|
+
// constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
|
|
121858
121849
|
}
|
|
121859
121850
|
|
|
121860
121851
|
connectedCallback() {
|
|
121861
121852
|
if (!this.#isInitialized) {
|
|
121853
|
+
// 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
|
|
121854
|
+
// use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
|
|
121855
|
+
const useShadow = this.getAttribute("use-shadow") !== "false";
|
|
121856
|
+
|
|
121857
|
+
if (useShadow && !this.shadowRoot) {
|
|
121858
|
+
this.attachShadow({ mode: 'open' });
|
|
121859
|
+
this.#root = this.shadowRoot;
|
|
121860
|
+
} else {
|
|
121861
|
+
this.#root = this;
|
|
121862
|
+
}
|
|
121863
|
+
|
|
121862
121864
|
this.#init();
|
|
121863
121865
|
this.#isInitialized = true;
|
|
121864
121866
|
return true;
|
|
@@ -121866,13 +121868,14 @@ class nxDiv extends HTMLElement {
|
|
|
121866
121868
|
return false;
|
|
121867
121869
|
}
|
|
121868
121870
|
|
|
121869
|
-
//
|
|
121871
|
+
// 자식 클래스에서 접근 가능하도록 getter 제공
|
|
121870
121872
|
get root() {
|
|
121871
|
-
return this.#root;
|
|
121873
|
+
return this.#root || this;
|
|
121872
121874
|
}
|
|
121873
121875
|
|
|
121874
|
-
// root
|
|
121876
|
+
// 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
|
|
121875
121877
|
#getElements() {
|
|
121878
|
+
// ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
|
|
121876
121879
|
return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
|
|
121877
121880
|
}
|
|
121878
121881
|
|
|
@@ -121915,8 +121918,9 @@ class nxDiv extends HTMLElement {
|
|
|
121915
121918
|
const value = jsonData[key];
|
|
121916
121919
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
|
|
121917
121920
|
if (el.type === "checkbox" || el.type === "radio") {
|
|
121918
|
-
|
|
121919
|
-
el.checked
|
|
121921
|
+
const isChecked = (String(el.value) === String(value));
|
|
121922
|
+
if (el.checked !== isChecked) bChanged = true;
|
|
121923
|
+
el.checked = isChecked;
|
|
121920
121924
|
} else {
|
|
121921
121925
|
if (el.value !== value) bChanged = true;
|
|
121922
121926
|
el.value = value;
|
|
@@ -121947,28 +121951,28 @@ class nxDiv extends HTMLElement {
|
|
|
121947
121951
|
}
|
|
121948
121952
|
|
|
121949
121953
|
#init = () => {
|
|
121950
|
-
|
|
121954
|
+
/** CSS style 적용 */
|
|
121951
121955
|
for (const attr of this.attributes) {
|
|
121952
121956
|
if (attr.name.startsWith("css-")) {
|
|
121953
121957
|
this.style.setProperty(attr.name.substring(4), attr.value);
|
|
121954
121958
|
}
|
|
121955
121959
|
}
|
|
121956
121960
|
|
|
121957
|
-
// 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
|
|
121958
|
-
if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
|
|
121959
|
-
|
|
121960
|
-
// 3. 내부 HTML 보관
|
|
121961
121961
|
this.originContents = this.innerHTML.trim();
|
|
121962
|
+
this.innerHTML = ""; // 기존 내부 HTML 제거
|
|
121962
121963
|
|
|
121963
|
-
|
|
121964
|
+
/**
|
|
121965
|
+
// 2. Shadow DOM을 사용할 때만 내용을 안으로 옮기고 밖을 비웁니다.
|
|
121964
121966
|
if (this.shadowRoot) {
|
|
121965
|
-
// 자식 클래스(nxButtons 등)
|
|
121966
|
-
//
|
|
121967
|
+
// 상속받은 자식 클래스(nxButtons 등)가 직접 렌더링하는 경우를 위해
|
|
121968
|
+
// nx-div 태그일 때만 자동으로 내용을 옮겨줍니다.
|
|
121967
121969
|
if (this.tagName.toLowerCase() === 'nx-div') {
|
|
121968
121970
|
this.shadowRoot.innerHTML = this.originContents;
|
|
121969
121971
|
}
|
|
121970
|
-
this.innerHTML = "";
|
|
121972
|
+
this.innerHTML = "";
|
|
121971
121973
|
}
|
|
121974
|
+
// Shadow DOM을 안 쓰면 Light DOM 상태이므로 innerHTML을 유지합니다.
|
|
121975
|
+
*/
|
|
121972
121976
|
};
|
|
121973
121977
|
}
|
|
121974
121978
|
|
|
@@ -122255,36 +122259,27 @@ class nxPanel extends nxDiv {
|
|
|
122255
122259
|
customElements.define("nx-panel", nxPanel);
|
|
122256
122260
|
|
|
122257
122261
|
class nxButtons extends nxDiv {
|
|
122262
|
+
|
|
122258
122263
|
constructor() {
|
|
122259
122264
|
super();
|
|
122260
122265
|
}
|
|
122261
122266
|
|
|
122262
122267
|
connectedCallback() {
|
|
122263
122268
|
if (super.connectedCallback()) this.#init();
|
|
122264
|
-
}
|
|
122269
|
+
};
|
|
122265
122270
|
|
|
122266
122271
|
#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
122272
|
const htmlTmpl = document.createElement("template");
|
|
122273
|
+
htmlTmpl.innerHTML = `
|
|
122274
|
+
<style>
|
|
122275
|
+
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
|
|
122276
|
+
${ninegrid.getCustomPath(this,"nxButtons.css")}
|
|
122277
|
+
</style>
|
|
122278
|
+
|
|
122279
|
+
${this.originContents}
|
|
122280
|
+
`;
|
|
122276
122281
|
|
|
122277
|
-
|
|
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
|
-
}
|
|
122282
|
+
this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
|
|
122288
122283
|
}
|
|
122289
122284
|
}
|
|
122290
122285
|
|
package/dist/bundle.esm.js
CHANGED
|
@@ -121837,24 +121837,26 @@ customElements.define("nx-title", nxTitle);
|
|
|
121837
121837
|
class nxDiv extends HTMLElement {
|
|
121838
121838
|
originContents;
|
|
121839
121839
|
#isInitialized = false;
|
|
121840
|
-
#root; //
|
|
121840
|
+
#root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
|
|
121841
121841
|
|
|
121842
121842
|
constructor() {
|
|
121843
121843
|
super();
|
|
121844
|
-
//
|
|
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
|
+
// constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
|
|
121854
121845
|
}
|
|
121855
121846
|
|
|
121856
121847
|
connectedCallback() {
|
|
121857
121848
|
if (!this.#isInitialized) {
|
|
121849
|
+
// 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
|
|
121850
|
+
// use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
|
|
121851
|
+
const useShadow = this.getAttribute("use-shadow") !== "false";
|
|
121852
|
+
|
|
121853
|
+
if (useShadow && !this.shadowRoot) {
|
|
121854
|
+
this.attachShadow({ mode: 'open' });
|
|
121855
|
+
this.#root = this.shadowRoot;
|
|
121856
|
+
} else {
|
|
121857
|
+
this.#root = this;
|
|
121858
|
+
}
|
|
121859
|
+
|
|
121858
121860
|
this.#init();
|
|
121859
121861
|
this.#isInitialized = true;
|
|
121860
121862
|
return true;
|
|
@@ -121862,13 +121864,14 @@ class nxDiv extends HTMLElement {
|
|
|
121862
121864
|
return false;
|
|
121863
121865
|
}
|
|
121864
121866
|
|
|
121865
|
-
//
|
|
121867
|
+
// 자식 클래스에서 접근 가능하도록 getter 제공
|
|
121866
121868
|
get root() {
|
|
121867
|
-
return this.#root;
|
|
121869
|
+
return this.#root || this;
|
|
121868
121870
|
}
|
|
121869
121871
|
|
|
121870
|
-
// root
|
|
121872
|
+
// 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
|
|
121871
121873
|
#getElements() {
|
|
121874
|
+
// ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
|
|
121872
121875
|
return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
|
|
121873
121876
|
}
|
|
121874
121877
|
|
|
@@ -121911,8 +121914,9 @@ class nxDiv extends HTMLElement {
|
|
|
121911
121914
|
const value = jsonData[key];
|
|
121912
121915
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
|
|
121913
121916
|
if (el.type === "checkbox" || el.type === "radio") {
|
|
121914
|
-
|
|
121915
|
-
el.checked
|
|
121917
|
+
const isChecked = (String(el.value) === String(value));
|
|
121918
|
+
if (el.checked !== isChecked) bChanged = true;
|
|
121919
|
+
el.checked = isChecked;
|
|
121916
121920
|
} else {
|
|
121917
121921
|
if (el.value !== value) bChanged = true;
|
|
121918
121922
|
el.value = value;
|
|
@@ -121943,28 +121947,28 @@ class nxDiv extends HTMLElement {
|
|
|
121943
121947
|
}
|
|
121944
121948
|
|
|
121945
121949
|
#init = () => {
|
|
121946
|
-
|
|
121950
|
+
/** CSS style 적용 */
|
|
121947
121951
|
for (const attr of this.attributes) {
|
|
121948
121952
|
if (attr.name.startsWith("css-")) {
|
|
121949
121953
|
this.style.setProperty(attr.name.substring(4), attr.value);
|
|
121950
121954
|
}
|
|
121951
121955
|
}
|
|
121952
121956
|
|
|
121953
|
-
// 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
|
|
121954
|
-
if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
|
|
121955
|
-
|
|
121956
|
-
// 3. 내부 HTML 보관
|
|
121957
121957
|
this.originContents = this.innerHTML.trim();
|
|
121958
|
+
this.innerHTML = ""; // 기존 내부 HTML 제거
|
|
121958
121959
|
|
|
121959
|
-
|
|
121960
|
+
/**
|
|
121961
|
+
// 2. Shadow DOM을 사용할 때만 내용을 안으로 옮기고 밖을 비웁니다.
|
|
121960
121962
|
if (this.shadowRoot) {
|
|
121961
|
-
// 자식 클래스(nxButtons 등)
|
|
121962
|
-
//
|
|
121963
|
+
// 상속받은 자식 클래스(nxButtons 등)가 직접 렌더링하는 경우를 위해
|
|
121964
|
+
// nx-div 태그일 때만 자동으로 내용을 옮겨줍니다.
|
|
121963
121965
|
if (this.tagName.toLowerCase() === 'nx-div') {
|
|
121964
121966
|
this.shadowRoot.innerHTML = this.originContents;
|
|
121965
121967
|
}
|
|
121966
|
-
this.innerHTML = "";
|
|
121968
|
+
this.innerHTML = "";
|
|
121967
121969
|
}
|
|
121970
|
+
// Shadow DOM을 안 쓰면 Light DOM 상태이므로 innerHTML을 유지합니다.
|
|
121971
|
+
*/
|
|
121968
121972
|
};
|
|
121969
121973
|
}
|
|
121970
121974
|
|
|
@@ -122251,36 +122255,27 @@ class nxPanel extends nxDiv {
|
|
|
122251
122255
|
customElements.define("nx-panel", nxPanel);
|
|
122252
122256
|
|
|
122253
122257
|
class nxButtons extends nxDiv {
|
|
122258
|
+
|
|
122254
122259
|
constructor() {
|
|
122255
122260
|
super();
|
|
122256
122261
|
}
|
|
122257
122262
|
|
|
122258
122263
|
connectedCallback() {
|
|
122259
122264
|
if (super.connectedCallback()) this.#init();
|
|
122260
|
-
}
|
|
122265
|
+
};
|
|
122261
122266
|
|
|
122262
122267
|
#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
122268
|
const htmlTmpl = document.createElement("template");
|
|
122269
|
+
htmlTmpl.innerHTML = `
|
|
122270
|
+
<style>
|
|
122271
|
+
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxButtons.css";
|
|
122272
|
+
${ninegrid.getCustomPath(this,"nxButtons.css")}
|
|
122273
|
+
</style>
|
|
122274
|
+
|
|
122275
|
+
${this.originContents}
|
|
122276
|
+
`;
|
|
122272
122277
|
|
|
122273
|
-
|
|
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
|
-
}
|
|
122278
|
+
this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
|
|
122284
122279
|
}
|
|
122285
122280
|
}
|
|
122286
122281
|
|
package/dist/nx/_nxDiv.js
CHANGED
|
@@ -3,24 +3,26 @@ import ninegrid from "../index.js";
|
|
|
3
3
|
export class nxDiv extends HTMLElement {
|
|
4
4
|
originContents;
|
|
5
5
|
#isInitialized = false;
|
|
6
|
-
#root; //
|
|
6
|
+
#root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
|
|
7
7
|
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
-
//
|
|
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
|
+
// constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
|
|
20
11
|
}
|
|
21
12
|
|
|
22
13
|
connectedCallback() {
|
|
23
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
|
+
|
|
24
26
|
this.#init();
|
|
25
27
|
this.#isInitialized = true;
|
|
26
28
|
return true;
|
|
@@ -28,13 +30,14 @@ export class nxDiv extends HTMLElement {
|
|
|
28
30
|
return false;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
//
|
|
33
|
+
// 자식 클래스에서 접근 가능하도록 getter 제공
|
|
32
34
|
get root() {
|
|
33
|
-
return this.#root;
|
|
35
|
+
return this.#root || this;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
// root
|
|
38
|
+
// 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
|
|
37
39
|
#getElements() {
|
|
40
|
+
// ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
|
|
38
41
|
return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -77,8 +80,9 @@ export class nxDiv extends HTMLElement {
|
|
|
77
80
|
const value = jsonData[key];
|
|
78
81
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
|
|
79
82
|
if (el.type === "checkbox" || el.type === "radio") {
|
|
80
|
-
|
|
81
|
-
el.checked
|
|
83
|
+
const isChecked = (String(el.value) === String(value));
|
|
84
|
+
if (el.checked !== isChecked) bChanged = true;
|
|
85
|
+
el.checked = isChecked;
|
|
82
86
|
} else {
|
|
83
87
|
if (el.value !== value) bChanged = true;
|
|
84
88
|
el.value = value;
|
|
@@ -109,27 +113,27 @@ export class nxDiv extends HTMLElement {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
#init = () => {
|
|
112
|
-
|
|
116
|
+
/** CSS style 적용 */
|
|
113
117
|
for (const attr of this.attributes) {
|
|
114
118
|
if (attr.name.startsWith("css-")) {
|
|
115
119
|
this.style.setProperty(attr.name.substring(4), attr.value);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
// 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
|
|
120
|
-
if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
|
|
121
|
-
|
|
122
|
-
// 3. 내부 HTML 보관
|
|
123
123
|
this.originContents = this.innerHTML.trim();
|
|
124
|
+
this.innerHTML = ""; // 기존 내부 HTML 제거
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
/**
|
|
127
|
+
// 2. Shadow DOM을 사용할 때만 내용을 안으로 옮기고 밖을 비웁니다.
|
|
126
128
|
if (this.shadowRoot) {
|
|
127
|
-
// 자식 클래스(nxButtons 등)
|
|
128
|
-
//
|
|
129
|
+
// 상속받은 자식 클래스(nxButtons 등)가 직접 렌더링하는 경우를 위해
|
|
130
|
+
// nx-div 태그일 때만 자동으로 내용을 옮겨줍니다.
|
|
129
131
|
if (this.tagName.toLowerCase() === 'nx-div') {
|
|
130
132
|
this.shadowRoot.innerHTML = this.originContents;
|
|
131
133
|
}
|
|
132
|
-
this.innerHTML = "";
|
|
134
|
+
this.innerHTML = "";
|
|
133
135
|
}
|
|
136
|
+
// Shadow DOM을 안 쓰면 Light DOM 상태이므로 innerHTML을 유지합니다.
|
|
137
|
+
*/
|
|
134
138
|
};
|
|
135
139
|
}
|
package/dist/nx/_nxDiv2.js
CHANGED
|
@@ -7,9 +7,9 @@ export class nxDiv2 extends HTMLElement
|
|
|
7
7
|
|
|
8
8
|
constructor () {
|
|
9
9
|
super();
|
|
10
|
-
|
|
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
|
|
package/dist/nx/nxButtons.js
CHANGED
|
@@ -1,38 +1,29 @@
|
|
|
1
1
|
import ninegrid from "../index.js";
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
package/src/nx/_nxDiv.js
CHANGED
|
@@ -3,24 +3,26 @@ import ninegrid from "../index.js";
|
|
|
3
3
|
export class nxDiv extends HTMLElement {
|
|
4
4
|
originContents;
|
|
5
5
|
#isInitialized = false;
|
|
6
|
-
#root; //
|
|
6
|
+
#root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
|
|
7
7
|
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
-
//
|
|
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
|
+
// constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
|
|
20
11
|
}
|
|
21
12
|
|
|
22
13
|
connectedCallback() {
|
|
23
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
|
+
|
|
24
26
|
this.#init();
|
|
25
27
|
this.#isInitialized = true;
|
|
26
28
|
return true;
|
|
@@ -28,13 +30,14 @@ export class nxDiv extends HTMLElement {
|
|
|
28
30
|
return false;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
//
|
|
33
|
+
// 자식 클래스에서 접근 가능하도록 getter 제공
|
|
32
34
|
get root() {
|
|
33
|
-
return this.#root;
|
|
35
|
+
return this.#root || this;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
// root
|
|
38
|
+
// 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
|
|
37
39
|
#getElements() {
|
|
40
|
+
// ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
|
|
38
41
|
return ninegrid.querySelectorAll("input[name], textarea[name], select[name]", this.#root);
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -77,8 +80,9 @@ export class nxDiv extends HTMLElement {
|
|
|
77
80
|
const value = jsonData[key];
|
|
78
81
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
|
|
79
82
|
if (el.type === "checkbox" || el.type === "radio") {
|
|
80
|
-
|
|
81
|
-
el.checked
|
|
83
|
+
const isChecked = (String(el.value) === String(value));
|
|
84
|
+
if (el.checked !== isChecked) bChanged = true;
|
|
85
|
+
el.checked = isChecked;
|
|
82
86
|
} else {
|
|
83
87
|
if (el.value !== value) bChanged = true;
|
|
84
88
|
el.value = value;
|
|
@@ -109,27 +113,27 @@ export class nxDiv extends HTMLElement {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
#init = () => {
|
|
112
|
-
|
|
116
|
+
/** CSS style 적용 */
|
|
113
117
|
for (const attr of this.attributes) {
|
|
114
118
|
if (attr.name.startsWith("css-")) {
|
|
115
119
|
this.style.setProperty(attr.name.substring(4), attr.value);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
// 2. 중요: 이미 데이터가 옮겨졌거나 초기화 중복 실행 방지
|
|
120
|
-
if (this.shadowRoot && this.shadowRoot.innerHTML !== "") return;
|
|
121
|
-
|
|
122
|
-
// 3. 내부 HTML 보관
|
|
123
123
|
this.originContents = this.innerHTML.trim();
|
|
124
|
+
this.innerHTML = ""; // 기존 내부 HTML 제거
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
/**
|
|
127
|
+
// 2. Shadow DOM을 사용할 때만 내용을 안으로 옮기고 밖을 비웁니다.
|
|
126
128
|
if (this.shadowRoot) {
|
|
127
|
-
// 자식 클래스(nxButtons 등)
|
|
128
|
-
//
|
|
129
|
+
// 상속받은 자식 클래스(nxButtons 등)가 직접 렌더링하는 경우를 위해
|
|
130
|
+
// nx-div 태그일 때만 자동으로 내용을 옮겨줍니다.
|
|
129
131
|
if (this.tagName.toLowerCase() === 'nx-div') {
|
|
130
132
|
this.shadowRoot.innerHTML = this.originContents;
|
|
131
133
|
}
|
|
132
|
-
this.innerHTML = "";
|
|
134
|
+
this.innerHTML = "";
|
|
133
135
|
}
|
|
136
|
+
// Shadow DOM을 안 쓰면 Light DOM 상태이므로 innerHTML을 유지합니다.
|
|
137
|
+
*/
|
|
134
138
|
};
|
|
135
139
|
}
|
package/src/nx/nxButtons.js
CHANGED
|
@@ -1,38 +1,29 @@
|
|
|
1
1
|
import ninegrid from "../index.js";
|
|
2
|
-
import {
|
|
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
|
-
|
|
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);
|