@ninebone/util 0.9.184 → 0.9.187

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.
@@ -49,3 +49,15 @@
49
49
  }
50
50
  }
51
51
 
52
+ :host(nine-popup) {
53
+ display: none; position: fixed; top:0; left:0; width:100vw; height:100vh; z-index: 9999;
54
+ &.open {
55
+ display: block;
56
+ }
57
+ .popup-dimmed { position:absolute; width:100%; height:100%; background: rgba(0,0,0,0.5); display:flex; justify-content:center; align-items:center; }
58
+ .popup-content { background: #fff; border-radius: 8px; min-width: 400px; box-shadow: 0 4px 15px rgba(0,0,0,0.2); display: flex; flex-direction: column; }
59
+ .popup-header { padding: 15px; border-bottom: 1px solid #eee; font-weight: bold; }
60
+ .popup-body { padding: 20px; min-height: 150px; }
61
+ }
62
+
63
+
package/dist/nine-util.js CHANGED
@@ -9,7 +9,9 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
9
9
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
10
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
11
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
- var _name, _color, _Trace_instances, isTraceEnabled_fn, _a, _timer, _queue, _delay, _TaskDebouncer_instances, flush_fn, _request, _shift, _dialog, _init, _onMouseDown, _onTouchStart, _NineUxUtil_instances, prepare_fn, _mode, _detectMode, _startDrag, _init2, _prepareLayout;
12
+ var _name, _color, _Trace_instances, isTraceEnabled_fn, _a, _timer, _queue, _delay, _TaskDebouncer_instances, flush_fn, _request, _shift, _dialog, _init, _onMouseDown, _onTouchStart, _NineUxUtil_instances, prepare_fn, _mode, _detectMode, _startDrag, _init2, _prepareLayout, _onCloseCallback, _isInitialized, _root, _NinePopup_instances, renderStructure_fn;
13
+ import React from "react";
14
+ import { createRoot } from "react-dom/client";
13
15
  const listeners = /* @__PURE__ */ new Set();
14
16
  const _initialConfig = {
15
17
  ux: { nativeOverride: false, theme: "light" },
@@ -1185,12 +1187,13 @@ class UxSplitter extends HTMLElement {
1185
1187
  this.classList.add(__privateGet(this, _mode));
1186
1188
  const contents = this.innerHTML.trim();
1187
1189
  const gripTmpl = contents === "" ? `<div class="grip"></div>` : `<div class="grip"></div><div class="inner-container">${contents}</div><div class="grip"></div>`;
1190
+ const customImport = nine.cssPath ? `@import "${nine.cssPath}/nine-util.css";` : "";
1188
1191
  this.innerHTML = "";
1189
1192
  const htmlTmpl = document.createElement("template");
1190
1193
  htmlTmpl.innerHTML = `
1191
1194
  <style>
1192
- @import "https://cdn.jsdelivr.net/npm/@ninebone/util@${"0.9.184"}/dist/css/nine-util.css";
1193
- ${this.cssPath ? `@import "${this.cssPath}";` : ""}
1195
+ @import "https://cdn.jsdelivr.net/npm/@ninebone/util@${"0.9.187"}/dist/css/nine-util.css";
1196
+ ${customImport}
1194
1197
  </style>
1195
1198
  ${gripTmpl}
1196
1199
  `;
@@ -1526,13 +1529,155 @@ var dayjs_minExports = requireDayjs_min();
1526
1529
  const dayjs = /* @__PURE__ */ getDefaultExportFromCjs(dayjs_minExports);
1527
1530
  class NineUtil {
1528
1531
  constructor() {
1529
- // static 필드는 클래스 자체에 저장됨
1532
+ // 📅 1. 날짜 포맷 헬퍼 (인스턴스 메서드)
1530
1533
  __publicField(this, "formatDate", (v, fmt) => {
1531
1534
  return dayjs(v).format(fmt);
1532
1535
  });
1536
+ /**
1537
+ * 🔮 2. 함수 호출형 만능 동적 팝업 엔진
1538
+ * @param {React.Component} ContentComponent - 팝업 내부에 띄울 리액트 컴포넌트 알맹이
1539
+ * @param {Object} props - 팝업 알맹이에 넘겨줄 Props 데이터 (선택)
1540
+ * @param {Function} onCloseCallback - 팝업이 닫힐 때 데이터를 받아먹을 콜백 함수 (선택)
1541
+ */
1542
+ __publicField(this, "popup", (ContentComponent, props = {}, onCloseCallback = null) => {
1543
+ const $popupWrapper = document.createElement("nine-popup");
1544
+ document.body.appendChild($popupWrapper);
1545
+ const $bodySpace = $popupWrapper.popupBody || $popupWrapper;
1546
+ const root = createRoot($bodySpace);
1547
+ $popupWrapper.onclose = (resultData) => {
1548
+ if (typeof onCloseCallback === "function") {
1549
+ onCloseCallback(resultData);
1550
+ }
1551
+ setTimeout(() => {
1552
+ root.unmount();
1553
+ $popupWrapper.remove();
1554
+ }, 300);
1555
+ };
1556
+ root.render(React.createElement(ContentComponent, props));
1557
+ setTimeout(() => $popupWrapper.open(), 0);
1558
+ });
1559
+ /**
1560
+ * 🎯 2. Shadow DOM 경계를 무력화하고 깊이 상관없이 모든 요소를 수집하는 만능 쿼리
1561
+ * @param {string} selector - 찾고자 하는 CSS 선택자 (예: 'input[name]')
1562
+ * @param {HTMLElement|ShadowRoot|Document} root - 탐색 시작점
1563
+ * @returns {HTMLElement[]} 매칭된 자바스크립트 DOM 엘리먼트 배열
1564
+ */
1565
+ __publicField(this, "querySelectorAll", (selector, root = document) => {
1566
+ const results = [];
1567
+ const search = (node) => {
1568
+ var _a2;
1569
+ if (!node) return;
1570
+ if (node.shadowRoot) {
1571
+ search(node.shadowRoot);
1572
+ }
1573
+ (_a2 = node.querySelectorAll) == null ? void 0 : _a2.call(node, selector).forEach((elem) => {
1574
+ if (!results.includes(elem)) {
1575
+ results.push(elem);
1576
+ }
1577
+ });
1578
+ const children = node.children ? Array.from(node.children) : [];
1579
+ children.forEach((child) => {
1580
+ search(child);
1581
+ });
1582
+ };
1583
+ search(root);
1584
+ return results;
1585
+ });
1586
+ /**
1587
+ * 🎯 3. Shadow DOM 경계를 뚫고 가장 먼저 매칭되는 단 하나의 요소를 반환 (조기 종료 최적화)
1588
+ * @param {string} selector - 찾고자 하는 CSS 선택자
1589
+ * @param {HTMLElement|ShadowRoot|Document} root - 탐색 시작점
1590
+ * @returns {HTMLElement|null} 매칭된 엘리먼트 객체 또는 null
1591
+ */
1592
+ __publicField(this, "querySelector", (selector, root = document) => {
1593
+ var _a2;
1594
+ if (!root) return null;
1595
+ let found = (_a2 = root.querySelector) == null ? void 0 : _a2.call(root, selector);
1596
+ if (found) return found;
1597
+ if (root.shadowRoot) {
1598
+ found = this.querySelector(selector, root.shadowRoot);
1599
+ if (found) return found;
1600
+ }
1601
+ const children = root.children ? Array.from(root.children) : [];
1602
+ for (const child of children) {
1603
+ found = this.querySelector(selector, child);
1604
+ if (found) return found;
1605
+ }
1606
+ return null;
1607
+ });
1533
1608
  }
1534
1609
  }
1535
1610
  Object.assign(nine$1, new NineUtil());
1611
+ class NinePopup extends HTMLElement {
1612
+ // 🔒 Shadow DOM 루트를 담을 주머니
1613
+ constructor() {
1614
+ super();
1615
+ __privateAdd(this, _NinePopup_instances);
1616
+ __privateAdd(this, _onCloseCallback, null);
1617
+ __privateAdd(this, _isInitialized, false);
1618
+ __privateAdd(this, _root);
1619
+ }
1620
+ get _onCloseCallback() {
1621
+ return __privateGet(this, _onCloseCallback);
1622
+ }
1623
+ set onclose(callbackFunc) {
1624
+ if (typeof callbackFunc === "function") __privateSet(this, _onCloseCallback, callbackFunc);
1625
+ }
1626
+ connectedCallback() {
1627
+ if (__privateGet(this, _isInitialized)) return;
1628
+ if (!this.shadowRoot) {
1629
+ this.attachShadow({ mode: "open" });
1630
+ }
1631
+ __privateSet(this, _root, this.shadowRoot);
1632
+ __privateMethod(this, _NinePopup_instances, renderStructure_fn).call(this);
1633
+ __privateSet(this, _isInitialized, true);
1634
+ }
1635
+ open() {
1636
+ this.classList.add("open");
1637
+ }
1638
+ close(callbackData = null) {
1639
+ this.classList.remove("open");
1640
+ if (typeof __privateGet(this, _onCloseCallback) === "function") {
1641
+ __privateGet(this, _onCloseCallback).call(this, callbackData);
1642
+ }
1643
+ }
1644
+ // 🔒 [퍼블릭 게터] 동적 렌더링 엔진(NineUtil)이 Shadow DOM 내부의 바디 공간을 찾을 수 있도록 통로 개방
1645
+ get popupBody() {
1646
+ var _a2;
1647
+ return ((_a2 = __privateGet(this, _root)) == null ? void 0 : _a2.querySelector(".popup-body")) || null;
1648
+ }
1649
+ }
1650
+ _onCloseCallback = new WeakMap();
1651
+ _isInitialized = new WeakMap();
1652
+ _root = new WeakMap();
1653
+ _NinePopup_instances = new WeakSet();
1654
+ renderStructure_fn = function() {
1655
+ if (__privateGet(this, _root).querySelector(".popup-dimmed")) return;
1656
+ const $dimmed = document.createElement("div");
1657
+ $dimmed.className = "popup-dimmed";
1658
+ $dimmed.addEventListener("click", (e) => {
1659
+ if (e.target === $dimmed) this.close();
1660
+ });
1661
+ const $content = document.createElement("div");
1662
+ $content.className = "popup-content";
1663
+ const customImport = nine.cssPath ? `@import "${nine.cssPath}/nine-util.css";` : "";
1664
+ $content.innerHTML = `
1665
+ <style>
1666
+ @import "https://cdn.jsdelivr.net/npm/@ninebone/util@${"0.9.187"}/dist/css/nine-util.css";
1667
+ ${customImport}
1668
+ </style>
1669
+
1670
+ <div class="popup-header"></div>
1671
+ <div class="popup-body"></div>
1672
+ `;
1673
+ const $bodySpace = $content.querySelector(".popup-body");
1674
+ while (this.firstChild) {
1675
+ $bodySpace.appendChild(this.firstChild);
1676
+ }
1677
+ $dimmed.appendChild($content);
1678
+ __privateGet(this, _root).appendChild($dimmed);
1679
+ };
1680
+ if (!customElements.get("nine-popup")) customElements.define("nine-popup", NinePopup);
1536
1681
  nine$1.safe = safe;
1537
1682
  nine$1.api = api;
1538
1683
  nine$1.trace = trace$2;