@designbasekorea/ui-wc 0.8.1 → 0.8.3

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.
Files changed (162) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +18 -1
  3. package/dist/esm/components/animation-background/controls.js +1 -1
  4. package/dist/esm/components/animation-background/layers.js +1 -1
  5. package/dist/esm/components/db-accordion.d.ts +1 -1
  6. package/dist/esm/components/db-activity-heatmap.d.ts +38 -0
  7. package/dist/esm/components/db-activity-heatmap.js +1 -0
  8. package/dist/esm/components/db-animation-background.d.ts +2 -0
  9. package/dist/esm/components/db-animation-background.js +1 -1
  10. package/dist/esm/components/db-app-badge.d.ts +2 -0
  11. package/dist/esm/components/db-app-badge.js +1 -1
  12. package/dist/esm/components/db-audio-player.d.ts +4 -0
  13. package/dist/esm/components/db-audio-player.js +1 -1
  14. package/dist/esm/components/db-avatar.js +1 -1
  15. package/dist/esm/components/db-backdrop.d.ts +4 -0
  16. package/dist/esm/components/db-backdrop.js +1 -1
  17. package/dist/esm/components/db-badge.d.ts +2 -2
  18. package/dist/esm/components/db-badge.js +1 -1
  19. package/dist/esm/components/db-bottom-navigation.js +1 -1
  20. package/dist/esm/components/db-bottom-sheet.d.ts +5 -0
  21. package/dist/esm/components/db-bottom-sheet.js +1 -1
  22. package/dist/esm/components/db-breadcrumbs.d.ts +1 -1
  23. package/dist/esm/components/db-button.d.ts +13 -0
  24. package/dist/esm/components/db-button.js +1 -1
  25. package/dist/esm/components/db-calendar.js +1 -1
  26. package/dist/esm/components/db-card.js +1 -1
  27. package/dist/esm/components/db-carousel.js +1 -1
  28. package/dist/esm/components/db-chat-composer.d.ts +14 -0
  29. package/dist/esm/components/db-chat-composer.js +1 -1
  30. package/dist/esm/components/db-chat-message.d.ts +15 -2
  31. package/dist/esm/components/db-chat-message.js +1 -1
  32. package/dist/esm/components/db-chat-orb.d.ts +6 -8
  33. package/dist/esm/components/db-chat-orb.js +1 -1
  34. package/dist/esm/components/db-chat-room.d.ts +12 -1
  35. package/dist/esm/components/db-chat-room.js +1 -1
  36. package/dist/esm/components/db-chat-welcome.js +1 -1
  37. package/dist/esm/components/db-chat-widget.d.ts +43 -10
  38. package/dist/esm/components/db-chat-widget.js +1 -1
  39. package/dist/esm/components/db-checkbox.d.ts +11 -0
  40. package/dist/esm/components/db-checkbox.js +1 -1
  41. package/dist/esm/components/db-chip.js +1 -1
  42. package/dist/esm/components/db-color-picker.js +1 -1
  43. package/dist/esm/components/db-confirm.d.ts +5 -0
  44. package/dist/esm/components/db-confirm.js +1 -1
  45. package/dist/esm/components/db-container.js +1 -1
  46. package/dist/esm/components/db-cookie-banner.js +1 -1
  47. package/dist/esm/components/db-date-picker.d.ts +4 -1
  48. package/dist/esm/components/db-date-picker.js +1 -1
  49. package/dist/esm/components/db-divider.js +1 -1
  50. package/dist/esm/components/db-download-progress.d.ts +3 -4
  51. package/dist/esm/components/db-download-progress.js +1 -1
  52. package/dist/esm/components/db-drawer.d.ts +5 -1
  53. package/dist/esm/components/db-drawer.js +1 -1
  54. package/dist/esm/components/db-dropdown.js +1 -1
  55. package/dist/esm/components/db-dropzone.js +1 -1
  56. package/dist/esm/components/db-email-verify.d.ts +2 -2
  57. package/dist/esm/components/db-email-verify.js +1 -1
  58. package/dist/esm/components/db-file-uploader.js +1 -1
  59. package/dist/esm/components/db-floating-action-button.d.ts +1 -0
  60. package/dist/esm/components/db-floating-action-button.js +1 -1
  61. package/dist/esm/components/db-footer.js +1 -1
  62. package/dist/esm/components/db-gantt.js +1 -1
  63. package/dist/esm/components/db-indicator.js +1 -1
  64. package/dist/esm/components/db-input.d.ts +7 -0
  65. package/dist/esm/components/db-input.js +1 -1
  66. package/dist/esm/components/db-kanban.js +1 -1
  67. package/dist/esm/components/db-lightbox.d.ts +4 -0
  68. package/dist/esm/components/db-lightbox.js +1 -1
  69. package/dist/esm/components/db-list.js +1 -1
  70. package/dist/esm/components/db-masonry.js +1 -1
  71. package/dist/esm/components/db-menu-item.js +1 -1
  72. package/dist/esm/components/db-modal.d.ts +10 -0
  73. package/dist/esm/components/db-modal.js +1 -1
  74. package/dist/esm/components/db-navbar.d.ts +4 -2
  75. package/dist/esm/components/db-navbar.js +1 -1
  76. package/dist/esm/components/db-onboarding-modal.d.ts +3 -0
  77. package/dist/esm/components/db-onboarding-modal.js +1 -1
  78. package/dist/esm/components/db-otp-input.d.ts +3 -2
  79. package/dist/esm/components/db-otp-input.js +1 -1
  80. package/dist/esm/components/db-page-header.js +1 -1
  81. package/dist/esm/components/db-phone-verify.d.ts +2 -2
  82. package/dist/esm/components/db-phone-verify.js +1 -1
  83. package/dist/esm/components/db-popover.js +1 -1
  84. package/dist/esm/components/db-progress-step.js +1 -1
  85. package/dist/esm/components/db-progress.js +1 -1
  86. package/dist/esm/components/db-progressbar.js +1 -1
  87. package/dist/esm/components/db-radio.d.ts +1 -0
  88. package/dist/esm/components/db-radio.js +1 -1
  89. package/dist/esm/components/db-range-slider.d.ts +9 -4
  90. package/dist/esm/components/db-range-slider.js +1 -1
  91. package/dist/esm/components/db-rating.js +1 -1
  92. package/dist/esm/components/db-resizable-panels.d.ts +14 -0
  93. package/dist/esm/components/db-resizable-panels.js +1 -1
  94. package/dist/esm/components/db-search-bar.js +1 -1
  95. package/dist/esm/components/db-section-cta.js +1 -1
  96. package/dist/esm/components/db-section-feature.js +1 -1
  97. package/dist/esm/components/db-section-pricing.js +1 -1
  98. package/dist/esm/components/db-section.js +1 -1
  99. package/dist/esm/components/db-segment-control.js +1 -1
  100. package/dist/esm/components/db-select.d.ts +8 -0
  101. package/dist/esm/components/db-select.js +1 -1
  102. package/dist/esm/components/db-sidebar.d.ts +41 -6
  103. package/dist/esm/components/db-sidebar.js +1 -1
  104. package/dist/esm/components/db-skeleton.js +1 -1
  105. package/dist/esm/components/db-spinner.d.ts +4 -0
  106. package/dist/esm/components/db-spinner.js +1 -1
  107. package/dist/esm/components/db-split-view.js +1 -1
  108. package/dist/esm/components/db-stat.js +1 -1
  109. package/dist/esm/components/db-stepper.js +1 -1
  110. package/dist/esm/components/db-table.js +1 -1
  111. package/dist/esm/components/db-tabs.d.ts +1 -1
  112. package/dist/esm/components/db-tabs.js +1 -1
  113. package/dist/esm/components/db-testimonial.js +1 -1
  114. package/dist/esm/components/db-textarea.js +1 -1
  115. package/dist/esm/components/db-time-picker.d.ts +5 -2
  116. package/dist/esm/components/db-time-picker.js +1 -1
  117. package/dist/esm/components/db-timeline.js +1 -1
  118. package/dist/esm/components/db-toast.d.ts +8 -1
  119. package/dist/esm/components/db-toast.js +1 -1
  120. package/dist/esm/components/db-toggle.d.ts +2 -0
  121. package/dist/esm/components/db-toggle.js +1 -1
  122. package/dist/esm/components/db-tooltip.js +1 -1
  123. package/dist/esm/components/db-top-banner.js +1 -1
  124. package/dist/esm/components/db-tutorial.d.ts +1 -0
  125. package/dist/esm/components/db-tutorial.js +1 -1
  126. package/dist/esm/components/db-two-factor.d.ts +2 -2
  127. package/dist/esm/components/db-two-factor.js +1 -1
  128. package/dist/esm/components/db-video-player.d.ts +3 -0
  129. package/dist/esm/components/db-video-player.js +1 -1
  130. package/dist/esm/components/section-block-header-utils.js +1 -1
  131. package/dist/esm/core/a11y.d.ts +40 -0
  132. package/dist/esm/core/a11y.js +1 -0
  133. package/dist/esm/core/base-element.d.ts +41 -0
  134. package/dist/esm/core/base-element.js +1 -0
  135. package/dist/esm/core/dom.d.ts +35 -0
  136. package/dist/esm/core/dom.js +1 -0
  137. package/dist/esm/core/focus-trap.d.ts +41 -0
  138. package/dist/esm/core/focus-trap.js +1 -0
  139. package/dist/esm/core/i18n.d.ts +82 -0
  140. package/dist/esm/core/i18n.js +1 -0
  141. package/dist/esm/core/scroll-lock.d.ts +19 -0
  142. package/dist/esm/core/scroll-lock.js +1 -0
  143. package/dist/esm/core/uid.d.ts +23 -0
  144. package/dist/esm/core/uid.js +1 -0
  145. package/dist/esm/helpers/toast.d.ts +10 -10
  146. package/dist/esm/helpers/toast.js +1 -1
  147. package/dist/esm/index.d.ts +12 -4
  148. package/dist/esm/index.js +1 -1
  149. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -0
  150. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/primitives.js +1 -0
  151. package/dist/index.cjs +1 -1
  152. package/dist/index.css +1 -1
  153. package/dist/index.d.ts +587 -82
  154. package/dist/index.esm.js +1 -1
  155. package/dist/react/index.cjs +1 -1
  156. package/dist/react/index.d.ts +470 -122
  157. package/dist/react/index.esm.js +1 -1
  158. package/package.json +37 -10
  159. package/dist/chunks/lottie-26a5e98f.js +0 -1
  160. package/dist/esm/components/db-lottie.d.ts +0 -20
  161. package/dist/esm/components/db-lottie.js +0 -1
  162. package/dist/react/chunks/lottie-14e7addb.js +0 -1
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";class DbMenuItem extends HTMLElement{static get observedAttributes(){return["label","href","icon","active","disabled","badge","badge-color","size","variant","type","menu-style","expanded","expandable","sub-items","depth"]}get subItems(){try{return JSON.parse(this.getAttribute("sub-items")||"[]")}catch{return[]}}set subItems(e){this.setAttribute("sub-items","string"==typeof e?e:JSON.stringify(e))}get expanded(){return this.hasAttribute("expanded")}set expanded(e){this.toggleAttribute("expanded",e)}connectedCallback(){this.render()}iconSize(e){return"s"===e?16:"l"===e?24:16}render(){const t=this.getAttribute("label")||"",i=this.getAttribute("href")||"",n=this.getAttribute("icon"),s=this.getAttribute("size")||"m",a=this.getAttribute("variant")||"default",d=this.getAttribute("type")||"block",c=this.getAttribute("menu-style")||"accordion",r=Number(this.getAttribute("depth")||0),b=this.hasAttribute("active"),u=this.hasAttribute("disabled"),m=this.getAttribute("badge")||"",o=this.getAttribute("badge-color")||"primary",l=this.subItems,h=l.length>0,g=this.hasAttribute("expandable")||h,p=this.expanded,A=this.iconSize(s),w="accordion"===c&&h;this.className=["designbase-wc-menu-item",`designbase-wc-menu-item--${d}`,`designbase-wc-menu-item--${s}`,`designbase-wc-menu-item--${a}`,`designbase-wc-menu-item--${c}`,`designbase-wc-menu-item--depth-${r}`,b&&"designbase-wc-menu-item--active",u&&"designbase-wc-menu-item--disabled",g&&"designbase-wc-menu-item--expandable",p&&"designbase-wc-menu-item--expanded",h&&"designbase-wc-menu-item--with-children",m&&"designbase-wc-menu-item--with-badge",n&&"designbase-wc-menu-item--with-icon"].filter(Boolean).join(" "),this.replaceChildren();const v=document.createElement("div");if(v.className=["designbase-wc-menu-item__content","designbase-wc-menu-item__content--clickable"].join(" "),n){const t=document.createElement("div");t.className=["designbase-wc-menu-item__icon",`designbase-wc-menu-item__icon--${a}`,b&&"designbase-wc-menu-item__icon--active",u&&"designbase-wc-menu-item__icon--disabled"].filter(Boolean).join(" "),t.append(e(n,A)),v.append(t)}const x=document.createElement("span");if(x.className="designbase-wc-menu-item__label",x.textContent=t,v.append(x),m){const e=document.createElement("db-badge");e.setAttribute("size","s"),e.setAttribute("variant",o),e.setAttribute("badge-style","number"),e.setAttribute("count",m),v.append(e)}if(h){const t=document.createElement("div");t.className="designbase-wc-menu-item__expand-icon",t.append(e(p?"chevron-up":"chevron-down",16)),v.append(t)}if(v.addEventListener("click",e=>{u||(h&&g?(e.preventDefault(),this.expanded=!this.expanded):i&&(window.location.href=i),this.dispatchEvent(new CustomEvent("db-click",{detail:{label:t,href:i,expanded:this.expanded},bubbles:!0,composed:!0})))}),this.append(v),h&&(p||w)){const e=document.createElement("div");e.className=`designbase-wc-menu-item__children designbase-wc-menu-item__children--${c}`,w&&e.setAttribute("aria-hidden",p?"false":"true"),l.forEach(t=>{const i=document.createElement("db-menu-item");i.setAttribute("label",t.label),i.setAttribute("type","block"),i.setAttribute("menu-style",c),i.setAttribute("size",s),i.setAttribute("depth",String(r+1)),t.href&&i.setAttribute("href",t.href),t.icon&&i.setAttribute("icon",t.icon),t.active&&i.setAttribute("active",""),t.disabled&&i.setAttribute("disabled",""),void 0!==t.badge&&i.setAttribute("badge",String(t.badge)),t.badgeColor&&i.setAttribute("badge-color",t.badgeColor),t.variant&&i.setAttribute("variant",t.variant),i.addEventListener("db-click",e=>{e.stopPropagation(),t.disabled||this.dispatchEvent(new CustomEvent("db-child-click",{detail:{child:t},bubbles:!0,composed:!0}))}),e.append(i)}),this.append(e)}}attributeChangedCallback(e){this.isConnected&&("expanded"!==e||"accordion"!==this.getAttribute("menu-style")?this.render():this.syncExpandedState())}syncExpandedState(){const t=this.expanded;this.classList.toggle("designbase-wc-menu-item--expanded",t);const i=this.querySelector(".designbase-wc-menu-item__expand-icon");i&&i.replaceChildren(e(t?"chevron-up":"chevron-down",16));const n=this.querySelector(".designbase-wc-menu-item__children--accordion");n?n.setAttribute("aria-hidden",t?"false":"true"):t&&this.subItems.length&&this.render()}}customElements.get("db-menu-item")||customElements.define("db-menu-item",DbMenuItem);export{DbMenuItem};
1
+ import{createDbIcon as e}from"./db-icons.js";class DbMenuItem extends HTMLElement{static get observedAttributes(){return["label","href","icon","active","disabled","badge","badge-color","size","variant","type","menu-style","expanded","expandable","sub-items","depth"]}get subItems(){try{return JSON.parse(this.getAttribute("sub-items")||"[]")}catch{return[]}}set subItems(e){this.setAttribute("sub-items","string"==typeof e?e:JSON.stringify(e))}get expanded(){return this.hasAttribute("expanded")}set expanded(e){this.toggleAttribute("expanded",e)}connectedCallback(){this.render()}iconSize(e){return"s"===e?16:"l"===e?24:16}render(){const t=this.getAttribute("label")||"",i=this.getAttribute("href")||"",n=this.getAttribute("icon"),s=this.getAttribute("size")||"m",a=this.getAttribute("variant")||"default",d=this.getAttribute("type")||"block",c=this.getAttribute("menu-style")||"accordion",r=Number(this.getAttribute("depth")||0),b=this.hasAttribute("active"),u=this.hasAttribute("disabled"),m=this.getAttribute("badge")||"",o=this.getAttribute("badge-color")||"primary",l=this.subItems,h=l.length>0,g=this.hasAttribute("expandable")||h,p=this.expanded,A=this.iconSize(s),w="accordion"===c&&h;this.className=["designbase-wc-menu-item",`designbase-wc-menu-item--${d}`,`designbase-wc-menu-item--${s}`,`designbase-wc-menu-item--${a}`,`designbase-wc-menu-item--${c}`,`designbase-wc-menu-item--depth-${r}`,b&&"designbase-wc-menu-item--active",u&&"designbase-wc-menu-item--disabled",g&&"designbase-wc-menu-item--expandable",p&&"designbase-wc-menu-item--expanded",h&&"designbase-wc-menu-item--with-children",m&&"designbase-wc-menu-item--with-badge",n&&"designbase-wc-menu-item--with-icon"].filter(Boolean).join(" "),this.replaceChildren();const v=document.createElement("div");if(v.className=["designbase-wc-menu-item__content","designbase-wc-menu-item__content--clickable"].join(" "),n){const t=document.createElement("div");t.className=["designbase-wc-menu-item__icon",`designbase-wc-menu-item__icon--${a}`,b&&"designbase-wc-menu-item__icon--active",u&&"designbase-wc-menu-item__icon--disabled"].filter(Boolean).join(" "),t.append(e(n,A)),v.append(t)}const x=document.createElement("span");if(x.className="designbase-wc-menu-item__label",x.textContent=t,v.append(x),m){const e=document.createElement("db-badge");e.setAttribute("size","s"),e.setAttribute("variant",o),e.setAttribute("type","number"),e.setAttribute("count",m),v.append(e)}if(h){const t=document.createElement("div");t.className="designbase-wc-menu-item__expand-icon",t.append(e(p?"chevron-up":"chevron-down",16)),v.append(t)}if(v.addEventListener("click",e=>{u||(h&&g?(e.preventDefault(),this.expanded=!this.expanded):i&&(window.location.href=i),this.dispatchEvent(new CustomEvent("db-click",{detail:{label:t,href:i,expanded:this.expanded},bubbles:!0,composed:!0})))}),this.append(v),h&&(p||w)){const e=document.createElement("div");e.className=`designbase-wc-menu-item__children designbase-wc-menu-item__children--${c}`,w&&e.setAttribute("aria-hidden",p?"false":"true"),l.forEach(t=>{const i=document.createElement("db-menu-item");i.setAttribute("label",t.label),i.setAttribute("type","block"),i.setAttribute("menu-style",c),i.setAttribute("size",s),i.setAttribute("depth",String(r+1)),t.href&&i.setAttribute("href",t.href),t.icon&&i.setAttribute("icon",t.icon),t.active&&i.setAttribute("active",""),t.disabled&&i.setAttribute("disabled",""),void 0!==t.badge&&i.setAttribute("badge",String(t.badge)),t.badgeColor&&i.setAttribute("badge-color",t.badgeColor),t.variant&&i.setAttribute("variant",t.variant),i.addEventListener("db-click",e=>{e.stopPropagation(),t.disabled||this.dispatchEvent(new CustomEvent("db-child-click",{detail:{child:t},bubbles:!0,composed:!0}))}),e.append(i)}),this.append(e)}}attributeChangedCallback(e){this.isConnected&&("expanded"!==e||"accordion"!==this.getAttribute("menu-style")?this.render():this.syncExpandedState())}syncExpandedState(){const t=this.expanded;this.classList.toggle("designbase-wc-menu-item--expanded",t);const i=this.querySelector(".designbase-wc-menu-item__expand-icon");i&&i.replaceChildren(e(t?"chevron-up":"chevron-down",16));const n=this.querySelector(".designbase-wc-menu-item__children--accordion");n?n.setAttribute("aria-hidden",t?"false":"true"):t&&this.subItems.length&&this.render()}}customElements.get("db-menu-item")||customElements.define("db-menu-item",DbMenuItem);export{DbMenuItem};
@@ -11,6 +11,7 @@ declare class DbModal extends HTMLElement {
11
11
  private segmentEl?;
12
12
  private contentEl?;
13
13
  private titleId;
14
+ private focusTrap?;
14
15
  private isMounted;
15
16
  private internalTabId;
16
17
  private internalSegment;
@@ -50,7 +51,16 @@ declare class DbModal extends HTMLElement {
50
51
  private exitTimerId;
51
52
  private syncVisibility;
52
53
  private syncOpenState;
54
+ /** 열릴 때 포커스를 패널 안으로 가둔다. 닫으면 직전 포커스 요소로 복원된다. */
55
+ private activateFocusTrap;
53
56
  private teardown;
57
+ /** 소비자가 `role="alertdialog"` 를 지정하지 않으면 dialog */
58
+ private dialogRole;
59
+ /**
60
+ * 본문 설명을 대화상자에 연결한다.
61
+ * `describedby` 로 id 를 직접 주거나, 없으면 본문 컨테이너를 자동으로 가리킨다.
62
+ */
63
+ private syncDescribedBy;
54
64
  private close;
55
65
  private handleDocumentKeyDown;
56
66
  }
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e=["s","m","l","xl","full"],s=["default","tabs","segment"],i=["s","m","l"];class DbModal extends HTMLElement{constructor(){super(...arguments),this.titleId=`db-modal-title-${Math.random().toString(36).slice(2,9)}`,this.isMounted=!1,this.internalTabId="",this.internalSegment="",this.exitTimerId=null,this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.open&&"false"!==this.getAttribute("close-on-escape")&&(t.preventDefault(),this.close())}}static get observedAttributes(){return["open","title","size","header-variant","tabs","segments","selected-tab-id","default-selected-tab-id","segment-value","default-segment-value","nav-size","segment-full-width","close-on-outside-click","close-on-escape","show-close-button"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open","true"):this.removeAttribute("open")}connectedCallback(){this.classList.add("designbase-wc-modal-host"),document.addEventListener("keydown",this.handleDocumentKeyDown),this.childObserver=new MutationObserver(()=>{this.open&&this.render()}),this.childObserver.observe(this,{childList:!0}),this.syncOpenState()}disconnectedCallback(){this.childObserver?.disconnect(),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.exitTimerId&&clearTimeout(this.exitTimerId),this.teardown()}attributeChangedCallback(t){if(this.isConnected)if("open"!==t){if("selected-tab-id"===t||"segment-value"===t){const t=this.getClassifiedChildren();return this.renderBodyContent(t.body),void this.renderHeader(t.header)}this.render(),this.isMounted&&this.syncVisibility()}else this.syncOpenState()}resolvedSize(){return e.includes(this.size)?this.size:"m"}get size(){return this.getAttribute("size")||"m"}set size(t){t?this.setAttribute("size",t):this.removeAttribute("size")}resolvedHeaderVariant(){const t=this.getAttribute("header-variant")||"default";return s.includes(t)?t:"default"}parsedTabs(){const t=this.getAttribute("tabs");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}parsedSegments(){const t=this.getAttribute("segments");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}usesIntegratedNav(){const t=this.resolvedHeaderVariant();return"tabs"===t&&this.parsedTabs().length>0||"segment"===t&&this.parsedSegments().length>0}closeIconSize(){const t=this.resolvedSize();return"s"===t?16:"l"===t?20:"xl"===t?24:18}activeTabId(){return this.getAttribute("selected-tab-id")||this.internalTabId||this.getAttribute("default-selected-tab-id")||this.parsedTabs()[0]?.id||""}activeSegmentValue(){return this.getAttribute("segment-value")||this.internalSegment||this.getAttribute("default-segment-value")||this.parsedSegments()[0]?.value||""}collectUserChildren(){return Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal"))}classifyChildren(t){const isPart=(t,e,s)=>t.classList.contains(s)||t.getAttribute("data-modal-part")===e,e=t.filter(t=>isPart(t,"header","designbase-wc-modal__header")),s=t.filter(t=>isPart(t,"footer","designbase-wc-modal__footer")||"footer"===t.getAttribute("slot")),i=t.filter(t=>isPart(t,"body","designbase-wc-modal__body")),n=t.filter(t=>!e.includes(t)&&!s.includes(t)&&!i.includes(t));return{header:e,body:[...i,...n],footer:s}}getClassifiedChildren(){const t=this.classifyChildren(this.collectUserChildren());if(t.header.length||t.body.length||t.footer.length)return t;return{header:Array.from(this.headerEl?.children||[]).filter(t=>t!==this.closeButton&&!t.classList.contains("designbase-wc-modal__header-row")&&("header"===t.getAttribute("data-modal-part")||t.classList.contains("designbase-wc-modal__header"))),body:this.collectContentParts("body"),footer:this.collectContentParts("footer")}}isBodyPart(t){return t.classList.contains("designbase-wc-modal__body")||"body"===t.getAttribute("data-modal-part")}isFooterPart(t){return t.classList.contains("designbase-wc-modal__footer")||"footer"===t.getAttribute("data-modal-part")||"footer"===t.getAttribute("slot")}collectContentParts(t){if(!this.contentEl)return[];const e=Array.from(this.contentEl.children).filter(e=>"body"===t?this.isBodyPart(e):this.isFooterPart(e));return e.length>0?e:Array.from(this.children).filter(e=>"body"===t?this.isBodyPart(e):this.isFooterPart(e))}placeContentParts(t,e){this.contentEl&&e.forEach(e=>{if(e.parentElement!==this.contentEl){if("body"===t){const t=this.contentEl.querySelector(':scope > .designbase-wc-modal__footer, :scope > [data-modal-part="footer"]')||null;return void this.contentEl.insertBefore(e,t)}this.contentEl.append(e)}})}restorePartsToHost(){this.contentEl&&Array.from(this.contentEl.children).filter(t=>!t.classList.contains("designbase-wc-modal__integrated-content")&&!t.hasAttribute("data-wc-internal")).forEach(t=>{t.parentElement!==this&&this.append(t)})}bindFooterActions(){if(!this.contentEl||"true"===this.contentEl.dataset.modalActionsBound)return;this.contentEl.dataset.modalActionsBound="true";const handleClose=t=>{const e=t.target?.closest("[data-modal-close]");e&&this.contentEl?.contains(e)&&this.close()};this.contentEl.addEventListener("click",handleClose),this.contentEl.addEventListener("db-click",handleClose)}ensureStructure(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-modal__overlay",this.root.setAttribute("data-wc-internal",""),this.root.addEventListener("click",t=>{t.target===this.root&&"false"!==this.getAttribute("close-on-outside-click")&&this.close()}),this.panel=document.createElement("div"),this.panel.className="designbase-wc-modal",this.panel.setAttribute("role","dialog"),this.panel.setAttribute("aria-modal","true"),this.panel.addEventListener("click",t=>t.stopPropagation()),this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-modal__header",this.headerContentEl=document.createElement("div"),this.headerContentEl.className="designbase-wc-modal__header-content",this.titleEl=document.createElement("h2"),this.titleEl.className="designbase-wc-modal__title",this.titleEl.id=this.titleId,this.closeButton=document.createElement("button"),this.closeButton.type="button",this.closeButton.className="designbase-wc-modal__close-button",this.closeButton.setAttribute("aria-label","모달 닫기"),this.closeButton.addEventListener("click",()=>this.close()),this.navEl=document.createElement("div"),this.navEl.className="designbase-wc-modal__header-nav",this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-modal__content",this.panel.append(this.headerEl,this.contentEl),this.root.append(this.panel))}renderCloseButton(){if(!this.closeButton)return;const e=this.closeIconSize();this.closeButton.replaceChildren(t("close",e)),this.closeButton.hidden="false"===this.getAttribute("show-close-button")}renderDefaultHeader(t){if(!(this.headerEl&&this.headerContentEl&&this.titleEl&&this.closeButton))return;if(this.headerEl.className="designbase-wc-modal__header",this.headerEl.replaceChildren(),t.length>0)return t.forEach(t=>this.headerEl.append(t)),void("false"!==this.getAttribute("show-close-button")&&this.headerEl.append(this.closeButton));const e=this.getAttribute("title")||"";this.titleEl.textContent=e,this.titleEl.hidden=!e,this.headerContentEl.replaceChildren(),e&&this.headerContentEl.append(this.titleEl),this.renderCloseButton(),this.headerEl.append(this.headerContentEl),"false"!==this.getAttribute("show-close-button")&&this.headerEl.append(this.closeButton),this.panel&&(e?this.panel.setAttribute("aria-labelledby",this.titleId):this.panel.removeAttribute("aria-labelledby"))}renderNavHeader(){if(!(this.headerEl&&this.headerContentEl&&this.titleEl&&this.closeButton&&this.navEl))return;const t=this.resolvedHeaderVariant(),e=this.parsedTabs(),s=this.parsedSegments(),n=i.includes(this.getAttribute("nav-size")||"m")?this.getAttribute("nav-size")||"m":"s";this.headerEl.className=["designbase-wc-modal__header","tabs"===t&&"designbase-wc-modal__header--tabs","segment"===t&&"designbase-wc-modal__header--segment"].filter(Boolean).join(" ");const a=this.getAttribute("title")||"";this.titleEl.textContent=a,this.titleEl.hidden=!a,this.headerContentEl.replaceChildren(),a&&this.headerContentEl.append(this.titleEl),this.renderCloseButton();const r=document.createElement("div");if(r.className="designbase-wc-modal__header-row",r.append(this.headerContentEl),"false"!==this.getAttribute("show-close-button")&&r.append(this.closeButton),this.headerEl.replaceChildren(r),this.navEl.replaceChildren(),"tabs"===t&&e.length>0){const t=document.createElement("db-tabs");t.setAttribute("size",n),t.setAttribute("items",JSON.stringify(e.map(t=>({id:t.id,label:t.label,disabled:t.disabled})))),t.setAttribute("selected-id",this.activeTabId()),t.addEventListener("db-change",t=>{const e=t.detail?.id;e&&(this.hasAttribute("selected-tab-id")||(this.internalTabId=e),this.dispatchEvent(new CustomEvent("db-tab-change",{detail:{tabId:e},bubbles:!0,composed:!0})),this.renderBodyContent(this.getClassifiedChildren().body))}),this.tabsEl=t,this.navEl.append(t),this.headerEl.append(this.navEl)}if("segment"===t&&s.length>0){const t=document.createElement("db-segment-control");t.setAttribute("size",n),t.setAttribute("options",JSON.stringify(s.map(t=>({value:t.value,label:t.label,disabled:t.disabled})))),t.setAttribute("value",this.activeSegmentValue()),"false"!==this.getAttribute("segment-full-width")&&t.setAttribute("full-width",""),t.addEventListener("db-change",t=>{const e=t.detail?.value;e&&(this.hasAttribute("segment-value")||(this.internalSegment=e),this.dispatchEvent(new CustomEvent("db-segment-change",{detail:{value:e},bubbles:!0,composed:!0})),this.renderBodyContent(this.getClassifiedChildren().body))}),this.segmentEl=t,this.navEl.append(t),this.headerEl.append(this.navEl)}this.panel&&(a?this.panel.setAttribute("aria-labelledby",this.titleId):this.panel.removeAttribute("aria-labelledby"))}renderHeader(t){if(!this.headerEl)return;if(t.length>0)return this.headerEl.hidden=!1,void this.renderDefaultHeader(t);if(this.usesIntegratedNav())return this.headerEl.hidden=!1,void this.renderNavHeader();this.getAttribute("title")||""?(this.headerEl.hidden=!1,this.renderDefaultHeader([])):this.headerEl.hidden=!0}renderBodyContent(t=[]){if(!this.contentEl)return;let e=this.contentEl.querySelector(":scope > .designbase-wc-modal__integrated-content"),s="";if(this.usesIntegratedNav()){const t=this.resolvedHeaderVariant();if("tabs"===t){const t=this.parsedTabs().find(t=>t.id===this.activeTabId());s=t?.content||""}if("segment"===t){const t=this.parsedSegments().find(t=>t.value===this.activeSegmentValue());s=t?.content||""}}s?(e||(e=document.createElement("div"),e.className="designbase-wc-modal__integrated-content designbase-wc-modal__body",this.contentEl.insertBefore(e,this.contentEl.firstChild)),e.textContent=s):e?.remove();const i=t.filter(t=>this.isBodyPart(t)),n=t.filter(t=>!this.isBodyPart(t)&&!this.isFooterPart(t));this.placeContentParts("body",i.length>0?i:n)}renderFooter(t){if(!this.contentEl)return;const e=t.filter(t=>this.isFooterPart(t)),s=t.filter(t=>!this.isFooterPart(t)&&!this.isBodyPart(t)),i=e.length>0?e:s;this.placeContentParts("footer",i),i.forEach(t=>{t.hidden=!1}),this.bindFooterActions()}render(){this.ensureStructure();const{header:t,body:s,footer:i}=this.getClassifiedChildren();e.forEach(t=>this.panel?.classList.remove(`designbase-wc-modal--${t}`)),this.panel?.classList.add(`designbase-wc-modal--${this.resolvedSize()}`),this.renderHeader(t),this.renderBodyContent(s),this.renderFooter(i)}syncVisibility(){if(this.root&&this.panel){if(this.open)return this.root.setAttribute("data-state","entering"),this.panel.setAttribute("data-state","entering"),void requestAnimationFrame(()=>{this.panel,requestAnimationFrame(()=>{this.open&&this.root&&this.panel&&(this.root.setAttribute("data-state","entered"),this.panel.setAttribute("data-state","entered"))})});this.root.setAttribute("data-state","exiting"),this.panel.setAttribute("data-state","exiting")}}syncOpenState(){if(this.open)return this.render(),this.root&&!this.root.isConnected&&document.body.append(this.root),document.body.style.overflow="hidden",this.isMounted=!0,void this.syncVisibility();this.isMounted&&(this.syncVisibility(),document.body.style.overflow="",this.exitTimerId&&clearTimeout(this.exitTimerId),this.exitTimerId=window.setTimeout(()=>{this.open||this.teardown()},200))}teardown(){this.restorePartsToHost(),this.root?.remove(),this.isMounted=!1,document.body.style.overflow=""}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}}customElements.get("db-modal")||customElements.define("db-modal",DbModal);export{DbModal};
1
+ import{createDbIcon as t}from"./db-icons.js";import{dbUid as e}from"../core/uid.js";import{createFocusTrap as s}from"../core/focus-trap.js";import{lockScroll as i,unlockScroll as n}from"../core/scroll-lock.js";import{labelFrom as a}from"../core/i18n.js";import{MODAL_SIZES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as o}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";const l=["default","tabs","segment"],d=["s","m","l"];class DbModal extends HTMLElement{constructor(){super(...arguments),this.titleId=e("db-modal-title"),this.isMounted=!1,this.internalTabId="",this.internalSegment="",this.exitTimerId=null,this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.open&&"false"!==this.getAttribute("close-on-escape")&&(t.preventDefault(),this.close())}}static get observedAttributes(){return["open","title","size","header-variant","tabs","segments","selected-tab-id","default-selected-tab-id","segment-value","default-segment-value","nav-size","segment-full-width","close-on-outside-click","close-on-escape","show-close-button","role","describedby","label-close"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open","true"):this.removeAttribute("open")}connectedCallback(){this.classList.add("designbase-wc-modal-host"),document.addEventListener("keydown",this.handleDocumentKeyDown),this.childObserver=new MutationObserver(()=>{this.open&&this.render()}),this.childObserver.observe(this,{childList:!0}),this.syncOpenState()}disconnectedCallback(){this.childObserver?.disconnect(),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.exitTimerId&&clearTimeout(this.exitTimerId),this.teardown()}attributeChangedCallback(t){if(this.isConnected)if("open"!==t){if("selected-tab-id"===t||"segment-value"===t){const t=this.getClassifiedChildren();return this.renderBodyContent(t.body),void this.renderHeader(t.header)}this.render(),this.isMounted&&this.syncVisibility()}else this.syncOpenState()}resolvedSize(){return r.includes(this.size)?this.size:"m"}get size(){return o(this.getAttribute("size"),r,"m")}set size(t){t?this.setAttribute("size",t):this.removeAttribute("size")}resolvedHeaderVariant(){const t=this.getAttribute("header-variant")||"default";return l.includes(t)?t:"default"}parsedTabs(){const t=this.getAttribute("tabs");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}parsedSegments(){const t=this.getAttribute("segments");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}usesIntegratedNav(){const t=this.resolvedHeaderVariant();return"tabs"===t&&this.parsedTabs().length>0||"segment"===t&&this.parsedSegments().length>0}closeIconSize(){const t=this.resolvedSize();return"s"===t?16:"l"===t?20:"xl"===t?24:18}activeTabId(){return this.getAttribute("selected-tab-id")||this.internalTabId||this.getAttribute("default-selected-tab-id")||this.parsedTabs()[0]?.id||""}activeSegmentValue(){return this.getAttribute("segment-value")||this.internalSegment||this.getAttribute("default-segment-value")||this.parsedSegments()[0]?.value||""}collectUserChildren(){return Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal"))}classifyChildren(t){const isPart=(t,e,s)=>t.classList.contains(s)||t.getAttribute("data-modal-part")===e,e=t.filter(t=>isPart(t,"header","designbase-wc-modal__header")),s=t.filter(t=>isPart(t,"footer","designbase-wc-modal__footer")||"footer"===t.getAttribute("slot")),i=t.filter(t=>isPart(t,"body","designbase-wc-modal__body")),n=t.filter(t=>!e.includes(t)&&!s.includes(t)&&!i.includes(t));return{header:e,body:[...i,...n],footer:s}}getClassifiedChildren(){const t=this.classifyChildren(this.collectUserChildren());if(t.header.length||t.body.length||t.footer.length)return t;return{header:Array.from(this.headerEl?.children||[]).filter(t=>t!==this.closeButton&&!t.classList.contains("designbase-wc-modal__header-row")&&("header"===t.getAttribute("data-modal-part")||t.classList.contains("designbase-wc-modal__header"))),body:this.collectContentParts("body"),footer:this.collectContentParts("footer")}}isBodyPart(t){return t.classList.contains("designbase-wc-modal__body")||"body"===t.getAttribute("data-modal-part")}isFooterPart(t){return t.classList.contains("designbase-wc-modal__footer")||"footer"===t.getAttribute("data-modal-part")||"footer"===t.getAttribute("slot")}collectContentParts(t){if(!this.contentEl)return[];const e=Array.from(this.contentEl.children).filter(e=>"body"===t?this.isBodyPart(e):this.isFooterPart(e));return e.length>0?e:Array.from(this.children).filter(e=>"body"===t?this.isBodyPart(e):this.isFooterPart(e))}placeContentParts(t,e){const s=this.contentEl;s&&e.forEach(e=>{if(e.parentElement!==s){if("body"===t){const t=s.querySelector(':scope > .designbase-wc-modal__footer, :scope > [data-modal-part="footer"]')||null;return void s.insertBefore(e,t)}s.append(e)}})}restorePartsToHost(){this.contentEl&&Array.from(this.contentEl.children).filter(t=>!t.classList.contains("designbase-wc-modal__integrated-content")&&!t.hasAttribute("data-wc-internal")).forEach(t=>{t.parentElement!==this&&this.append(t)})}bindFooterActions(){if(!this.contentEl||"true"===this.contentEl.dataset.modalActionsBound)return;this.contentEl.dataset.modalActionsBound="true";const handleClose=t=>{const e=t.target?.closest("[data-modal-close]");e&&this.contentEl?.contains(e)&&this.close()};this.contentEl.addEventListener("click",handleClose),this.contentEl.addEventListener("db-click",handleClose)}ensureStructure(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-modal__overlay",this.root.setAttribute("data-wc-internal",""),this.root.addEventListener("click",t=>{t.target===this.root&&"false"!==this.getAttribute("close-on-outside-click")&&this.close()}),this.panel=document.createElement("div"),this.panel.className="designbase-wc-modal",this.panel.setAttribute("role",this.dialogRole()),this.panel.setAttribute("aria-modal","true"),this.panel.addEventListener("click",t=>t.stopPropagation()),this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-modal__header",this.headerContentEl=document.createElement("div"),this.headerContentEl.className="designbase-wc-modal__header-content",this.titleEl=document.createElement("h2"),this.titleEl.className="designbase-wc-modal__title",this.titleEl.id=this.titleId,this.closeButton=document.createElement("button"),this.closeButton.type="button",this.closeButton.className="designbase-wc-modal__close-button",this.closeButton.setAttribute("aria-label",a(this,"label-close","modal.close")),this.closeButton.addEventListener("click",()=>this.close()),this.navEl=document.createElement("div"),this.navEl.className="designbase-wc-modal__header-nav",this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-modal__content",this.panel.append(this.headerEl,this.contentEl),this.root.append(this.panel))}renderCloseButton(){if(!this.closeButton)return;const e=this.closeIconSize(),s=t("close",e);s.setAttribute("aria-hidden","true"),this.closeButton.replaceChildren(s),this.closeButton.setAttribute("aria-label",a(this,"label-close","modal.close")),this.closeButton.hidden="false"===this.getAttribute("show-close-button")}renderDefaultHeader(t){if(!(this.headerEl&&this.headerContentEl&&this.titleEl&&this.closeButton))return;if(this.headerEl.className="designbase-wc-modal__header",this.headerEl.replaceChildren(),t.length>0)return t.forEach(t=>this.headerEl.append(t)),void("false"!==this.getAttribute("show-close-button")&&this.headerEl.append(this.closeButton));const e=this.getAttribute("title")||"";this.titleEl.textContent=e,this.titleEl.hidden=!e,this.headerContentEl.replaceChildren(),e&&this.headerContentEl.append(this.titleEl),this.renderCloseButton(),this.headerEl.append(this.headerContentEl),"false"!==this.getAttribute("show-close-button")&&this.headerEl.append(this.closeButton),this.panel&&(e?this.panel.setAttribute("aria-labelledby",this.titleId):this.panel.removeAttribute("aria-labelledby"),this.panel.setAttribute("role",this.dialogRole()),this.syncDescribedBy())}renderNavHeader(){if(!(this.headerEl&&this.headerContentEl&&this.titleEl&&this.closeButton&&this.navEl))return;const t=this.resolvedHeaderVariant(),e=this.parsedTabs(),s=this.parsedSegments(),i=d.includes(this.getAttribute("nav-size")||"m")?this.getAttribute("nav-size")||"m":"s";this.headerEl.className=["designbase-wc-modal__header","tabs"===t&&"designbase-wc-modal__header--tabs","segment"===t&&"designbase-wc-modal__header--segment"].filter(Boolean).join(" ");const n=this.getAttribute("title")||"";this.titleEl.textContent=n,this.titleEl.hidden=!n,this.headerContentEl.replaceChildren(),n&&this.headerContentEl.append(this.titleEl),this.renderCloseButton();const a=document.createElement("div");if(a.className="designbase-wc-modal__header-row",a.append(this.headerContentEl),"false"!==this.getAttribute("show-close-button")&&a.append(this.closeButton),this.headerEl.replaceChildren(a),this.navEl.replaceChildren(),"tabs"===t&&e.length>0){const t=document.createElement("db-tabs");t.setAttribute("size",i),t.setAttribute("items",JSON.stringify(e.map(t=>({id:t.id,label:t.label,disabled:t.disabled})))),t.setAttribute("selected-id",this.activeTabId()),t.addEventListener("db-change",t=>{const e=t.detail?.id;e&&(this.hasAttribute("selected-tab-id")||(this.internalTabId=e),this.dispatchEvent(new CustomEvent("db-tab-change",{detail:{tabId:e},bubbles:!0,composed:!0})),this.renderBodyContent(this.getClassifiedChildren().body))}),this.tabsEl=t,this.navEl.append(t),this.headerEl.append(this.navEl)}if("segment"===t&&s.length>0){const t=document.createElement("db-segment-control");t.setAttribute("size",i),t.setAttribute("options",JSON.stringify(s.map(t=>({value:t.value,label:t.label,disabled:t.disabled})))),t.setAttribute("value",this.activeSegmentValue()),"false"!==this.getAttribute("segment-full-width")&&t.setAttribute("full-width",""),t.addEventListener("db-change",t=>{const e=t.detail?.value;e&&(this.hasAttribute("segment-value")||(this.internalSegment=e),this.dispatchEvent(new CustomEvent("db-segment-change",{detail:{value:e},bubbles:!0,composed:!0})),this.renderBodyContent(this.getClassifiedChildren().body))}),this.segmentEl=t,this.navEl.append(t),this.headerEl.append(this.navEl)}this.panel&&(n?this.panel.setAttribute("aria-labelledby",this.titleId):this.panel.removeAttribute("aria-labelledby"))}renderHeader(t){if(!this.headerEl)return;if(t.length>0)return this.headerEl.hidden=!1,void this.renderDefaultHeader(t);if(this.usesIntegratedNav())return this.headerEl.hidden=!1,void this.renderNavHeader();this.getAttribute("title")||""?(this.headerEl.hidden=!1,this.renderDefaultHeader([])):this.headerEl.hidden=!0}renderBodyContent(t=[]){if(!this.contentEl)return;let e=this.contentEl.querySelector(":scope > .designbase-wc-modal__integrated-content"),s="";if(this.usesIntegratedNav()){const t=this.resolvedHeaderVariant();if("tabs"===t){const t=this.parsedTabs().find(t=>t.id===this.activeTabId());s=t?.content||""}if("segment"===t){const t=this.parsedSegments().find(t=>t.value===this.activeSegmentValue());s=t?.content||""}}s?(e||(e=document.createElement("div"),e.className="designbase-wc-modal__integrated-content designbase-wc-modal__body",this.contentEl.insertBefore(e,this.contentEl.firstChild)),e.textContent=s):e?.remove();const i=t.filter(t=>this.isBodyPart(t)),n=t.filter(t=>!this.isBodyPart(t)&&!this.isFooterPart(t));this.placeContentParts("body",i.length>0?i:n)}renderFooter(t){if(!this.contentEl)return;const e=t.filter(t=>this.isFooterPart(t)),s=t.filter(t=>!this.isFooterPart(t)&&!this.isBodyPart(t)),i=e.length>0?e:s;this.placeContentParts("footer",i),i.forEach(t=>{t instanceof HTMLElement&&(t.hidden=!1)}),this.bindFooterActions()}render(){this.ensureStructure();const{header:t,body:e,footer:s}=this.getClassifiedChildren();r.forEach(t=>this.panel?.classList.remove(`designbase-wc-modal--${t}`)),this.panel?.classList.add(`designbase-wc-modal--${this.resolvedSize()}`),this.renderHeader(t),this.renderBodyContent(e),this.renderFooter(s)}syncVisibility(){if(this.root&&this.panel){if(this.open)return this.root.setAttribute("data-state","entering"),this.panel.setAttribute("data-state","entering"),void requestAnimationFrame(()=>{this.panel,requestAnimationFrame(()=>{this.open&&this.root&&this.panel&&(this.root.setAttribute("data-state","entered"),this.panel.setAttribute("data-state","entered"))})});this.root.setAttribute("data-state","exiting"),this.panel.setAttribute("data-state","exiting")}}syncOpenState(){if(this.open)return this.render(),this.root&&!this.root.isConnected&&document.body.append(this.root),this.isMounted||i(),this.isMounted=!0,this.syncVisibility(),void this.activateFocusTrap();this.isMounted&&(this.syncVisibility(),this.focusTrap?.deactivate(),this.focusTrap=void 0,this.exitTimerId&&clearTimeout(this.exitTimerId),this.exitTimerId=window.setTimeout(()=>{this.open||this.teardown()},200))}activateFocusTrap(){this.panel&&!this.focusTrap&&(this.focusTrap=s(this.panel,{initialFocus:()=>this.panel?.querySelector("[autofocus]")||null}),this.focusTrap.activate())}teardown(){this.focusTrap?.deactivate(),this.focusTrap=void 0,this.restorePartsToHost(),this.root?.remove(),this.isMounted&&n(),this.isMounted=!1}dialogRole(){return"alertdialog"===this.getAttribute("role")?"alertdialog":"dialog"}syncDescribedBy(){if(!this.panel)return;const t=this.getAttribute("describedby");t?this.panel.setAttribute("aria-describedby",t):this.contentEl&&(this.contentEl.textContent||"").trim()?(this.contentEl.id||(this.contentEl.id=e("db-modal-desc")),this.panel.setAttribute("aria-describedby",this.contentEl.id)):this.panel.removeAttribute("aria-describedby")}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}}customElements.get("db-modal")||customElements.define("db-modal",DbModal);export{DbModal};
@@ -1,3 +1,5 @@
1
+ import { BadgeVariant, BadgeType } from '@designbasekorea/ui-contracts';
2
+
1
3
  interface DbNavbarItem {
2
4
  id: string;
3
5
  label: string;
@@ -37,8 +39,8 @@ interface DbNavbarUserProfile {
37
39
  email?: string;
38
40
  avatar?: string;
39
41
  badge?: number;
40
- badgeVariant?: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger';
41
- badgeStyle?: 'dot' | 'number' | 'text' | 'outlined';
42
+ badgeVariant?: BadgeVariant;
43
+ badgeType?: BadgeType;
42
44
  badgeText?: string;
43
45
  }
44
46
  declare class DbNavbar extends HTMLElement {
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";const t=["s","m","l"],a=["default","transparent"],n=["fixed","sticky","static"];function resolveIcon(e){if(e)return e}class DbNavbar extends HTMLElement{constructor(){super(...arguments),this.mobileOpen=!1,this.userMenuOpen=!1,this.expandedMobile={},this.outsideHandler=null}static get observedAttributes(){return["items","user-menu-items","user-profile","size","variant","position","is-authenticated","show-search","search-placeholder","full-width","shadow"]}connectedCallback(){this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems("items")}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseItems("user-menu-items")}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}parseItems(e="items"){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}iconSize(e){return"s"===e?16:"l"===e?24:20}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{this.contains(e.target)||(this.userMenuOpen=!1,this.updateUserMenuVisibility())},document.addEventListener("mousedown",this.outsideHandler))}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}dispatchItemClick(e,t){this.dispatchEvent(new CustomEvent("user"===t?"db-user-menu-item-click":"db-item-click",{bubbles:!0,composed:!0,detail:{item:e,source:t}}))}syncHostClasses(){const e=this.getAttribute("size")||"m",s=this.getAttribute("variant")||"default",i=this.getAttribute("position")||"static";this.className=["designbase-wc-navbar",`designbase-wc-navbar--${t.includes(e)?e:"m"}`,`designbase-wc-navbar--${a.includes(s)?s:"default"}`,`designbase-wc-navbar--${n.includes(i)?i:"static"}`,this.hasAttribute("full-width")&&"designbase-wc-navbar--full-width",this.hasAttribute("shadow")&&"designbase-wc-navbar--shadow",this.mobileOpen&&"designbase-wc-navbar--mobile-open"].filter(Boolean).join(" ")}isMegaMenu(e){return Boolean(e.megaMenu&&e.columns?.length)}createNavToggleButton(t,a){const n=document.createElement("button");n.type="button",n.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),n.disabled=Boolean(t.disabled);const s=resolveIcon(t.icon);s&&n.append(e(s,a)),n.append(document.createTextNode(t.label));const i=e("chevron-down",12);return i.classList.add("designbase-wc-navbar__chevron"),n.append(i),n}createMegaLink(t,a){const n=document.createElement("a");n.href=t.href||"#",n.className=["designbase-wc-navbar__mega-link",t.active&&"designbase-wc-navbar__mega-link--active",t.disabled&&"designbase-wc-navbar__mega-link--disabled"].filter(Boolean).join(" ");const s=resolveIcon(t.icon);if(s){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-link-icon",t.append(e(s,a)),n.append(t)}const i=document.createElement("span");i.className="designbase-wc-navbar__mega-link-body";const r=document.createElement("span");if(r.className="designbase-wc-navbar__mega-link-label",r.textContent=t.label,i.append(r),t.description){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-link-desc",e.textContent=t.description,i.append(e)}return n.append(i),n.addEventListener("click",e=>{e.preventDefault(),t.disabled||this.dispatchItemClick(t,"nav")}),n}createMegaMenu(e,t){const a=document.createElement("li");a.className="designbase-wc-navbar__nav-item designbase-wc-navbar__nav-item--mega";const n=this.createNavToggleButton(e,t),s=document.createElement("div");s.className="designbase-wc-navbar__mega";const i=document.createElement("div");i.className="designbase-wc-navbar__mega-inner";const r=document.createElement("div");return r.className="designbase-wc-navbar__mega-columns",r.style.setProperty("--db-navbar-mega-columns",String(e.columns.length)),e.columns.forEach(e=>{const a=document.createElement("div");if(a.className="designbase-wc-navbar__mega-column",e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-column-title",t.textContent=e.title,a.append(t)}const n=document.createElement("ul");n.className="designbase-wc-navbar__mega-list",e.items.forEach(e=>{const a=document.createElement("li");a.append(this.createMegaLink(e,t)),n.append(a)}),a.append(n),r.append(a)}),i.append(r),e.featured&&i.append(this.createMegaFeatured(e.featured,t)),s.append(i),a.append(n,s),a}createMegaFeatured(t,a){const n=document.createElement("a");n.href=t.href||"#",n.className="designbase-wc-navbar__mega-featured",t.image&&(n.style.setProperty("--db-navbar-mega-featured-image",`url("${t.image}")`),n.classList.add("designbase-wc-navbar__mega-featured--image"));const s=resolveIcon(t.icon);if(s){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-icon",t.append(e(s,a+4)),n.append(t)}if(t.title){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-title",e.textContent=t.title,n.append(e)}if(t.description){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-desc",e.textContent=t.description,n.append(e)}if(t.ctaLabel){const a=document.createElement("span");a.className="designbase-wc-navbar__mega-featured-cta",a.append(document.createTextNode(t.ctaLabel)),a.append(e("chevron-right",14)),n.append(a)}return n.addEventListener("click",e=>{e.preventDefault(),this.dispatchItemClick({id:`${t.href||"featured"}`,label:t.title||"featured",href:t.href},"nav")}),n}createDesktopNavItem(t,a){if(this.isMegaMenu(t))return this.createMegaMenu(t,a);const n=document.createElement("li");n.className="designbase-wc-navbar__nav-item";if(Boolean(t.children?.length)){const s=document.createElement("div");s.className="designbase-wc-navbar__dropdown";const i=document.createElement("button");i.type="button",i.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),i.disabled=Boolean(t.disabled);const r=resolveIcon(t.icon);r&&i.append(e(r,a)),i.append(document.createTextNode(t.label));const c=e("chevron-down",12);c.classList.add("designbase-wc-navbar__chevron"),i.append(c);const d=document.createElement("ul");return d.className="designbase-wc-navbar__dropdown-menu",t.children.forEach(t=>{const n=document.createElement("li"),s=document.createElement("a");s.href=t.href||"#",s.className=["designbase-wc-navbar__dropdown-item",t.active&&"designbase-wc-navbar__dropdown-item--active",t.disabled&&"designbase-wc-navbar__dropdown-item--disabled"].filter(Boolean).join(" ");const i=resolveIcon(t.icon);i&&s.append(e(i,a)),s.append(document.createTextNode(t.label)),s.addEventListener("click",e=>{t.disabled?e.preventDefault():(e.preventDefault(),this.dispatchItemClick(t,"nav"))}),n.append(s),d.append(n)}),s.append(i,d),n.append(s),n}const s=document.createElement("a");s.href=t.href||"#",s.className=["designbase-wc-navbar__nav-link",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" ");const i=resolveIcon(t.icon);return i&&s.append(e(i,a)),s.append(document.createTextNode(t.label)),s.addEventListener("click",e=>{t.disabled?e.preventDefault():(e.preventDefault(),this.dispatchItemClick(t,"nav"))}),n.append(s),n}createUserMenuItemElement(e,t,a){const n=document.createElement("db-menu-item");return n.setAttribute("label",e.label),n.setAttribute("type","block"),n.setAttribute("menu-style","dropdown"),n.setAttribute("size",t),e.href&&n.setAttribute("href",e.href),e.icon&&n.setAttribute("icon",e.icon),e.disabled&&n.setAttribute("disabled",""),n.addEventListener("db-click",()=>{e.disabled||(a(),this.dispatchItemClick(e,"user"))}),n}bindSearchEvents(e){e.addEventListener("db-search",e=>{const t=e.detail,a=t.query??t.value??"";this.dispatchEvent(new CustomEvent("db-search",{bubbles:!0,composed:!0,detail:{query:a,value:a}}))})}applyAvatarProfile(e,t,a){e.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),e.setAttribute("initials",t.name),e.setAttribute("alt",t.name),t.avatar&&e.setAttribute("src",t.avatar),void 0!==t.badge&&e.setAttribute("badge",String(t.badge)),t.badgeVariant&&e.setAttribute("badge-variant",t.badgeVariant),t.badgeStyle&&e.setAttribute("badge-style",t.badgeStyle),t.badgeText&&e.setAttribute("badge-text",t.badgeText)}getMobileChildren(e){if(this.isMegaMenu(e)){const t=(e.columns||[]).flatMap(e=>e.items);return e.featured?.href&&t.push({id:`${e.id}-featured`,label:e.featured.title||e.featured.ctaLabel||e.label,href:e.featured.href,icon:e.featured.icon}),t}return e.children||[]}createMobileMenuItem(e,t){const a=this.getMobileChildren(e),n=a.length>0,s=Boolean(this.expandedMobile[e.id]),i=document.createElement("db-menu-item");return i.setAttribute("label",e.label),i.setAttribute("type","block"),i.setAttribute("menu-style","accordion"),i.setAttribute("size",t),e.href&&i.setAttribute("href",e.href),e.icon&&i.setAttribute("icon",e.icon),e.active&&i.setAttribute("active",""),e.disabled&&i.setAttribute("disabled",""),n&&(i.setAttribute("expandable",""),i.subItems=a.map(e=>({id:e.id,label:e.label,href:e.href,icon:e.icon,active:e.active,disabled:e.disabled})),s&&i.setAttribute("expanded","")),i.addEventListener("db-click",()=>{if(!e.disabled){if(n)return this.expandedMobile[e.id]=!s,void this.renderMobileMenu();this.mobileOpen=!1,this.dispatchItemClick(e,"mobile"),this.render()}}),i.addEventListener("db-child-click",e=>{const t=e.detail;this.mobileOpen=!1,this.dispatchItemClick(t.child,"mobile"),this.render()}),i}updateUserMenuVisibility(){const e=this.querySelector(".designbase-wc-navbar__user-dropdown-menu");e&&(e.hidden=!this.userMenuOpen)}renderMobileMenu(){const e=this.querySelector(".designbase-wc-navbar__mobile-nav-list");if(!e)return;const t=this.getAttribute("size")||"m",a=this.parseItems();e.replaceChildren(...a.map(e=>this.createMobileMenuItem(e,t)))}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.setAttribute("aria-label","메인 네비게이션");const t=this.getAttribute("size")||"m",a=this.iconSize(t),n=this.parseItems(),s=this.parseItems("user-menu-items"),i=this.parseUserProfile(),r=this.hasAttribute("is-authenticated"),c=this.hasAttribute("show-search");this.replaceChildren();const d=document.createElement("div");d.className=["designbase-wc-navbar__container",this.hasAttribute("full-width")&&"designbase-wc-navbar__container--full-width"].filter(Boolean).join(" ");const l=document.createElement("div");l.className="designbase-wc-navbar__left";const o=document.createElement("div");o.className="designbase-wc-navbar__brand";const b=document.createElement("div");b.className="designbase-wc-navbar__logo";const u=document.createElement("db-logo");u.setAttribute("type","designbase"),u.setAttribute("size","s"),u.setAttribute("clickable",""),u.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),b.append(u),o.append(b),l.append(o);const m=document.createElement("div");m.className="designbase-wc-navbar__right";const p=document.createElement("div");p.className="designbase-wc-navbar__nav designbase-wc-navbar__nav--desktop";const h=document.createElement("ul");if(h.className="designbase-wc-navbar__nav-list",n.forEach(e=>h.append(this.createDesktopNavItem(e,a))),p.append(h),m.append(p),c){const e=document.createElement("div");e.className="designbase-wc-navbar__search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"===t?"s":"l"===t?"l":"m"),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),e.append(a),m.append(e)}const v=document.createElement("div");if(v.className="designbase-wc-navbar__user-menu",r&&i){const a=document.createElement("div");a.className="designbase-wc-navbar__user-dropdown";const n=document.createElement("button");n.type="button",n.className="designbase-wc-navbar__user-toggle",n.setAttribute("aria-expanded",String(this.userMenuOpen));const r=document.createElement("db-avatar");this.applyAvatarProfile(r,i,t);const c=document.createElement("span");c.className="designbase-wc-navbar__user-name",c.textContent=i.name,n.append(r,c,e("chevron-down",12)),n.addEventListener("click",()=>{this.userMenuOpen=!this.userMenuOpen,n.setAttribute("aria-expanded",String(this.userMenuOpen)),this.updateUserMenuVisibility()});const d=document.createElement("ul");if(d.className="designbase-wc-navbar__user-dropdown-menu",d.hidden=!this.userMenuOpen,i.email){const e=document.createElement("li");e.className="designbase-wc-navbar__user-info";const t=document.createElement("span");t.className="designbase-wc-navbar__user-email",t.textContent=i.email,e.append(t),d.append(e)}s.forEach(e=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(e,t,()=>{this.userMenuOpen=!1,this.updateUserMenuVisibility()})),d.append(a)}),a.append(n,d),v.append(a)}else{const e=document.createElement("db-button");e.setAttribute("variant","primary"),e.setAttribute("size","s"===t?"s":"l"===t?"l":"m"),e.textContent="로그인",e.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),v.append(e)}m.append(v);const g=document.createElement("button");g.type="button",g.className="designbase-wc-navbar__mobile-toggle",g.setAttribute("aria-expanded",String(this.mobileOpen)),g.setAttribute("aria-label","메뉴 열기");for(let e=0;e<3;e+=1){const e=document.createElement("span");e.className="designbase-wc-navbar__mobile-toggle-line",g.append(e)}if(g.addEventListener("click",()=>{this.mobileOpen=!this.mobileOpen,this.render()}),d.append(l,m,g),this.append(d),this.mobileOpen){const e=document.createElement("div");if(e.className="designbase-wc-navbar__mobile-menu",c){const t=document.createElement("div");t.className="designbase-wc-navbar__mobile-search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"),a.setAttribute("full-width",""),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),t.append(a),e.append(t)}const t=document.createElement("ul");t.className="designbase-wc-navbar__mobile-nav-list",e.append(t);const a=document.createElement("div");if(a.className="designbase-wc-navbar__mobile-user",r&&i){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-info";const t=document.createElement("db-avatar");this.applyAvatarProfile(t,i,"m");const n=document.createElement("div"),r=document.createElement("div");if(r.className="designbase-wc-navbar__mobile-user-name",r.textContent=i.name,n.append(r),i.email){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-email",e.textContent=i.email,n.append(e)}if(e.append(t,n),a.append(e),s.length){const e=document.createElement("ul");e.className="designbase-wc-navbar__mobile-user-menu",s.forEach(t=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(t,"m",()=>{this.mobileOpen=!1,this.render()})),e.append(a)}),a.append(e)}}else{const e=document.createElement("db-button");e.setAttribute("variant","primary"),e.setAttribute("size","m"),e.setAttribute("full-width",""),e.textContent="로그인",e.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),a.append(e)}e.append(a),this.append(e),this.renderMobileMenu()}}}customElements.get("db-navbar")||customElements.define("db-navbar",DbNavbar);export{DbNavbar};
1
+ import{createDbIcon as e}from"./db-icons.js";import{NAVBAR_SIZES as t,NAVBAR_VARIANTS as a,NAVBAR_POSITIONS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function resolveIcon(e){if(e)return e}class DbNavbar extends HTMLElement{constructor(){super(...arguments),this.mobileOpen=!1,this.userMenuOpen=!1,this.expandedMobile={},this.outsideHandler=null}static get observedAttributes(){return["items","user-menu-items","user-profile","size","variant","position","is-authenticated","show-search","search-placeholder","full-width","shadow"]}connectedCallback(){this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems("items")}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseItems("user-menu-items")}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}parseItems(e="items"){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}iconSize(e){return"s"===e?16:"l"===e?24:20}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{this.contains(e.target)||(this.userMenuOpen=!1,this.updateUserMenuVisibility())},document.addEventListener("mousedown",this.outsideHandler))}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}dispatchItemClick(e,t){this.dispatchEvent(new CustomEvent("user"===t?"db-user-menu-item-click":"db-item-click",{bubbles:!0,composed:!0,detail:{item:e,source:t}}))}syncHostClasses(){const e=this.getAttribute("size")||"m",s=this.getAttribute("variant")||"default",i=this.getAttribute("position")||"static";this.className=["designbase-wc-navbar",`designbase-wc-navbar--${t.includes(e)?e:"m"}`,`designbase-wc-navbar--${a.includes(s)?s:"default"}`,`designbase-wc-navbar--${n.includes(i)?i:"static"}`,this.hasAttribute("full-width")&&"designbase-wc-navbar--full-width",this.hasAttribute("shadow")&&"designbase-wc-navbar--shadow",this.mobileOpen&&"designbase-wc-navbar--mobile-open"].filter(Boolean).join(" ")}isMegaMenu(e){return Boolean(e.megaMenu&&e.columns?.length)}createNavToggleButton(t,a){const n=document.createElement("button");n.type="button",n.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),n.disabled=Boolean(t.disabled);const s=resolveIcon(t.icon);s&&n.append(e(s,a)),n.append(document.createTextNode(t.label));const i=e("chevron-down",12);return i.classList.add("designbase-wc-navbar__chevron"),n.append(i),n}createMegaLink(t,a){const n=document.createElement("a");n.href=t.href||"#",n.className=["designbase-wc-navbar__mega-link",t.active&&"designbase-wc-navbar__mega-link--active",t.disabled&&"designbase-wc-navbar__mega-link--disabled"].filter(Boolean).join(" ");const s=resolveIcon(t.icon);if(s){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-link-icon",t.append(e(s,a)),n.append(t)}const i=document.createElement("span");i.className="designbase-wc-navbar__mega-link-body";const r=document.createElement("span");if(r.className="designbase-wc-navbar__mega-link-label",r.textContent=t.label,i.append(r),t.description){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-link-desc",e.textContent=t.description,i.append(e)}return n.append(i),n.addEventListener("click",e=>{e.preventDefault(),t.disabled||this.dispatchItemClick(t,"nav")}),n}createMegaMenu(e,t){const a=document.createElement("li");a.className="designbase-wc-navbar__nav-item designbase-wc-navbar__nav-item--mega";const n=this.createNavToggleButton(e,t),s=document.createElement("div");s.className="designbase-wc-navbar__mega";const i=document.createElement("div");i.className="designbase-wc-navbar__mega-inner";const r=document.createElement("div");return r.className="designbase-wc-navbar__mega-columns",r.style.setProperty("--db-navbar-mega-columns",String(e.columns.length)),e.columns.forEach(e=>{const a=document.createElement("div");if(a.className="designbase-wc-navbar__mega-column",e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-column-title",t.textContent=e.title,a.append(t)}const n=document.createElement("ul");n.className="designbase-wc-navbar__mega-list",e.items.forEach(e=>{const a=document.createElement("li");a.append(this.createMegaLink(e,t)),n.append(a)}),a.append(n),r.append(a)}),i.append(r),e.featured&&i.append(this.createMegaFeatured(e.featured,t)),s.append(i),a.append(n,s),a}createMegaFeatured(t,a){const n=document.createElement("a");n.href=t.href||"#",n.className="designbase-wc-navbar__mega-featured",t.image&&(n.style.setProperty("--db-navbar-mega-featured-image",`url("${t.image}")`),n.classList.add("designbase-wc-navbar__mega-featured--image"));const s=resolveIcon(t.icon);if(s){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-icon",t.append(e(s,a+4)),n.append(t)}if(t.title){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-title",e.textContent=t.title,n.append(e)}if(t.description){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-desc",e.textContent=t.description,n.append(e)}if(t.ctaLabel){const a=document.createElement("span");a.className="designbase-wc-navbar__mega-featured-cta",a.append(document.createTextNode(t.ctaLabel)),a.append(e("chevron-right",14)),n.append(a)}return n.addEventListener("click",e=>{e.preventDefault(),this.dispatchItemClick({id:`${t.href||"featured"}`,label:t.title||"featured",href:t.href},"nav")}),n}createDesktopNavItem(t,a){if(this.isMegaMenu(t))return this.createMegaMenu(t,a);const n=document.createElement("li");n.className="designbase-wc-navbar__nav-item";if(Boolean(t.children?.length)){const s=document.createElement("div");s.className="designbase-wc-navbar__dropdown";const i=document.createElement("button");i.type="button",i.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),i.disabled=Boolean(t.disabled);const r=resolveIcon(t.icon);r&&i.append(e(r,a)),i.append(document.createTextNode(t.label));const c=e("chevron-down",12);c.classList.add("designbase-wc-navbar__chevron"),i.append(c);const d=document.createElement("ul");return d.className="designbase-wc-navbar__dropdown-menu",t.children.forEach(t=>{const n=document.createElement("li"),s=document.createElement("a");s.href=t.href||"#",s.className=["designbase-wc-navbar__dropdown-item",t.active&&"designbase-wc-navbar__dropdown-item--active",t.disabled&&"designbase-wc-navbar__dropdown-item--disabled"].filter(Boolean).join(" ");const i=resolveIcon(t.icon);i&&s.append(e(i,a)),s.append(document.createTextNode(t.label)),s.addEventListener("click",e=>{t.disabled?e.preventDefault():(e.preventDefault(),this.dispatchItemClick(t,"nav"))}),n.append(s),d.append(n)}),s.append(i,d),n.append(s),n}const s=document.createElement("a");s.href=t.href||"#",s.className=["designbase-wc-navbar__nav-link",t.active&&"designbase-wc-navbar__nav-link--active",t.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" ");const i=resolveIcon(t.icon);return i&&s.append(e(i,a)),s.append(document.createTextNode(t.label)),s.addEventListener("click",e=>{t.disabled?e.preventDefault():(e.preventDefault(),this.dispatchItemClick(t,"nav"))}),n.append(s),n}createUserMenuItemElement(e,t,a){const n=document.createElement("db-menu-item");return n.setAttribute("label",e.label),n.setAttribute("type","block"),n.setAttribute("menu-style","dropdown"),n.setAttribute("size",t),e.href&&n.setAttribute("href",e.href),e.icon&&n.setAttribute("icon",e.icon),e.disabled&&n.setAttribute("disabled",""),n.addEventListener("db-click",()=>{e.disabled||(a(),this.dispatchItemClick(e,"user"))}),n}bindSearchEvents(e){e.addEventListener("db-search",e=>{const t=e.detail,a=t.query??t.value??"";this.dispatchEvent(new CustomEvent("db-search",{bubbles:!0,composed:!0,detail:{query:a,value:a}}))})}applyAvatarProfile(e,t,a){e.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),e.setAttribute("initials",t.name),e.setAttribute("alt",t.name),t.avatar&&e.setAttribute("src",t.avatar),void 0!==t.badge&&e.setAttribute("badge",String(t.badge)),t.badgeVariant&&e.setAttribute("badge-variant",t.badgeVariant),t.badgeType&&e.setAttribute("badge-type",t.badgeType),t.badgeText&&e.setAttribute("badge-text",t.badgeText)}getMobileChildren(e){if(this.isMegaMenu(e)){const t=(e.columns||[]).flatMap(e=>e.items);return e.featured?.href&&t.push({id:`${e.id}-featured`,label:e.featured.title||e.featured.ctaLabel||e.label,href:e.featured.href,icon:e.featured.icon}),t}return e.children||[]}createMobileMenuItem(e,t){const a=this.getMobileChildren(e),n=a.length>0,s=Boolean(this.expandedMobile[e.id]),i=document.createElement("db-menu-item");return i.setAttribute("label",e.label),i.setAttribute("type","block"),i.setAttribute("menu-style","accordion"),i.setAttribute("size",t),e.href&&i.setAttribute("href",e.href),e.icon&&i.setAttribute("icon",e.icon),e.active&&i.setAttribute("active",""),e.disabled&&i.setAttribute("disabled",""),n&&(i.setAttribute("expandable",""),i.subItems=a.map(e=>({id:e.id,label:e.label,href:e.href,icon:e.icon,active:e.active,disabled:e.disabled})),s&&i.setAttribute("expanded","")),i.addEventListener("db-click",()=>{if(!e.disabled){if(n)return this.expandedMobile[e.id]=!s,void this.renderMobileMenu();this.mobileOpen=!1,this.dispatchItemClick(e,"mobile"),this.render()}}),i.addEventListener("db-child-click",e=>{const t=e.detail;this.mobileOpen=!1,this.dispatchItemClick(t.child,"mobile"),this.render()}),i}updateUserMenuVisibility(){const e=this.querySelector(".designbase-wc-navbar__user-dropdown-menu");e&&(e.hidden=!this.userMenuOpen)}renderMobileMenu(){const e=this.querySelector(".designbase-wc-navbar__mobile-nav-list");if(!e)return;const t=this.getAttribute("size")||"m",a=this.parseItems();e.replaceChildren(...a.map(e=>this.createMobileMenuItem(e,t)))}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.setAttribute("aria-label","메인 네비게이션");const t=this.getAttribute("size")||"m",a=this.iconSize(t),n=this.parseItems(),s=this.parseItems("user-menu-items"),i=this.parseUserProfile(),r=this.hasAttribute("is-authenticated"),c=this.hasAttribute("show-search");this.replaceChildren();const d=document.createElement("div");d.className=["designbase-wc-navbar__container",this.hasAttribute("full-width")&&"designbase-wc-navbar__container--full-width"].filter(Boolean).join(" ");const l=document.createElement("div");l.className="designbase-wc-navbar__left";const o=document.createElement("div");o.className="designbase-wc-navbar__brand";const b=document.createElement("div");b.className="designbase-wc-navbar__logo";const u=document.createElement("db-logo");u.setAttribute("type","designbase"),u.setAttribute("size","s"),u.setAttribute("clickable",""),u.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),b.append(u),o.append(b),l.append(o);const m=document.createElement("div");m.className="designbase-wc-navbar__right";const p=document.createElement("div");p.className="designbase-wc-navbar__nav designbase-wc-navbar__nav--desktop";const h=document.createElement("ul");if(h.className="designbase-wc-navbar__nav-list",n.forEach(e=>h.append(this.createDesktopNavItem(e,a))),p.append(h),m.append(p),c){const e=document.createElement("div");e.className="designbase-wc-navbar__search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"===t?"s":"l"===t?"l":"m"),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),e.append(a),m.append(e)}const v=document.createElement("div");if(v.className="designbase-wc-navbar__user-menu",r&&i){const a=document.createElement("div");a.className="designbase-wc-navbar__user-dropdown";const n=document.createElement("button");n.type="button",n.className="designbase-wc-navbar__user-toggle",n.setAttribute("aria-expanded",String(this.userMenuOpen));const r=document.createElement("db-avatar");this.applyAvatarProfile(r,i,t);const c=document.createElement("span");c.className="designbase-wc-navbar__user-name",c.textContent=i.name,n.append(r,c,e("chevron-down",12)),n.addEventListener("click",()=>{this.userMenuOpen=!this.userMenuOpen,n.setAttribute("aria-expanded",String(this.userMenuOpen)),this.updateUserMenuVisibility()});const d=document.createElement("ul");if(d.className="designbase-wc-navbar__user-dropdown-menu",d.hidden=!this.userMenuOpen,i.email){const e=document.createElement("li");e.className="designbase-wc-navbar__user-info";const t=document.createElement("span");t.className="designbase-wc-navbar__user-email",t.textContent=i.email,e.append(t),d.append(e)}s.forEach(e=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(e,t,()=>{this.userMenuOpen=!1,this.updateUserMenuVisibility()})),d.append(a)}),a.append(n,d),v.append(a)}else{const e=document.createElement("db-button");e.setAttribute("variant","primary"),e.setAttribute("size","s"===t?"s":"l"===t?"l":"m"),e.textContent="로그인",e.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),v.append(e)}m.append(v);const g=document.createElement("button");g.type="button",g.className="designbase-wc-navbar__mobile-toggle",g.setAttribute("aria-expanded",String(this.mobileOpen)),g.setAttribute("aria-label","메뉴 열기");for(let e=0;e<3;e+=1){const e=document.createElement("span");e.className="designbase-wc-navbar__mobile-toggle-line",g.append(e)}if(g.addEventListener("click",()=>{this.mobileOpen=!this.mobileOpen,this.render()}),d.append(l,m,g),this.append(d),this.mobileOpen){const e=document.createElement("div");if(e.className="designbase-wc-navbar__mobile-menu",c){const t=document.createElement("div");t.className="designbase-wc-navbar__mobile-search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"),a.setAttribute("full-width",""),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),t.append(a),e.append(t)}const t=document.createElement("ul");t.className="designbase-wc-navbar__mobile-nav-list",e.append(t);const a=document.createElement("div");if(a.className="designbase-wc-navbar__mobile-user",r&&i){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-info";const t=document.createElement("db-avatar");this.applyAvatarProfile(t,i,"m");const n=document.createElement("div"),r=document.createElement("div");if(r.className="designbase-wc-navbar__mobile-user-name",r.textContent=i.name,n.append(r),i.email){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-email",e.textContent=i.email,n.append(e)}if(e.append(t,n),a.append(e),s.length){const e=document.createElement("ul");e.className="designbase-wc-navbar__mobile-user-menu",s.forEach(t=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(t,"m",()=>{this.mobileOpen=!1,this.render()})),e.append(a)}),a.append(e)}}else{const e=document.createElement("db-button");e.setAttribute("variant","primary"),e.setAttribute("size","m"),e.setAttribute("full-width",""),e.textContent="로그인",e.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),a.append(e)}e.append(a),this.append(e),this.renderMobileMenu()}}}customElements.get("db-navbar")||customElements.define("db-navbar",DbNavbar);export{DbNavbar};
@@ -7,6 +7,9 @@ type OnboardingStep = {
7
7
  declare class DbOnboardingModal extends HTMLElement {
8
8
  static get observedAttributes(): string[];
9
9
  private root?;
10
+ private focusTrap?;
11
+ /** 참조 카운트 스크롤락을 이 인스턴스가 잡고 있는지 (PERF-GLOBAL-STATE) */
12
+ private scrollLocked;
10
13
  private internalStep;
11
14
  private keyHandler;
12
15
  private isMounted;
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";class DbOnboardingModal extends HTMLElement{constructor(){super(...arguments),this.internalStep=0,this.keyHandler=null,this.isMounted=!1,this.handlePrev=()=>{this.getCurrentStep()>0&&this.goToStep(this.getCurrentStep()-1)},this.handleNext=()=>{const t=this.getSteps(),e=this.getCurrentStep();e>=t.length-1?this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})):this.goToStep(e+1)}}static get observedAttributes(){return["open","steps","current-step","show-close-button","show-indicator","indicator-type","indicator-size"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}get steps(){return this.parseSteps()}set steps(t){const e="string"==typeof t?t:JSON.stringify(t);this.getAttribute("steps")!==e&&this.setAttribute("steps",e)}connectedCallback(){this.style.display="contents",this.syncStepFromAttribute(),this.syncOpenState()}disconnectedCallback(){this.detachKeyHandler(),this.unmount()}attributeChangedCallback(t){this.isConnected&&("open"!==t?("current-step"===t&&this.syncStepFromAttribute(),"steps"!==t?this.isMounted&&this.render():this.isOpenRequested()&&(this.isMounted?this.render():this.syncOpenState())):this.syncOpenState())}isOpenRequested(){return this.open}parseSteps(){const t=this.getAttribute("steps");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}syncStepFromAttribute(){if(!this.hasAttribute("current-step"))return;const t=Number(this.getAttribute("current-step")||0);Number.isFinite(t)&&(this.internalStep=Math.max(0,t))}getSteps(){return this.parseSteps()}getCurrentStep(){const t=this.getSteps();return t.length?Math.min(Math.max(this.internalStep,0),t.length-1):0}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}emitStepChange(t){this.dispatchEvent(new CustomEvent("db-step-change",{bubbles:!0,composed:!0,detail:{step:t}}))}goToStep(t){const e=this.getSteps();if(!e.length)return;const i=Math.min(Math.max(t,0),e.length-1);this.internalStep=i,this.emitStepChange(i),this.render()}attachKeyHandler(){this.keyHandler||(this.keyHandler=t=>{"Escape"!==t.key?"ArrowLeft"===t.key&&this.getCurrentStep()>0?this.handlePrev():"ArrowRight"===t.key&&this.getCurrentStep()<this.getSteps().length-1&&this.handleNext():this.close()},document.addEventListener("keydown",this.keyHandler))}detachKeyHandler(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}syncOpenState(){if(this.isOpenRequested())return this.mount(),void this.attachKeyHandler();this.detachKeyHandler(),this.unmount()}mount(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-onboarding-modal",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.tabIndex=-1,this.ensureStructure()),this.root.isConnected||document.body.append(this.root),this.isMounted=!0,this.render()}unmount(){this.isMounted=!1,this.root?.remove()}ensureStructure(){this.root&&(this.contentEl&&this.root.contains(this.contentEl)||(this.overlayEl=void 0,this.contentEl=void 0,this.closeButtonEl=void 0,this.mainEl=void 0,this.imageWrapEl=void 0,this.imageEl=void 0,this.textEl=void 0,this.titleEl=void 0,this.descriptionEl=void 0,this.navigationEl=void 0,this.prevButtonEl=void 0,this.nextButtonEl=void 0,this.indicatorEl=void 0,this.root.replaceChildren(),this.overlayEl=document.createElement("div"),this.overlayEl.className="designbase-wc-onboarding-modal__overlay",this.overlayEl.addEventListener("click",()=>this.close()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-onboarding-modal__content",this.closeButtonEl=document.createElement("button"),this.closeButtonEl.type="button",this.closeButtonEl.className="designbase-wc-onboarding-modal__close-button",this.closeButtonEl.setAttribute("aria-label","닫기"),this.closeButtonEl.append(t("close",20)),this.closeButtonEl.addEventListener("click",()=>this.close()),this.mainEl=document.createElement("div"),this.mainEl.className="designbase-wc-onboarding-modal__main",this.imageWrapEl=document.createElement("div"),this.imageWrapEl.className="designbase-wc-onboarding-modal__image",this.imageEl=document.createElement("img"),this.imageWrapEl.append(this.imageEl),this.textEl=document.createElement("div"),this.textEl.className="designbase-wc-onboarding-modal__text",this.titleEl=document.createElement("h2"),this.titleEl.id="onboarding-title",this.titleEl.className="designbase-wc-onboarding-modal__title",this.descriptionEl=document.createElement("p"),this.descriptionEl.id="onboarding-description",this.descriptionEl.className="designbase-wc-onboarding-modal__description",this.textEl.append(this.titleEl,this.descriptionEl),this.mainEl.append(this.imageWrapEl,this.textEl),this.navigationEl=document.createElement("div"),this.navigationEl.className="designbase-wc-onboarding-modal__navigation",this.prevButtonEl=document.createElement("db-button"),this.prevButtonEl.setAttribute("variant","secondary"),this.prevButtonEl.setAttribute("size","m"),this.prevButtonEl.setAttribute("start-icon","chevron-left"),this.prevButtonEl.setAttribute("aria-label","이전"),this.prevButtonEl.addEventListener("db-click",this.handlePrev),this.indicatorEl=document.createElement("db-indicator"),this.indicatorEl.addEventListener("db-step-click",t=>{const e=t.detail;this.goToStep(e.index??e.current)}),this.nextButtonEl=document.createElement("db-button"),this.nextButtonEl.setAttribute("variant","primary"),this.nextButtonEl.setAttribute("size","m"),this.nextButtonEl.addEventListener("db-click",this.handleNext),this.navigationEl.append(this.prevButtonEl,this.indicatorEl,this.nextButtonEl),this.contentEl.append(this.closeButtonEl,this.mainEl,this.navigationEl),this.root.append(this.overlayEl,this.contentEl)))}render(){if(!this.root||!this.isMounted)return;this.ensureStructure();const t=this.getSteps(),e=this.getCurrentStep(),i=t[e];if(!i)return;const s=!this.hasAttribute("show-close-button")||"false"!==this.getAttribute("show-close-button"),n=!this.hasAttribute("show-indicator")||"false"!==this.getAttribute("show-indicator"),o=this.getAttribute("indicator-type")||"dots",r=this.getAttribute("indicator-size")||"m",a=0===e,l=e===t.length-1;if(this.root.setAttribute("aria-labelledby","onboarding-title"),this.root.setAttribute("aria-describedby","onboarding-description"),this.closeButtonEl&&(this.closeButtonEl.style.display=s?"":"none"),this.imageWrapEl&&this.imageEl&&(i.image?(this.imageEl.src=i.image,this.imageEl.alt=i.title||"온보딩 이미지",this.imageWrapEl.style.display=""):this.imageWrapEl.style.display="none"),this.titleEl&&(this.titleEl.textContent=i.title||"",this.titleEl.style.display=i.title?"":"none"),this.descriptionEl&&(this.descriptionEl.textContent=i.description||"",this.descriptionEl.style.display=i.description?"":"none"),this.prevButtonEl&&(this.prevButtonEl.textContent="이전",a?this.prevButtonEl.setAttribute("disabled",""):this.prevButtonEl.removeAttribute("disabled")),this.nextButtonEl&&(this.nextButtonEl.textContent=l?"완료":"다음",this.nextButtonEl.setAttribute("aria-label",l?"완료":"다음"),l?this.nextButtonEl.removeAttribute("end-icon"):this.nextButtonEl.setAttribute("end-icon","chevron-right")),this.indicatorEl){const i=n&&t.length>1;this.indicatorEl.style.display=i?"":"none",i&&(this.indicatorEl.setAttribute("total",String(t.length)),this.indicatorEl.setAttribute("current",String(e)),this.indicatorEl.setAttribute("indicator-type",o),this.indicatorEl.setAttribute("size",r),this.indicatorEl.setAttribute("clickable",""))}}}customElements.get("db-onboarding-modal")||customElements.define("db-onboarding-modal",DbOnboardingModal);export{DbOnboardingModal};
1
+ import{createDbIcon as t}from"./db-icons.js";import{createFocusTrap as e}from"../core/focus-trap.js";import{lockScroll as i,unlockScroll as s}from"../core/scroll-lock.js";class DbOnboardingModal extends HTMLElement{constructor(){super(...arguments),this.scrollLocked=!1,this.internalStep=0,this.keyHandler=null,this.isMounted=!1,this.handlePrev=()=>{this.getCurrentStep()>0&&this.goToStep(this.getCurrentStep()-1)},this.handleNext=()=>{const t=this.getSteps(),e=this.getCurrentStep();e>=t.length-1?this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})):this.goToStep(e+1)}}static get observedAttributes(){return["open","steps","current-step","show-close-button","show-indicator","indicator-type","indicator-size"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}get steps(){return this.parseSteps()}set steps(t){const e="string"==typeof t?t:JSON.stringify(t);this.getAttribute("steps")!==e&&this.setAttribute("steps",e)}connectedCallback(){this.style.display="contents",this.syncStepFromAttribute(),this.syncOpenState()}disconnectedCallback(){this.detachKeyHandler(),this.unmount()}attributeChangedCallback(t){this.isConnected&&("open"!==t?("current-step"===t&&this.syncStepFromAttribute(),"steps"!==t?this.isMounted&&this.render():this.isOpenRequested()&&(this.isMounted?this.render():this.syncOpenState())):this.syncOpenState())}isOpenRequested(){return this.open}parseSteps(){const t=this.getAttribute("steps");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}syncStepFromAttribute(){if(!this.hasAttribute("current-step"))return;const t=Number(this.getAttribute("current-step")||0);Number.isFinite(t)&&(this.internalStep=Math.max(0,t))}getSteps(){return this.parseSteps()}getCurrentStep(){const t=this.getSteps();return t.length?Math.min(Math.max(this.internalStep,0),t.length-1):0}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}emitStepChange(t){this.dispatchEvent(new CustomEvent("db-step-change",{bubbles:!0,composed:!0,detail:{step:t}}))}goToStep(t){const e=this.getSteps();if(!e.length)return;const i=Math.min(Math.max(t,0),e.length-1);this.internalStep=i,this.emitStepChange(i),this.render()}attachKeyHandler(){this.keyHandler||(this.keyHandler=t=>{"Escape"!==t.key?"ArrowLeft"===t.key&&this.getCurrentStep()>0?this.handlePrev():"ArrowRight"===t.key&&this.getCurrentStep()<this.getSteps().length-1&&this.handleNext():this.close()},document.addEventListener("keydown",this.keyHandler))}detachKeyHandler(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}syncOpenState(){if(this.isOpenRequested())return this.mount(),void this.attachKeyHandler();this.detachKeyHandler(),this.unmount()}mount(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-onboarding-modal",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.tabIndex=-1,this.ensureStructure()),this.root.isConnected||document.body.append(this.root),this.isMounted=!0,this.render(),this.scrollLocked||(i(),this.scrollLocked=!0),this.root&&!this.focusTrap&&(this.focusTrap=e(this.root),requestAnimationFrame(()=>this.focusTrap?.activate()))}unmount(){this.isMounted=!1,this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.scrollLocked&&(this.scrollLocked=!1,s())}ensureStructure(){this.root&&(this.contentEl&&this.root.contains(this.contentEl)||(this.overlayEl=void 0,this.contentEl=void 0,this.closeButtonEl=void 0,this.mainEl=void 0,this.imageWrapEl=void 0,this.imageEl=void 0,this.textEl=void 0,this.titleEl=void 0,this.descriptionEl=void 0,this.navigationEl=void 0,this.prevButtonEl=void 0,this.nextButtonEl=void 0,this.indicatorEl=void 0,this.root.replaceChildren(),this.overlayEl=document.createElement("div"),this.overlayEl.className="designbase-wc-onboarding-modal__overlay",this.overlayEl.addEventListener("click",()=>this.close()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-onboarding-modal__content",this.closeButtonEl=document.createElement("button"),this.closeButtonEl.type="button",this.closeButtonEl.className="designbase-wc-onboarding-modal__close-button",this.closeButtonEl.setAttribute("aria-label","닫기"),this.closeButtonEl.append(t("close",20)),this.closeButtonEl.addEventListener("click",()=>this.close()),this.mainEl=document.createElement("div"),this.mainEl.className="designbase-wc-onboarding-modal__main",this.imageWrapEl=document.createElement("div"),this.imageWrapEl.className="designbase-wc-onboarding-modal__image",this.imageEl=document.createElement("img"),this.imageWrapEl.append(this.imageEl),this.textEl=document.createElement("div"),this.textEl.className="designbase-wc-onboarding-modal__text",this.titleEl=document.createElement("h2"),this.titleEl.id="onboarding-title",this.titleEl.className="designbase-wc-onboarding-modal__title",this.descriptionEl=document.createElement("p"),this.descriptionEl.id="onboarding-description",this.descriptionEl.className="designbase-wc-onboarding-modal__description",this.textEl.append(this.titleEl,this.descriptionEl),this.mainEl.append(this.imageWrapEl,this.textEl),this.navigationEl=document.createElement("div"),this.navigationEl.className="designbase-wc-onboarding-modal__navigation",this.prevButtonEl=document.createElement("db-button"),this.prevButtonEl.setAttribute("variant","secondary"),this.prevButtonEl.setAttribute("size","m"),this.prevButtonEl.setAttribute("start-icon","chevron-left"),this.prevButtonEl.setAttribute("aria-label","이전"),this.prevButtonEl.addEventListener("db-click",this.handlePrev),this.indicatorEl=document.createElement("db-indicator"),this.indicatorEl.addEventListener("db-step-click",t=>{const e=t.detail;this.goToStep(e.index??e.current)}),this.nextButtonEl=document.createElement("db-button"),this.nextButtonEl.setAttribute("variant","primary"),this.nextButtonEl.setAttribute("size","m"),this.nextButtonEl.addEventListener("db-click",this.handleNext),this.navigationEl.append(this.prevButtonEl,this.indicatorEl,this.nextButtonEl),this.contentEl.append(this.closeButtonEl,this.mainEl,this.navigationEl),this.root.append(this.overlayEl,this.contentEl)))}render(){if(!this.root||!this.isMounted)return;this.ensureStructure();const t=this.getSteps(),e=this.getCurrentStep(),i=t[e];if(!i)return;const s=!this.hasAttribute("show-close-button")||"false"!==this.getAttribute("show-close-button"),n=!this.hasAttribute("show-indicator")||"false"!==this.getAttribute("show-indicator"),o=this.getAttribute("indicator-type")||"dots",r=this.getAttribute("indicator-size")||"m",a=0===e,l=e===t.length-1;if(this.root.setAttribute("aria-labelledby","onboarding-title"),this.root.setAttribute("aria-describedby","onboarding-description"),this.closeButtonEl&&(this.closeButtonEl.style.display=s?"":"none"),this.imageWrapEl&&this.imageEl&&(i.image?(this.imageEl.src=i.image,this.imageEl.alt=i.title||"온보딩 이미지",this.imageWrapEl.style.display=""):this.imageWrapEl.style.display="none"),this.titleEl&&(this.titleEl.textContent=i.title||"",this.titleEl.style.display=i.title?"":"none"),this.descriptionEl&&(this.descriptionEl.textContent=i.description||"",this.descriptionEl.style.display=i.description?"":"none"),this.prevButtonEl&&(this.prevButtonEl.textContent="이전",a?this.prevButtonEl.setAttribute("disabled",""):this.prevButtonEl.removeAttribute("disabled")),this.nextButtonEl&&(this.nextButtonEl.textContent=l?"완료":"다음",this.nextButtonEl.setAttribute("aria-label",l?"완료":"다음"),l?this.nextButtonEl.removeAttribute("end-icon"):this.nextButtonEl.setAttribute("end-icon","chevron-right")),this.indicatorEl){const i=n&&t.length>1;this.indicatorEl.style.display=i?"":"none",i&&(this.indicatorEl.setAttribute("total",String(t.length)),this.indicatorEl.setAttribute("current",String(e)),this.indicatorEl.setAttribute("indicator-type",o),this.indicatorEl.setAttribute("size",r),this.indicatorEl.setAttribute("clickable",""))}}}customElements.get("db-onboarding-modal")||customElements.define("db-onboarding-modal",DbOnboardingModal);export{DbOnboardingModal};
@@ -1,10 +1,11 @@
1
+ import { OTP_INPUT_SIZES } from '@designbasekorea/ui-contracts';
2
+
1
3
  /**
2
4
  * ui-wc — db-otp-input (수동 작성, 자동 동기화 대상 아님)
3
5
  *
4
6
  * 분할 자릿수 OTP/PIN 입력. 붙여넣기·화살표·백스페이스를 지원합니다.
5
7
  */
6
- declare const SIZES: readonly ["s", "m", "l"];
7
- type OtpSize = (typeof SIZES)[number];
8
+ type OtpSize = (typeof OTP_INPUT_SIZES)[number];
8
9
  declare class DbOtpInput extends HTMLElement {
9
10
  static formAssociated: boolean;
10
11
  static get observedAttributes(): string[];
@@ -1 +1 @@
1
- const t=["s","m","l"];function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}class DbOtpInput extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals?.(),this.built=!1,this.digits=[],this.suppressSync=!1,this.initialValue="",this.lastCompleteValue="",this.onDigitFocus=t=>{const e=t.currentTarget;requestAnimationFrame(()=>e.select())},this.onDigitInput=t=>{if(this.suppressSync)return;const e=t.currentTarget,i=Number(e.dataset.index||0),s=e.value.replace(/\D/g,"");if(s.length>1){const t=this.digits.slice(0,i).map(t=>t.value).join("");return void this.applyValue(t+s,Math.min(this.length-1,t.length+s.length))}e.value=s.slice(-1),e.classList.toggle("designbase-wc-otp-input__digit--filled",Boolean(e.value));const a=this.digits.map(t=>t.value).join("");this.setAttribute("value",a),this.emit("db-input"),this.emit("db-change"),e.value&&i<this.digits.length-1&&this.focusAt(i+1)},this.onDigitKeydown=t=>{const e=t.currentTarget,i=Number(e.dataset.index||0);if("Backspace"!==t.key)return"ArrowLeft"===t.key?(t.preventDefault(),void this.focusAt(i-1)):"ArrowRight"===t.key?(t.preventDefault(),void this.focusAt(i+1)):void("Delete"===t.key&&(e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change")));if(e.value)e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change");else if(i>0){t.preventDefault(),this.focusAt(i-1);const e=this.digits[i-1];e&&(e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change"))}},this.onPaste=t=>{t.preventDefault();const e=t.clipboardData?.getData("text")||"",i=Number(t.currentTarget.dataset.index||0),s=this.digits.slice(0,i).map(t=>t.value).join("");this.applyValue(s+e,Math.min(this.length-1,s.length+e.replace(/\D/g,"").length))}}static get observedAttributes(){return["length","value","size","disabled","readonly","error","error-message","label","auto-focus","masked","name","required"]}get length(){const t=Number(this.getAttribute("length")||6);return Number.isFinite(t)?Math.min(8,Math.max(4,Math.round(t))):6}set length(t){this.setAttribute("length",String(t))}get value(){return this.digits.map(t=>t.value).join("")||this.getAttribute("value")||""}set value(t){this.setAttribute("value",t)}get size(){return function pick(t,e,i){return t.includes(e)?e:i}(t,this.getAttribute("size"),"m")}set size(t){this.setAttribute("size",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}connectedCallback(){this.built||(this.initialValue=this.getAttribute("value")||""),this.build(),this.sync(),this.hasAttribute("auto-focus")&&!this.disabled&&requestAnimationFrame(()=>this.focusFirstEmpty())}attributeChangedCallback(t){this.built&&("length"===t&&(this.built=!1,this.build()),this.sync())}focus(){this.disabled||this.focusFirstEmpty()}clear(){this.suppressSync=!0,this.digits.forEach(t=>{t.value=""}),this.suppressSync=!1,this.lastCompleteValue="",this.setValueAttribute(""),this.emit("db-input"),this.emit("db-change"),this.focusFirstEmpty()}formResetCallback(){this.lastCompleteValue="",this.value=this.initialValue}formDisabledCallback(t){this.toggleAttribute("disabled",t)}build(){this.replaceChildren(),this.digits=[];const t=this.length,e="designbase-wc-otp-input",i=this.getAttribute("label");if(i){const t=el("div",`${e}__label`);t.textContent=i,this.append(t)}const s=el("div",`${e}__row`);s.setAttribute("role","group"),s.setAttribute("aria-label",i||"인증 코드");for(let i=0;i<t;i+=1){const t=el("div",`${e}__cell`),a=document.createElement("input");a.className=`${e}__digit`,a.type=this.hasAttribute("masked")?"password":"text",a.inputMode="numeric",a.autocomplete=0===i?"one-time-code":"off",a.maxLength=1,a.pattern="[0-9]*",a.setAttribute("aria-label",`${i+1}번째 자리`),a.dataset.index=String(i),a.addEventListener("input",this.onDigitInput),a.addEventListener("keydown",this.onDigitKeydown),a.addEventListener("paste",this.onPaste),a.addEventListener("focus",this.onDigitFocus),t.append(a),s.append(t),this.digits.push(a)}this.append(s),this.errorEl=el("p",`${e}__error`),this.errorEl.id=`${this.id||`db-otp-${Math.random().toString(36).slice(2)}`}-error`,this.errorEl.setAttribute("role","alert"),this.errorEl.hidden=!0,this.append(this.errorEl),this.built=!0}sync(){const t="designbase-wc-otp-input",e=this.size,i=this.hasAttribute("error"),s=this.disabled,a=this.readOnly,l=this.getAttribute("error-message")||"";this.className=[t,`${t}--${e}`,i&&`${t}--error`,s&&`${t}--disabled`].filter(Boolean).join(" ");const r=(this.getAttribute("value")||"").replace(/\D/g,"").slice(0,this.length);this.suppressSync=!0,this.digits.forEach((e,n)=>{e.value=r[n]||"",e.disabled=s,e.readOnly=a,e.type=this.hasAttribute("masked")?"password":"text",e.classList.toggle(`${t}__digit--filled`,Boolean(e.value)),e.setAttribute("aria-invalid",String(i)),i&&l?e.setAttribute("aria-describedby",this.errorEl?.id||""):e.removeAttribute("aria-describedby")}),this.suppressSync=!1,this.errorEl&&(this.errorEl.textContent=l,this.errorEl.hidden=!i||!l),this.setAttribute("role","group"),this.setAttribute("aria-disabled",String(s)),this.setAttribute("aria-invalid",String(i)),this.syncFormValue(r)}emit(t){const e=this.digits.map(t=>t.value).join("");if(this.setValueAttribute(e),this.dispatchEvent(new CustomEvent(t,{detail:{value:e},bubbles:!0,composed:!0})),"db-change"===t&&e.length===this.length&&/^\d+$/.test(e)){if(e===this.lastCompleteValue)return;this.lastCompleteValue=e,this.dispatchEvent(new CustomEvent("db-complete",{detail:{value:e},bubbles:!0,composed:!0}))}else e.length!==this.length&&(this.lastCompleteValue="")}setValueAttribute(t){this.getAttribute("value")!==t&&this.setAttribute("value",t),this.syncFormValue(t)}syncFormValue(t){this.internals?.setFormValue(t||null),this.internals&&(this.hasAttribute("error")?this.internals.setValidity({customError:!0},this.getAttribute("error-message")||"인증 코드가 올바르지 않습니다.",this.digits[0]):this.hasAttribute("required")&&t.length!==this.length?this.internals.setValidity({valueMissing:!0},"인증 코드를 모두 입력해 주세요.",this.digits.find(t=>!t.value)||this.digits[0]):this.internals.setValidity({}))}focusFirstEmpty(){const t=this.digits.find(t=>!t.value)||this.digits[this.digits.length-1];t?.focus(),t?.select()}focusAt(t){const e=this.digits[Math.max(0,Math.min(this.digits.length-1,t))];e?.focus(),e?.select()}applyValue(t,e){const i=t.replace(/\D/g,"").slice(0,this.length);this.suppressSync=!0,this.digits.forEach((t,e)=>{t.value=i[e]||"",t.classList.toggle("designbase-wc-otp-input__digit--filled",Boolean(t.value))}),this.suppressSync=!1,this.emit("db-input"),this.emit("db-change"),void 0!==e?this.focusAt(e):i.length<this.length?this.focusAt(i.length):this.focusAt(this.length-1)}}DbOtpInput.formAssociated=!0,customElements.get("db-otp-input")||customElements.define("db-otp-input",DbOtpInput);export{DbOtpInput};
1
+ import{dbUid as t}from"../core/uid.js";import{OTP_INPUT_SIZES as e}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}class DbOtpInput extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals?.(),this.built=!1,this.digits=[],this.suppressSync=!1,this.initialValue="",this.lastCompleteValue="",this.onDigitFocus=t=>{const e=t.currentTarget;requestAnimationFrame(()=>e.select())},this.onDigitInput=t=>{if(this.suppressSync)return;const e=t.currentTarget,i=Number(e.dataset.index||0),s=e.value.replace(/\D/g,"");if(s.length>1){const t=this.digits.slice(0,i).map(t=>t.value).join("");return void this.applyValue(t+s,Math.min(this.length-1,t.length+s.length))}e.value=s.slice(-1),e.classList.toggle("designbase-wc-otp-input__digit--filled",Boolean(e.value));const a=this.digits.map(t=>t.value).join("");this.setAttribute("value",a),this.emit("db-input"),this.emit("db-change"),e.value&&i<this.digits.length-1&&this.focusAt(i+1)},this.onDigitKeydown=t=>{const e=t.currentTarget,i=Number(e.dataset.index||0);if("Backspace"!==t.key)return"ArrowLeft"===t.key?(t.preventDefault(),void this.focusAt(i-1)):"ArrowRight"===t.key?(t.preventDefault(),void this.focusAt(i+1)):void("Delete"===t.key&&(e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change")));if(e.value)e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change");else if(i>0){t.preventDefault(),this.focusAt(i-1);const e=this.digits[i-1];e&&(e.value="",e.classList.remove("designbase-wc-otp-input__digit--filled"),this.emit("db-input"),this.emit("db-change"))}},this.onPaste=t=>{t.preventDefault();const e=t.clipboardData?.getData("text")||"",i=Number(t.currentTarget.dataset.index||0),s=this.digits.slice(0,i).map(t=>t.value).join("");this.applyValue(s+e,Math.min(this.length-1,s.length+e.replace(/\D/g,"").length))}}static get observedAttributes(){return["length","value","size","disabled","readonly","error","error-message","label","auto-focus","masked","name","required"]}get length(){const t=Number(this.getAttribute("length")||6);return Number.isFinite(t)?Math.min(8,Math.max(4,Math.round(t))):6}set length(t){this.setAttribute("length",String(t))}get value(){return this.digits.map(t=>t.value).join("")||this.getAttribute("value")||""}set value(t){this.setAttribute("value",t)}get size(){return function pick(t,e,i){return t.includes(e)?e:i}(e,this.getAttribute("size"),"m")}set size(t){this.setAttribute("size",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}connectedCallback(){this.built||(this.initialValue=this.getAttribute("value")||""),this.build(),this.sync(),this.hasAttribute("auto-focus")&&!this.disabled&&requestAnimationFrame(()=>this.focusFirstEmpty())}attributeChangedCallback(t){this.built&&("length"===t&&(this.built=!1,this.build()),this.sync())}focus(){this.disabled||this.focusFirstEmpty()}clear(){this.suppressSync=!0,this.digits.forEach(t=>{t.value=""}),this.suppressSync=!1,this.lastCompleteValue="",this.setValueAttribute(""),this.emit("db-input"),this.emit("db-change"),this.focusFirstEmpty()}formResetCallback(){this.lastCompleteValue="",this.value=this.initialValue}formDisabledCallback(t){this.toggleAttribute("disabled",t)}build(){this.replaceChildren(),this.digits=[];const e=this.length,i="designbase-wc-otp-input",s=this.getAttribute("label");if(s){const t=el("div",`${i}__label`);t.textContent=s,this.append(t)}const a=el("div",`${i}__row`);a.setAttribute("role","group"),a.setAttribute("aria-label",s||"인증 코드");for(let t=0;t<e;t+=1){const e=el("div",`${i}__cell`),s=document.createElement("input");s.className=`${i}__digit`,s.type=this.hasAttribute("masked")?"password":"text",s.inputMode="numeric",s.autocomplete=0===t?"one-time-code":"off",s.maxLength=1,s.pattern="[0-9]*",s.setAttribute("aria-label",`${t+1}번째 자리`),s.dataset.index=String(t),s.addEventListener("input",this.onDigitInput),s.addEventListener("keydown",this.onDigitKeydown),s.addEventListener("paste",this.onPaste),s.addEventListener("focus",this.onDigitFocus),e.append(s),a.append(e),this.digits.push(s)}this.append(a),this.errorEl=el("p",`${i}__error`),this.errorEl.id=`${this.id||t("db-otp")}-error`,this.errorEl.setAttribute("role","alert"),this.errorEl.hidden=!0,this.append(this.errorEl),this.built=!0}sync(){const t="designbase-wc-otp-input",e=this.size,i=this.hasAttribute("error"),s=this.disabled,a=this.readOnly,l=this.getAttribute("error-message")||"";this.className=[t,`${t}--${e}`,i&&`${t}--error`,s&&`${t}--disabled`].filter(Boolean).join(" ");const r=(this.getAttribute("value")||"").replace(/\D/g,"").slice(0,this.length);this.suppressSync=!0,this.digits.forEach((e,n)=>{e.value=r[n]||"",e.disabled=s,e.readOnly=a,e.type=this.hasAttribute("masked")?"password":"text",e.classList.toggle(`${t}__digit--filled`,Boolean(e.value)),e.setAttribute("aria-invalid",String(i)),i&&l?e.setAttribute("aria-describedby",this.errorEl?.id||""):e.removeAttribute("aria-describedby")}),this.suppressSync=!1,this.errorEl&&(this.errorEl.textContent=l,this.errorEl.hidden=!i||!l),this.setAttribute("role","group"),this.setAttribute("aria-disabled",String(s)),this.setAttribute("aria-invalid",String(i)),this.syncFormValue(r)}emit(t){const e=this.digits.map(t=>t.value).join("");if(this.setValueAttribute(e),this.dispatchEvent(new CustomEvent(t,{detail:{value:e},bubbles:!0,composed:!0})),"db-change"===t&&e.length===this.length&&/^\d+$/.test(e)){if(e===this.lastCompleteValue)return;this.lastCompleteValue=e,this.dispatchEvent(new CustomEvent("db-complete",{detail:{value:e},bubbles:!0,composed:!0}))}else e.length!==this.length&&(this.lastCompleteValue="")}setValueAttribute(t){this.getAttribute("value")!==t&&this.setAttribute("value",t),this.syncFormValue(t)}syncFormValue(t){this.internals?.setFormValue(t||null),this.internals&&(this.hasAttribute("error")?this.internals.setValidity({customError:!0},this.getAttribute("error-message")||"인증 코드가 올바르지 않습니다.",this.digits[0]):this.hasAttribute("required")&&t.length!==this.length?this.internals.setValidity({valueMissing:!0},"인증 코드를 모두 입력해 주세요.",this.digits.find(t=>!t.value)||this.digits[0]):this.internals.setValidity({}))}focusFirstEmpty(){const t=this.digits.find(t=>!t.value)||this.digits[this.digits.length-1];t?.focus(),t?.select()}focusAt(t){const e=this.digits[Math.max(0,Math.min(this.digits.length-1,t))];e?.focus(),e?.select()}applyValue(t,e){const i=t.replace(/\D/g,"").slice(0,this.length);this.suppressSync=!0,this.digits.forEach((t,e)=>{t.value=i[e]||"",t.classList.toggle("designbase-wc-otp-input__digit--filled",Boolean(t.value))}),this.suppressSync=!1,this.emit("db-input"),this.emit("db-change"),void 0!==e?this.focusAt(e):i.length<this.length?this.focusAt(i.length):this.focusAt(this.length-1)}}DbOtpInput.formAssociated=!0,customElements.get("db-otp-input")||customElements.define("db-otp-input",DbOtpInput);export{DbOtpInput};
@@ -1 +1 @@
1
- const e=["default","minimal"],t=["center","left"];class DbPageHeader extends HTMLElement{constructor(){super(...arguments),this.internalTabId="",this.isRendering=!1,this.handleBack=()=>{const e=new CustomEvent("db-back",{bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(e),e.defaultPrevented||function navigatePageHeaderBack(e="/"){if("undefined"==typeof window)return;const t=window.history.state?.idx;if("number"==typeof t&&t>0)return void window.history.back();(()=>{try{return!!document.referrer&&new URL(document.referrer).origin===window.location.origin}catch{return!1}})()||window.history.length>1?window.history.back():window.location.assign(e)}(this.getAttribute("back-fallback-href")||"/")},this.handleTabChange=e=>{const t=e.detail,a=t?.selectedId??this.parseTabs()[t?.index??0]?.id??String(t?.index??0);this.hasAttribute("selected-tab-id")||(this.internalTabId=a),this.dispatchEvent(new CustomEvent("db-tab-change",{bubbles:!0,composed:!0,detail:{tabId:a}}))}}static get observedAttributes(){return["title","subtitle","description","breadcrumbs","variant","show-back-button","back-fallback-href","back-label","tabs","selected-tab-id","default-selected-tab-id","align"]}connectedCallback(){this.syncDefaultTab(),this.render(),this.childObserver=new MutationObserver(()=>{this.isRendering||this.hasPendingSlottedChildren()&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.childObserver?.disconnect()}attributeChangedCallback(e){this.isConnected&&("default-selected-tab-id"!==e&&"tabs"!==e||this.syncDefaultTab(),this.render())}hasPendingSlottedChildren(){return Array.from(this.children).some(e=>{const t=e.getAttribute("slot");return"actions"===t||"meta"===t||"description"===t})}syncDefaultTab(){if(this.internalTabId)return;const e=this.parseTabs(),t=this.getAttribute("default-selected-tab-id");this.internalTabId=t||e[0]?.id||""}parseTabs(){try{const e=JSON.parse(this.getAttribute("tabs")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBreadcrumbs(){try{const e=JSON.parse(this.getAttribute("breadcrumbs")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}getActiveTabId(){return this.getAttribute("selected-tab-id")||this.internalTabId}getVariant(){const t=this.getAttribute("variant")||"default";return e.includes(t)?t:"default"}getAlign(){const e=this.getAttribute("align")||"center";return t.includes(e)?e:"center"}collectActions(){const e=Array.from(this.querySelectorAll(':scope > [slot="actions"]'));if(e.length)return e;const t=this.querySelector(".designbase-wc-page-header__cta");if(t?.children.length)return Array.from(t.children);const a=this.querySelector(".designbase-wc-page-header__actions");return a?.children.length?Array.from(a.children):[]}collectMeta(){const e=Array.from(this.querySelectorAll(':scope > [slot="meta"]'));if(e.length)return e;const t=this.querySelector(".designbase-wc-page-header__meta");return t?.children.length?Array.from(t.children):[]}renderMinimalAside(e,t){if(!e.length&&!t.length)return null;const a=document.createElement("div");if(a.className="designbase-wc-page-header__aside",e.length){const t=document.createElement("div");t.className="designbase-wc-page-header__meta",e.forEach(e=>t.append(e)),a.append(t)}if(t.length){const e=document.createElement("div");e.className="designbase-wc-page-header__cta",t.forEach(t=>e.append(t)),a.append(e)}return a}collectDescriptionSlot(){const e=this.querySelector(':scope > [slot="description"]');if(e)return e;const t=this.querySelector(":scope .designbase-wc-page-header__description"),a=t?.firstElementChild;return a||null}renderTitleBlock(e){const t=document.createDocumentFragment(),a=this.getAttribute("title")||"",n=this.getAttribute("subtitle"),s=document.createElement("h1");if(s.className="designbase-wc-page-header__title",s.textContent=a,t.append(s),n){const e=document.createElement("h2");e.className="designbase-wc-page-header__subtitle",e.textContent=n,t.append(e)}const i=this.getAttribute("description");if(e||i){const a=document.createElement("div");a.className="designbase-wc-page-header__description",e?a.append(e):a.textContent=i,t.append(a)}return t}render(){this.isRendering=!0;const e=this.collectActions(),t=this.collectMeta(),a=this.collectDescriptionSlot(),n="minimal"===this.getVariant(),s=this.getAlign(),i=this.parseBreadcrumbs(),r=this.parseTabs(),c=r.length>0,d=this.hasAttribute("show-back-button");if(this.className=["designbase-wc-page-header",n?"designbase-wc-page-header--minimal":`designbase-wc-page-header--${s}`,n&&c?"designbase-wc-page-header--has-tabs":""].filter(Boolean).join(" "),this.replaceChildren(),i.length){const e=document.createElement("div");e.className="designbase-wc-page-header__breadcrumbs";const t=document.createElement("db-breadcrumbs");t.setAttribute("size","s"),t.setAttribute("items",JSON.stringify(i)),e.append(t),this.append(e)}const l=document.createElement("div");l.className="designbase-wc-page-header__main";const o=document.createElement("div");if(o.className="designbase-wc-page-header__content",n&&d){const e=document.createElement("div");e.className="designbase-wc-page-header__title-row";const t=document.createElement("db-button");t.className="designbase-wc-page-header__back-button",t.setAttribute("variant","tertiary"),t.setAttribute("size","m"),t.setAttribute("icon-only",""),t.setAttribute("start-icon","chevron-left"),t.setAttribute("aria-label",this.getAttribute("back-label")||"뒤로가기"),t.setAttribute("tooltip",this.getAttribute("back-label")||"뒤로가기"),t.addEventListener("db-click",this.handleBack),e.append(t);const n=document.createElement("div");n.className="designbase-wc-page-header__title-group",n.append(this.renderTitleBlock(a)),e.append(n),o.append(e)}else o.append(this.renderTitleBlock(a));if(l.append(o),n){const a=this.renderMinimalAside(t,e);a&&l.append(a)}if(this.append(l),!n&&e.length){const t=document.createElement("div");t.className="designbase-wc-page-header__actions",e.forEach(e=>t.append(e)),this.append(t)}this.renderMinimalTabs(n,c,r),queueMicrotask(()=>{this.isRendering=!1})}renderMinimalTabs(e,t,a){if(!e||!t)return;const n=document.createElement("div");n.className="designbase-wc-page-header__toolbar";const s=document.createElement("div");s.className="designbase-wc-page-header__tabs";const i=document.createElement("db-tabs");i.setAttribute("size","m"),i.setAttribute("items",JSON.stringify(a)),i.setAttribute("selected-id",this.getActiveTabId()),i.addEventListener("db-change",this.handleTabChange),s.append(i),n.append(s),this.append(n)}}customElements.get("db-page-header")||customElements.define("db-page-header",DbPageHeader);export{DbPageHeader};
1
+ import{PAGE_HEADER_VARIANTS as e,PAGE_HEADER_ALIGNS as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbPageHeader extends HTMLElement{constructor(){super(...arguments),this.internalTabId="",this.isRendering=!1,this.handleBack=()=>{const e=new CustomEvent("db-back",{bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(e),e.defaultPrevented||function navigatePageHeaderBack(e="/"){if("undefined"==typeof window)return;const t=window.history.state?.idx;if("number"==typeof t&&t>0)return void window.history.back();(()=>{try{return!!document.referrer&&new URL(document.referrer).origin===window.location.origin}catch{return!1}})()||window.history.length>1?window.history.back():window.location.assign(e)}(this.getAttribute("back-fallback-href")||"/")},this.handleTabChange=e=>{const t=e.detail,a=t?.selectedId??this.parseTabs()[t?.index??0]?.id??String(t?.index??0);this.hasAttribute("selected-tab-id")||(this.internalTabId=a),this.dispatchEvent(new CustomEvent("db-tab-change",{bubbles:!0,composed:!0,detail:{tabId:a}}))}}static get observedAttributes(){return["title","subtitle","description","breadcrumbs","variant","show-back-button","back-fallback-href","back-label","tabs","selected-tab-id","default-selected-tab-id","align"]}connectedCallback(){this.syncDefaultTab(),this.render(),this.childObserver=new MutationObserver(()=>{this.isRendering||this.hasPendingSlottedChildren()&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.childObserver?.disconnect()}attributeChangedCallback(e){this.isConnected&&("default-selected-tab-id"!==e&&"tabs"!==e||this.syncDefaultTab(),this.render())}hasPendingSlottedChildren(){return Array.from(this.children).some(e=>{const t=e.getAttribute("slot");return"actions"===t||"meta"===t||"description"===t})}syncDefaultTab(){if(this.internalTabId)return;const e=this.parseTabs(),t=this.getAttribute("default-selected-tab-id");this.internalTabId=t||e[0]?.id||""}parseTabs(){try{const e=JSON.parse(this.getAttribute("tabs")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBreadcrumbs(){try{const e=JSON.parse(this.getAttribute("breadcrumbs")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}getActiveTabId(){return this.getAttribute("selected-tab-id")||this.internalTabId}getVariant(){const t=this.getAttribute("variant")||"default";return e.includes(t)?t:"default"}getAlign(){const e=this.getAttribute("align")||"center";return t.includes(e)?e:"center"}collectActions(){const e=Array.from(this.querySelectorAll(':scope > [slot="actions"]'));if(e.length)return e;const t=this.querySelector(".designbase-wc-page-header__cta");if(t?.children.length)return Array.from(t.children);const a=this.querySelector(".designbase-wc-page-header__actions");return a?.children.length?Array.from(a.children):[]}collectMeta(){const e=Array.from(this.querySelectorAll(':scope > [slot="meta"]'));if(e.length)return e;const t=this.querySelector(".designbase-wc-page-header__meta");return t?.children.length?Array.from(t.children):[]}renderMinimalAside(e,t){if(!e.length&&!t.length)return null;const a=document.createElement("div");if(a.className="designbase-wc-page-header__aside",e.length){const t=document.createElement("div");t.className="designbase-wc-page-header__meta",e.forEach(e=>t.append(e)),a.append(t)}if(t.length){const e=document.createElement("div");e.className="designbase-wc-page-header__cta",t.forEach(t=>e.append(t)),a.append(e)}return a}collectDescriptionSlot(){const e=this.querySelector(':scope > [slot="description"]');if(e)return e;const t=this.querySelector(":scope .designbase-wc-page-header__description"),a=t?.firstElementChild;return a||null}renderTitleBlock(e){const t=document.createDocumentFragment(),a=this.getAttribute("title")||"",s=this.getAttribute("subtitle"),n=document.createElement("h1");if(n.className="designbase-wc-page-header__title",n.textContent=a,t.append(n),s){const e=document.createElement("h2");e.className="designbase-wc-page-header__subtitle",e.textContent=s,t.append(e)}const i=this.getAttribute("description");if(e||i){const a=document.createElement("div");a.className="designbase-wc-page-header__description",e?a.append(e):a.textContent=i,t.append(a)}return t}render(){this.isRendering=!0;const e=this.collectActions(),t=this.collectMeta(),a=this.collectDescriptionSlot(),s="minimal"===this.getVariant(),n=this.getAlign(),i=this.parseBreadcrumbs(),r=this.parseTabs(),c=r.length>0,d=this.hasAttribute("show-back-button");if(this.className=["designbase-wc-page-header",s?"designbase-wc-page-header--minimal":`designbase-wc-page-header--${n}`,s&&c?"designbase-wc-page-header--has-tabs":""].filter(Boolean).join(" "),this.replaceChildren(),i.length){const e=document.createElement("div");e.className="designbase-wc-page-header__breadcrumbs";const t=document.createElement("db-breadcrumbs");t.setAttribute("size","s"),t.setAttribute("items",JSON.stringify(i)),e.append(t),this.append(e)}const l=document.createElement("div");l.className="designbase-wc-page-header__main";const o=document.createElement("div");if(o.className="designbase-wc-page-header__content",s&&d){const e=document.createElement("div");e.className="designbase-wc-page-header__title-row";const t=document.createElement("db-button");t.className="designbase-wc-page-header__back-button",t.setAttribute("variant","tertiary"),t.setAttribute("size","m"),t.setAttribute("icon-only",""),t.setAttribute("start-icon","chevron-left"),t.setAttribute("aria-label",this.getAttribute("back-label")||"뒤로가기"),t.setAttribute("tooltip",this.getAttribute("back-label")||"뒤로가기"),t.addEventListener("db-click",this.handleBack),e.append(t);const s=document.createElement("div");s.className="designbase-wc-page-header__title-group",s.append(this.renderTitleBlock(a)),e.append(s),o.append(e)}else o.append(this.renderTitleBlock(a));if(l.append(o),s){const a=this.renderMinimalAside(t,e);a&&l.append(a)}if(this.append(l),!s&&e.length){const t=document.createElement("div");t.className="designbase-wc-page-header__actions",e.forEach(e=>t.append(e)),this.append(t)}this.renderMinimalTabs(s,c,r),queueMicrotask(()=>{this.isRendering=!1})}renderMinimalTabs(e,t,a){if(!e||!t)return;const s=document.createElement("div");s.className="designbase-wc-page-header__toolbar";const n=document.createElement("div");n.className="designbase-wc-page-header__tabs";const i=document.createElement("db-tabs");i.setAttribute("size","m"),i.setAttribute("items",JSON.stringify(a)),i.setAttribute("selected-id",this.getActiveTabId()),i.addEventListener("db-change",this.handleTabChange),n.append(i),s.append(n),this.append(s)}}customElements.get("db-page-header")||customElements.define("db-page-header",DbPageHeader);export{DbPageHeader};
@@ -2,6 +2,7 @@ import './db-button.js';
2
2
  import './db-input.js';
3
3
  import './db-otp-input.js';
4
4
  import './db-select.js';
5
+ import { PHONE_VERIFY_SIZES } from '@designbasekorea/ui-contracts';
5
6
 
6
7
  /**
7
8
  * ui-wc — db-phone-verify (수동 작성, 자동 동기화 대상 아님)
@@ -9,8 +10,7 @@ import './db-select.js';
9
10
  * 한국형 휴대폰 본인인증: 통신사 → 번호 → 인증번호 발송 → OTP + 타이머/재전송.
10
11
  */
11
12
 
12
- declare const SIZES: readonly ["s", "m", "l"];
13
- type Size = (typeof SIZES)[number];
13
+ type Size = (typeof PHONE_VERIFY_SIZES)[number];
14
14
  declare class DbPhoneVerify extends HTMLElement {
15
15
  static get observedAttributes(): string[];
16
16
  private built;
@@ -1 +1 @@
1
- import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import"./db-select.js";const t=[{value:"skt",label:"SKT"},{value:"kt",label:"KT"},{value:"lgu",label:"LG U+"},{value:"mvno",label:"알뜰폰"}],e=["s","m","l"];function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}function formatPhone(t){const e=t.replace(/\D/g,"").slice(0,11);return e.length<=3?e:e.length<=7?`${e.slice(0,3)}-${e.slice(3)}`:`${e.slice(0,3)}-${e.slice(3,7)}-${e.slice(7)}`}class DbPhoneVerify extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0}static get observedAttributes(){return["carrier","phone","code","step","size","disabled","error","error-message","carrier-options","countdown","title","description","send-label","resend-label","verify-label","code-length","manual","sending","verifying","auto-submit"]}get size(){return function pick(t,e,i){return t.includes(e)?e:i}(e,this.getAttribute("size"),"m")}set size(t){this.setAttribute("size",t)}get step(){const t=this.getAttribute("step");return"code"===t||"verified"===t?t:"phone"}set step(t){this.setAttribute("step",t)}get phone(){return(this.getAttribute("phone")||"").replace(/\D/g,"")}set phone(t){this.setAttribute("phone",formatPhone(t))}get carrier(){return this.getAttribute("carrier")||"skt"}set carrier(t){this.setAttribute("carrier",t)}get code(){return this.getAttribute("code")||""}set code(t){this.setAttribute("code",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}connectedCallback(){this.build(),this.sync(),"code"===this.step&&this.startTimer(this.countdown)}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&(this.sync(),"step"===t&&e!==i&&("code"===this.step?this.startTimer(this.countdown):this.clearTimer()))}startCodeStep(){"code"===this.step?this.startTimer(this.countdown):this.step="code",requestAnimationFrame(()=>this.otpInput?.focus?.())}restartCountdown(){"code"===this.step&&this.startTimer(this.countdown)}markVerified(){this.step="verified",this.clearTimer()}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0}startTimer(t){this.clearTimer(),this.remaining=t,this.renderTimer(),this.timerId=setInterval(()=>{this.remaining-=1,this.renderTimer(),this.remaining<=0&&(this.clearTimer(),this.resendBtn.disabled=!1,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))},1e3)}renderTimer(){const t=Math.max(0,Math.floor(this.remaining/60)),e=Math.max(0,this.remaining%60);this.timerEl.textContent=`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")}`,this.timerEl.setAttribute("aria-label",`남은 시간 ${t}분 ${e}초`),this.resendBtn.disabled=this.remaining>0||this.hasAttribute("disabled")}build(){if(this.built)return;this.built=!0;const t="designbase-wc-phone-verify";this.replaceChildren();const e=el("div",`${t}__header`),i=el("h3",`${t}__title`);i.dataset.role="title";const s=el("p",`${t}__description`);s.dataset.role="description",e.append(i,s);const r=el("div",`${t}__field`);this.carrierSelect=document.createElement("db-select"),this.carrierSelect.setAttribute("label","통신사"),this.carrierSelect.setAttribute("full-width",""),this.carrierSelect.setAttribute("placeholder","통신사 선택"),this.carrierSelect.addEventListener("db-change",t=>{t.stopPropagation();const e=t.detail?.value??this.carrierSelect.value;this.carrier=String(e||""),this.dispatchEvent(new CustomEvent("db-carrier-change",{detail:{carrier:this.carrier},bubbles:!0,composed:!0}))}),r.append(this.carrierSelect);const n=el("div",`${t}__phone-row`);this.phoneInput=document.createElement("db-input"),this.phoneInput.setAttribute("type","tel"),this.phoneInput.setAttribute("label","휴대폰 번호"),this.phoneInput.setAttribute("placeholder","010-0000-0000"),this.phoneInput.setAttribute("full-width",""),this.phoneInput.setAttribute("start-icon","user"),this.phoneInput.addEventListener("db-input",t=>{t.stopPropagation();const e=formatPhone(String(t.detail?.value??this.phoneInput.value??""));this.phoneInput.value=e,this.setAttribute("phone",e),this.dispatchEvent(new CustomEvent("db-phone-change",{detail:{phone:e.replace(/\D/g,""),formatted:e},bubbles:!0,composed:!0}))}),this.sendBtn=document.createElement("db-button"),this.sendBtn.setAttribute("variant","primary"),this.sendBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.isPhoneValid()&&(this.dispatchEvent(new CustomEvent("db-send-code",{detail:{carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("manual")||this.startCodeStep())}),n.append(this.phoneInput,this.sendBtn),this.codeBlock=el("div",`${t}__code`);const o=el("div",`${t}__code-head`),h=el("span",`${t}__code-label`);h.textContent="인증번호",this.timerEl=el("span",`${t}__timer`),o.append(h,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:e},bubbles:!0,composed:!0}))}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.dispatchEvent(new CustomEvent("db-code-complete",{detail:{code:e,carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("auto-submit")&&this.requestVerify()});const a=el("div",`${t}__code-actions`);this.resendBtn=el("button",`${t}__resend`),this.resendBtn.type="button",this.resendBtn.addEventListener("click",()=>{this.resendBtn.disabled||(this.dispatchEvent(new CustomEvent("db-resend",{detail:{carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("manual")||this.startTimer(this.countdown))}),this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),a.append(this.resendBtn,this.verifyBtn),this.codeBlock.append(o,this.otpInput,a),this.errorEl=el("p",`${t}__error`),this.errorEl.hidden=!0;const d=el("div",`${t}__verified`);d.dataset.role="verified",d.innerHTML=`<span class="${t}__verified-badge">인증 완료</span><p class="${t}__verified-text">휴대폰 번호 인증이 완료되었습니다.</p>`,this.append(e,r,n,this.codeBlock,this.errorEl,d)}sync(){const e="designbase-wc-phone-verify",i=this.size,s=this.step,r=this.hasAttribute("disabled"),n=function parseCarriers(e){if(!e)return t;try{const i=JSON.parse(e);return Array.isArray(i)&&i.length?i:t}catch{return t}}(this.getAttribute("carrier-options")),o=this.getAttribute("code-length")||"6";this.className=[e,`${e}--${i}`,`${e}--step-${s}`,r&&`${e}--disabled`,this.hasAttribute("error")&&`${e}--error`].filter(Boolean).join(" ");const h=this.querySelector('[data-role="title"]'),a=this.querySelector('[data-role="description"]');h.textContent=this.getAttribute("title")||"휴대폰 인증",a.textContent=this.getAttribute("description")||"본인 명의의 휴대폰 번호를 입력하고 인증번호를 받아 주세요.",this.carrierSelect.setAttribute("options",JSON.stringify(n)),this.carrierSelect.setAttribute("value",this.carrier),this.carrierSelect.setAttribute("size",i),this.carrierSelect.toggleAttribute("disabled",r||"verified"===s);const d=this.getAttribute("phone")||"";this.phoneInput.value=d,this.phoneInput.setAttribute("size",i),this.phoneInput.toggleAttribute("disabled",r||"phone"!==s),this.phoneInput.toggleAttribute("error",this.hasAttribute("error")&&"phone"===s),this.sendBtn.setAttribute("size",i),this.sendBtn.textContent=this.getAttribute("send-label")||"인증번호 받기",this.sendBtn.toggleAttribute("disabled",r||"phone"!==s||!this.isPhoneValid()),this.sendBtn.toggleAttribute("loading",this.hasAttribute("sending")),this.otpInput.setAttribute("length",o),this.otpInput.setAttribute("size",i),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",r||"code"!==s),this.otpInput.toggleAttribute("error",this.hasAttribute("error")&&"code"===s),this.resendBtn.textContent=this.getAttribute("resend-label")||"재전송",this.verifyBtn.setAttribute("size",i),this.verifyBtn.textContent=this.getAttribute("verify-label")||"인증하기",this.verifyBtn.toggleAttribute("disabled",r||(this.getAttribute("code")||"").length<Number(o)),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.codeBlock.hidden="phone"===s;this.querySelector('[data-role="verified"]').hidden="verified"!==s;const l=this.getAttribute("error-message")||"";this.errorEl.textContent=l,this.errorEl.hidden=!this.hasAttribute("error")||!l}isPhoneValid(){return/^01[016789]\d{7,8}$/.test(this.phone)&&Boolean(this.carrier)}requestVerify(){const t=(this.code||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);"code"!==this.step||t.length!==e||this.hasAttribute("disabled")||this.dispatchEvent(new CustomEvent("db-verify",{detail:{carrier:this.carrier,phone:this.phone,code:t},bubbles:!0,composed:!0}))}}customElements.get("db-phone-verify")||customElements.define("db-phone-verify",DbPhoneVerify);export{DbPhoneVerify};
1
+ import{t}from"../core/i18n.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import"./db-select.js";import{PHONE_VERIFY_SIZES as e}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const i=[{value:"skt",label:"SKT"},{value:"kt",label:"KT"},{value:"lgu",label:"LG U+"},{value:"mvno",label:"알뜰폰"}];function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}function formatPhone(t){const e=t.replace(/\D/g,"").slice(0,11);return e.length<=3?e:e.length<=7?`${e.slice(0,3)}-${e.slice(3)}`:`${e.slice(0,3)}-${e.slice(3,7)}-${e.slice(7)}`}class DbPhoneVerify extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0}static get observedAttributes(){return["carrier","phone","code","step","size","disabled","error","error-message","carrier-options","countdown","title","description","send-label","resend-label","verify-label","code-length","manual","sending","verifying","auto-submit"]}get size(){return function pick(t,e,i){return t.includes(e)?e:i}(e,this.getAttribute("size"),"m")}set size(t){this.setAttribute("size",t)}get step(){const t=this.getAttribute("step");return"code"===t||"verified"===t?t:"phone"}set step(t){this.setAttribute("step",t)}get phone(){return(this.getAttribute("phone")||"").replace(/\D/g,"")}set phone(t){this.setAttribute("phone",formatPhone(t))}get carrier(){return this.getAttribute("carrier")||"skt"}set carrier(t){this.setAttribute("carrier",t)}get code(){return this.getAttribute("code")||""}set code(t){this.setAttribute("code",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}connectedCallback(){this.build(),this.sync(),"code"===this.step&&this.startTimer(this.countdown)}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&(this.sync(),"step"===t&&e!==i&&("code"===this.step?this.startTimer(this.countdown):this.clearTimer()))}startCodeStep(){"code"===this.step?this.startTimer(this.countdown):this.step="code",requestAnimationFrame(()=>this.otpInput?.focus?.())}restartCountdown(){"code"===this.step&&this.startTimer(this.countdown)}markVerified(){this.step="verified",this.clearTimer()}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0}startTimer(t){this.clearTimer(),this.remaining=t,this.renderTimer(),this.timerId=setInterval(()=>{this.remaining-=1,this.renderTimer(),this.remaining<=0&&(this.clearTimer(),this.resendBtn.disabled=!1,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))},1e3)}renderTimer(){const t=Math.max(0,Math.floor(this.remaining/60)),e=Math.max(0,this.remaining%60);this.timerEl.textContent=`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")}`,this.timerEl.setAttribute("aria-label",`남은 시간 ${t}분 ${e}초`),this.resendBtn.disabled=this.remaining>0||this.hasAttribute("disabled")}build(){if(this.built)return;this.built=!0;const e="designbase-wc-phone-verify";this.replaceChildren();const i=el("div",`${e}__header`),s=el("h3",`${e}__title`);s.dataset.role="title";const r=el("p",`${e}__description`);r.dataset.role="description",i.append(s,r);const n=el("div",`${e}__field`);this.carrierSelect=document.createElement("db-select"),this.carrierSelect.setAttribute("label","통신사"),this.carrierSelect.setAttribute("full-width",""),this.carrierSelect.setAttribute("placeholder","통신사 선택"),this.carrierSelect.addEventListener("db-change",t=>{t.stopPropagation();const e=t.detail?.value??this.carrierSelect.value;this.carrier=String(e||""),this.dispatchEvent(new CustomEvent("db-carrier-change",{detail:{carrier:this.carrier},bubbles:!0,composed:!0}))}),n.append(this.carrierSelect);const o=el("div",`${e}__phone-row`);this.phoneInput=document.createElement("db-input"),this.phoneInput.setAttribute("type","tel"),this.phoneInput.setAttribute("label","휴대폰 번호"),this.phoneInput.setAttribute("placeholder","010-0000-0000"),this.phoneInput.setAttribute("full-width",""),this.phoneInput.setAttribute("start-icon","user"),this.phoneInput.addEventListener("db-input",t=>{t.stopPropagation();const e=formatPhone(String(t.detail?.value??this.phoneInput.value??""));this.phoneInput.value=e,this.setAttribute("phone",e),this.dispatchEvent(new CustomEvent("db-phone-change",{detail:{phone:e.replace(/\D/g,""),formatted:e},bubbles:!0,composed:!0}))}),this.sendBtn=document.createElement("db-button"),this.sendBtn.setAttribute("variant","primary"),this.sendBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.isPhoneValid()&&(this.dispatchEvent(new CustomEvent("db-send-code",{detail:{carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("manual")||this.startCodeStep())}),o.append(this.phoneInput,this.sendBtn),this.codeBlock=el("div",`${e}__code`);const h=el("div",`${e}__code-head`),a=el("span",`${e}__code-label`);a.textContent="인증번호",this.timerEl=el("span",`${e}__timer`),h.append(a,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:e},bubbles:!0,composed:!0}))}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.dispatchEvent(new CustomEvent("db-code-complete",{detail:{code:e,carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("auto-submit")&&this.requestVerify()});const d=el("div",`${e}__code-actions`);this.resendBtn=el("button",`${e}__resend`),this.resendBtn.type="button",this.resendBtn.addEventListener("click",()=>{this.resendBtn.disabled||(this.dispatchEvent(new CustomEvent("db-resend",{detail:{carrier:this.carrier,phone:this.phone},bubbles:!0,composed:!0})),this.hasAttribute("manual")||this.startTimer(this.countdown))}),this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),d.append(this.resendBtn,this.verifyBtn),this.codeBlock.append(h,this.otpInput,d),this.errorEl=el("p",`${e}__error`),this.errorEl.hidden=!0;const l=el("div",`${e}__verified`);l.dataset.role="verified";const c=el("span",`${e}__verified-badge`);c.textContent=t("verify.done");const u=document.createElement("p");u.className=`${e}__verified-text`,u.textContent=t("verify.phoneDone"),l.append(c,u),this.append(i,n,o,this.codeBlock,this.errorEl,l)}sync(){const t="designbase-wc-phone-verify",e=this.size,s=this.step,r=this.hasAttribute("disabled"),n=function parseCarriers(t){if(!t)return i;try{const e=JSON.parse(t);return Array.isArray(e)&&e.length?e:i}catch{return i}}(this.getAttribute("carrier-options")),o=this.getAttribute("code-length")||"6";this.className=[t,`${t}--${e}`,`${t}--step-${s}`,r&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" ");const h=this.querySelector('[data-role="title"]'),a=this.querySelector('[data-role="description"]');h.textContent=this.getAttribute("title")||"휴대폰 인증",a.textContent=this.getAttribute("description")||"본인 명의의 휴대폰 번호를 입력하고 인증번호를 받아 주세요.",this.carrierSelect.setAttribute("options",JSON.stringify(n)),this.carrierSelect.setAttribute("value",this.carrier),this.carrierSelect.setAttribute("size",e),this.carrierSelect.toggleAttribute("disabled",r||"verified"===s);const d=this.getAttribute("phone")||"";this.phoneInput.value=d,this.phoneInput.setAttribute("size",e),this.phoneInput.toggleAttribute("disabled",r||"phone"!==s),this.phoneInput.toggleAttribute("error",this.hasAttribute("error")&&"phone"===s),this.sendBtn.setAttribute("size",e),this.sendBtn.textContent=this.getAttribute("send-label")||"인증번호 받기",this.sendBtn.toggleAttribute("disabled",r||"phone"!==s||!this.isPhoneValid()),this.sendBtn.toggleAttribute("loading",this.hasAttribute("sending")),this.otpInput.setAttribute("length",o),this.otpInput.setAttribute("size",e),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",r||"code"!==s),this.otpInput.toggleAttribute("error",this.hasAttribute("error")&&"code"===s),this.resendBtn.textContent=this.getAttribute("resend-label")||"재전송",this.verifyBtn.setAttribute("size",e),this.verifyBtn.textContent=this.getAttribute("verify-label")||"인증하기",this.verifyBtn.toggleAttribute("disabled",r||(this.getAttribute("code")||"").length<Number(o)),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.codeBlock.hidden="phone"===s;this.querySelector('[data-role="verified"]').hidden="verified"!==s;const l=this.getAttribute("error-message")||"";this.errorEl.textContent=l,this.errorEl.hidden=!this.hasAttribute("error")||!l}isPhoneValid(){return/^01[016789]\d{7,8}$/.test(this.phone)&&Boolean(this.carrier)}requestVerify(){const t=(this.code||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);"code"!==this.step||t.length!==e||this.hasAttribute("disabled")||this.dispatchEvent(new CustomEvent("db-verify",{detail:{carrier:this.carrier,phone:this.phone,code:t},bubbles:!0,composed:!0}))}}customElements.get("db-phone-verify")||customElements.define("db-phone-verify",DbPhoneVerify);export{DbPhoneVerify};
@@ -1 +1 @@
1
- const e=["top","bottom","left","right","top-start","top-end","bottom-start","bottom-end","left-start","left-end","right-start","right-end"],t=["click","hover","focus","manual"];class DbPopover extends HTMLElement{constructor(){super(...arguments),this.onDocMouseDown=null,this.onDocKeyDown=null,this.onExternalTriggerClick=null,this.handleTriggerClick=e=>{"click"===this.resolvedTrigger()&&(e.preventDefault(),e.stopPropagation(),this.setOpen(!this.isOpen()))},this.handleTriggerMouseEnter=()=>{"hover"===this.resolvedTrigger()&&this.scheduleOpen()},this.handleTriggerMouseLeave=()=>{"hover"===this.resolvedTrigger()&&this.scheduleClose()},this.handleTriggerFocus=()=>{"focus"===this.resolvedTrigger()&&this.scheduleOpen()},this.handleTriggerBlur=()=>{"focus"===this.resolvedTrigger()&&this.scheduleClose()},this.handleReposition=()=>{this.isOpen()&&(this.repositionRaf&&cancelAnimationFrame(this.repositionRaf),this.repositionRaf=requestAnimationFrame(()=>{this.positionPanel(),this.repositionRaf=void 0}))}}static get observedAttributes(){return["open","placement","position","title","content","size","variant","trigger","delay","hide-delay","always-show","disabled","max-width","show-arrow","close-on-outside-click","close-on-escape","trigger-id"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(e){e?this.setAttribute("open",""):this.removeAttribute("open")}connectedCallback(){this.classList.add("designbase-wc-popover-host"),this.hasAttribute("placement")||this.hasAttribute("position")||this.setAttribute("placement","top"),this.render(),this.childObserver=new MutationObserver(()=>this.render()),this.childObserver.observe(this,{childList:!0}),this.bindExternalTrigger(),this.attachGlobalListeners(),this.syncOpenFromAttributes()}disconnectedCallback(){this.childObserver?.disconnect(),this.clearTimers(),this.repositionRaf&&cancelAnimationFrame(this.repositionRaf),this.unbindExternalTrigger(),this.detachGlobalListeners(),this.removePanel()}attributeChangedCallback(e){this.isConnected&&("trigger-id"===e&&(this.unbindExternalTrigger(),this.bindExternalTrigger()),"open"!==e&&"always-show"!==e&&"disabled"!==e?("content"===e&&this.bodyEl&&(this.bodyEl.textContent=this.getAttribute("content")||""),this.isOpen()&&(this.updatePanelMetadata(),requestAnimationFrame(()=>this.positionPanel()))):this.syncOpenFromAttributes())}resolvedPlacement(){const t=this.getAttribute("position")||this.getAttribute("placement")||"top";return e.includes(t)?t:"top"}resolvedTrigger(){const e=this.getAttribute("trigger")||"click";return t.includes(e)?e:"click"}isControlled(){return this.hasAttribute("open")}isOpen(){return!this.hasAttribute("disabled")&&(!!this.hasAttribute("always-show")||(this.isControlled()?"false"!==this.getAttribute("open"):this.panel?.classList.contains("designbase-wc-popover--visible")??!1))}setOpen(e){this.hasAttribute("disabled")||this.hasAttribute("always-show")||(this.isControlled()?e?this.setAttribute("open",""):this.removeAttribute("open"):e?this.showPanel():this.hidePanel(),this.dispatchEvent(new CustomEvent("db-open-change",{bubbles:!0,composed:!0,detail:{open:e}})),e||this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))}syncOpenFromAttributes(){this.hasAttribute("always-show")?this.showPanel():this.isControlled()&&("false"!==this.getAttribute("open")?this.showPanel():this.hidePanel())}clearTimers(){this.showTimer&&clearTimeout(this.showTimer),this.hideTimer&&clearTimeout(this.hideTimer),this.showTimer=void 0,this.hideTimer=void 0}groupOf(e){return e.startsWith("top")?"top":e.startsWith("bottom")?"bottom":e.startsWith("left")?"left":"right"}collectTriggerChildren(){const isInternalNode=e=>e.hasAttribute("data-wc-internal")||e===this.triggerWrap,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[])}ensureTriggerWrap(){this.triggerWrap||(this.triggerWrap=document.createElement("span"),this.triggerWrap.className="designbase-wc-popover__trigger",this.triggerWrap.setAttribute("data-wc-internal",""),this.triggerWrap.tabIndex=0,this.triggerWrap.addEventListener("click",this.handleTriggerClick),this.triggerWrap.addEventListener("mouseenter",this.handleTriggerMouseEnter),this.triggerWrap.addEventListener("mouseleave",this.handleTriggerMouseLeave),this.triggerWrap.addEventListener("focus",this.handleTriggerFocus),this.triggerWrap.addEventListener("blur",this.handleTriggerBlur))}mountTriggerChildren(e){this.triggerWrap&&e.forEach(e=>{e.parentElement!==this.triggerWrap&&this.triggerWrap.append(e)})}collectBodyChildren(){return Array.from(this.querySelectorAll('[slot="content"]'))}bindExternalTrigger(){const e=this.getAttribute("trigger-id");e&&(this.triggerEl=document.getElementById(e),this.triggerEl&&(this.onExternalTriggerClick=()=>{"click"===this.resolvedTrigger()&&this.setOpen(!this.isOpen())},this.triggerEl.addEventListener("click",this.onExternalTriggerClick)))}unbindExternalTrigger(){this.triggerEl&&this.onExternalTriggerClick&&this.triggerEl.removeEventListener("click",this.onExternalTriggerClick),this.triggerEl=null,this.onExternalTriggerClick=null}attachGlobalListeners(){this.onDocMouseDown=e=>{if(!this.isOpen()||"false"===this.getAttribute("close-on-outside-click"))return;const t=e.target;this.panel?.contains(t)||this.triggerWrap?.contains(t)||this.triggerEl?.contains(t)||this.setOpen(!1)},this.onDocKeyDown=e=>{"Escape"===e.key&&this.isOpen()&&"false"!==this.getAttribute("close-on-escape")&&this.setOpen(!1)},document.addEventListener("mousedown",this.onDocMouseDown),document.addEventListener("keydown",this.onDocKeyDown)}detachGlobalListeners(){this.onDocMouseDown&&document.removeEventListener("mousedown",this.onDocMouseDown),this.onDocKeyDown&&document.removeEventListener("keydown",this.onDocKeyDown),this.onDocMouseDown=null,this.onDocKeyDown=null}scheduleOpen(){this.clearTimers();const e="hover"===this.resolvedTrigger()?Math.max(0,Number(this.getAttribute("delay")||0)):0;this.showTimer=setTimeout(()=>this.showPanel(),e)}scheduleClose(){this.clearTimers();const e="hover"===this.resolvedTrigger()?Math.max(0,Number(this.getAttribute("hide-delay")||80)):0;this.hideTimer=setTimeout(()=>this.setOpen(!1),e)}getTriggerRect(){const e=this.triggerEl||this.triggerWrap;return e?.getBoundingClientRect()}flipPlacementIfNeeded(e,t,i){const s=window.innerHeight,r=window.innerWidth,o=this.groupOf(e),n=t.top-i.height-8>=8,a=t.bottom+8+i.height<=s-8,h=t.left-i.width-8>=8,l=t.right+8+i.width<=r-8;return"top"===o&&!n&&a?e.replace(/^top/,"bottom"):"bottom"===o&&!a&&n?e.replace(/^bottom/,"top"):"left"===o&&!h&&l?e.replace(/^left/,"right"):"right"===o&&!l&&h?e.replace(/^right/,"left"):e}applyCoords(e,t,i){let s=0,r=0,o=0,n=0;const a=i.height,h=i.width,l=16;switch(e){case"top":s=t.top-i.height-8,r=t.left+t.width/2-i.width/2,o=a-5,n=h/2-5;break;case"top-start":s=t.top-i.height-8,r=t.left,o=a-5,n=11;break;case"top-end":s=t.top-i.height-8,r=t.right-i.width,o=a-5,n=h-l-5;break;case"bottom":s=t.bottom+8,r=t.left+t.width/2-i.width/2,o=-5,n=h/2-5;break;case"bottom-start":s=t.bottom+8,r=t.left,o=-5,n=11;break;case"bottom-end":s=t.bottom+8,r=t.right-i.width,o=-5,n=h-l-5;break;case"left":s=t.top+t.height/2-i.height/2,r=t.left-i.width-8,o=a/2-5,n=h-5;break;case"left-start":s=t.top,r=t.left-i.width-8,o=11,n=h-5;break;case"left-end":s=t.bottom-i.height,r=t.left-i.width-8,o=a-l-5,n=h-5;break;case"right":s=t.top+t.height/2-i.height/2,r=t.right+8,o=a/2-5,n=-5;break;case"right-start":s=t.top,r=t.right+8,o=11,n=-5;break;case"right-end":s=t.bottom-i.height,r=t.right+8,o=a-l-5,n=-5}const d=window.innerWidth,c=window.innerHeight;return r<8&&(r=8),r+i.width>d-8&&(r=d-i.width-8),s<8&&(s=8),s+i.height>c-8&&(s=c-i.height-8),{top:s,left:r,aTop:o,aLeft:n,placement:e}}positionPanel(){if(!this.panel)return;const t=this.getTriggerRect();if(!t)return;const i=Number(this.getAttribute("max-width")||300);this.panel.style.maxWidth=`${i}px`,this.panel.offsetHeight;const s=this.panel.getBoundingClientRect(),r=this.resolvedPlacement(),o=this.flipPlacementIfNeeded(r,t,s),{top:n,left:a,aTop:h,aLeft:l}=this.applyCoords(o,t,s);this.panel.style.top=`${n}px`,this.panel.style.left=`${a}px`,this.panel.dataset.placementGroup=this.groupOf(o),e.forEach(e=>{this.panel.classList.toggle(`designbase-wc-popover--${e}`,e===o)}),this.arrowEl&&(this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${o}`,this.arrowEl.style.top=`${h}px`,this.arrowEl.style.left=`${l}px`)}revealPanel(){this.panel&&(this.panel.classList.remove("designbase-wc-popover--visible"),this.positionPanel(),this.panel.offsetHeight,this.positionPanel(),this.panel.classList.add("designbase-wc-popover--visible"))}updatePanelMetadata(){if(!this.panel)return;const e=this.getAttribute("size")||"m",t=this.getAttribute("variant")||"default",i=this.resolvedPlacement();this.panel.className=["designbase-wc-popover",`designbase-wc-popover--${e}`,`designbase-wc-popover--${t}`,`designbase-wc-popover--${i}`,this.isOpen()?"designbase-wc-popover--visible":"",this.hasAttribute("disabled")?"designbase-wc-popover--disabled":""].filter(Boolean).join(" ")}ensurePanel(){if(this.panel)return;const e=document.createElement("div");e.className="designbase-wc-popover",e.setAttribute("data-wc-internal",""),e.setAttribute("role","dialog"),e.setAttribute("aria-modal","false"),e.style.position="fixed",e.style.zIndex="9999";const t=document.createElement("div");t.className="designbase-wc-popover__content";const i=document.createElement("div");i.className="designbase-wc-popover__header";const s=document.createElement("h3");s.className="designbase-wc-popover__title";const r=document.createElement("db-button");r.className="designbase-wc-popover__close-button",r.setAttribute("variant","ghost"),r.setAttribute("size","s"),r.setAttribute("icon-only",""),r.setAttribute("start-icon","close"),r.setAttribute("aria-label","팝오버 닫기"),r.addEventListener("db-click",e=>{e.stopPropagation(),this.setOpen(!1)}),i.append(s,r),this.bodyEl=document.createElement("div"),this.bodyEl.className="designbase-wc-popover__body",t.append(i,this.bodyEl),e.append(t),"false"!==this.getAttribute("show-arrow")&&(this.arrowEl=document.createElement("div"),this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${this.resolvedPlacement()}`,e.append(this.arrowEl)),this.panel=e,this.panel.querySelector(".designbase-wc-popover__title").textContent=this.getAttribute("title")||"",this.panel.querySelector(".designbase-wc-popover__title").hidden=!this.getAttribute("title"),document.body.append(e),e.addEventListener("mouseenter",()=>{"hover"===this.resolvedTrigger()&&this.clearTimers()}),e.addEventListener("mouseleave",()=>{"hover"===this.resolvedTrigger()&&this.scheduleClose()})}showPanel(){if(this.hasAttribute("disabled"))return;this.ensurePanel(),this.updatePanelMetadata();const e=this.collectBodyChildren();e.length>0?this.bodyEl.replaceChildren(...e.map(e=>e.cloneNode(!0))):this.bodyEl.textContent=this.getAttribute("content")||"";const t=this.panel.querySelector(".designbase-wc-popover__title");t.textContent=this.getAttribute("title")||"",t.hidden=!this.getAttribute("title"),requestAnimationFrame(()=>{this.revealPanel(),window.addEventListener("scroll",this.handleReposition,!0),window.addEventListener("resize",this.handleReposition)})}hidePanel(){this.panel?.classList.remove("designbase-wc-popover--visible"),window.removeEventListener("scroll",this.handleReposition,!0),window.removeEventListener("resize",this.handleReposition),this.hasAttribute("always-show")||this.removePanel()}removePanel(){this.panel?.remove(),this.panel=void 0,this.bodyEl=void 0,this.arrowEl=void 0}render(){this.ensureTriggerWrap();const e=this.collectTriggerChildren();this.mountTriggerChildren(e);const t=Boolean(this.getAttribute("trigger-id"));this.triggerWrap&&(e.length>0||!t?this.triggerWrap.parentElement!==this&&this.append(this.triggerWrap):this.triggerWrap.parentElement===this&&this.triggerWrap.remove()),this.hasAttribute("always-show")&&this.showPanel()}}customElements.get("db-popover")||customElements.define("db-popover",DbPopover);export{DbPopover};
1
+ import{POPOVER_PLACEMENTS as e,POPOVER_TRIGGERS as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbPopover extends HTMLElement{constructor(){super(...arguments),this.onDocMouseDown=null,this.onDocKeyDown=null,this.onExternalTriggerClick=null,this.handleTriggerClick=e=>{"click"===this.resolvedTrigger()&&(e.preventDefault(),e.stopPropagation(),this.setOpen(!this.isOpen()))},this.handleTriggerMouseEnter=()=>{"hover"===this.resolvedTrigger()&&this.scheduleOpen()},this.handleTriggerMouseLeave=()=>{"hover"===this.resolvedTrigger()&&this.scheduleClose()},this.handleTriggerFocus=()=>{"focus"===this.resolvedTrigger()&&this.scheduleOpen()},this.handleTriggerBlur=()=>{"focus"===this.resolvedTrigger()&&this.scheduleClose()},this.handleReposition=()=>{this.isOpen()&&(this.repositionRaf&&cancelAnimationFrame(this.repositionRaf),this.repositionRaf=requestAnimationFrame(()=>{this.positionPanel(),this.repositionRaf=void 0}))}}static get observedAttributes(){return["open","placement","position","title","content","size","variant","trigger","delay","hide-delay","always-show","disabled","max-width","show-arrow","close-on-outside-click","close-on-escape","trigger-id"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(e){e?this.setAttribute("open",""):this.removeAttribute("open")}connectedCallback(){this.classList.add("designbase-wc-popover-host"),this.hasAttribute("placement")||this.hasAttribute("position")||this.setAttribute("placement","top"),this.render(),this.childObserver=new MutationObserver(()=>this.render()),this.childObserver.observe(this,{childList:!0}),this.bindExternalTrigger(),this.attachGlobalListeners(),this.syncOpenFromAttributes()}disconnectedCallback(){this.childObserver?.disconnect(),this.clearTimers(),this.repositionRaf&&cancelAnimationFrame(this.repositionRaf),this.unbindExternalTrigger(),this.detachGlobalListeners(),this.removePanel()}attributeChangedCallback(e){this.isConnected&&("trigger-id"===e&&(this.unbindExternalTrigger(),this.bindExternalTrigger()),"open"!==e&&"always-show"!==e&&"disabled"!==e?("content"===e&&this.bodyEl&&(this.bodyEl.textContent=this.getAttribute("content")||""),this.isOpen()&&(this.updatePanelMetadata(),requestAnimationFrame(()=>this.positionPanel()))):this.syncOpenFromAttributes())}resolvedPlacement(){const t=this.getAttribute("position")||this.getAttribute("placement")||"top";return e.includes(t)?t:"top"}resolvedTrigger(){const e=this.getAttribute("trigger")||"click";return t.includes(e)?e:"click"}isControlled(){return this.hasAttribute("open")}isOpen(){return!this.hasAttribute("disabled")&&(!!this.hasAttribute("always-show")||(this.isControlled()?"false"!==this.getAttribute("open"):this.panel?.classList.contains("designbase-wc-popover--visible")??!1))}setOpen(e){this.hasAttribute("disabled")||this.hasAttribute("always-show")||(this.isControlled()?e?this.setAttribute("open",""):this.removeAttribute("open"):e?this.showPanel():this.hidePanel(),this.dispatchEvent(new CustomEvent("db-open-change",{bubbles:!0,composed:!0,detail:{open:e}})),e||this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))}syncOpenFromAttributes(){this.hasAttribute("always-show")?this.showPanel():this.isControlled()&&("false"!==this.getAttribute("open")?this.showPanel():this.hidePanel())}clearTimers(){this.showTimer&&clearTimeout(this.showTimer),this.hideTimer&&clearTimeout(this.hideTimer),this.showTimer=void 0,this.hideTimer=void 0}groupOf(e){return e.startsWith("top")?"top":e.startsWith("bottom")?"bottom":e.startsWith("left")?"left":"right"}collectTriggerChildren(){const isInternalNode=e=>e.hasAttribute("data-wc-internal")||e===this.triggerWrap,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[])}ensureTriggerWrap(){this.triggerWrap||(this.triggerWrap=document.createElement("span"),this.triggerWrap.className="designbase-wc-popover__trigger",this.triggerWrap.setAttribute("data-wc-internal",""),this.triggerWrap.tabIndex=0,this.triggerWrap.addEventListener("click",this.handleTriggerClick),this.triggerWrap.addEventListener("mouseenter",this.handleTriggerMouseEnter),this.triggerWrap.addEventListener("mouseleave",this.handleTriggerMouseLeave),this.triggerWrap.addEventListener("focus",this.handleTriggerFocus),this.triggerWrap.addEventListener("blur",this.handleTriggerBlur))}mountTriggerChildren(e){this.triggerWrap&&e.forEach(e=>{e.parentElement!==this.triggerWrap&&this.triggerWrap.append(e)})}collectBodyChildren(){return Array.from(this.querySelectorAll('[slot="content"]'))}bindExternalTrigger(){const e=this.getAttribute("trigger-id");e&&(this.triggerEl=document.getElementById(e),this.triggerEl&&(this.onExternalTriggerClick=()=>{"click"===this.resolvedTrigger()&&this.setOpen(!this.isOpen())},this.triggerEl.addEventListener("click",this.onExternalTriggerClick)))}unbindExternalTrigger(){this.triggerEl&&this.onExternalTriggerClick&&this.triggerEl.removeEventListener("click",this.onExternalTriggerClick),this.triggerEl=null,this.onExternalTriggerClick=null}attachGlobalListeners(){this.onDocMouseDown=e=>{if(!this.isOpen()||"false"===this.getAttribute("close-on-outside-click"))return;const t=e.target;this.panel?.contains(t)||this.triggerWrap?.contains(t)||this.triggerEl?.contains(t)||this.setOpen(!1)},this.onDocKeyDown=e=>{"Escape"===e.key&&this.isOpen()&&"false"!==this.getAttribute("close-on-escape")&&this.setOpen(!1)},document.addEventListener("mousedown",this.onDocMouseDown),document.addEventListener("keydown",this.onDocKeyDown)}detachGlobalListeners(){this.onDocMouseDown&&document.removeEventListener("mousedown",this.onDocMouseDown),this.onDocKeyDown&&document.removeEventListener("keydown",this.onDocKeyDown),this.onDocMouseDown=null,this.onDocKeyDown=null}scheduleOpen(){this.clearTimers();const e="hover"===this.resolvedTrigger()?Math.max(0,Number(this.getAttribute("delay")||0)):0;this.showTimer=setTimeout(()=>this.showPanel(),e)}scheduleClose(){this.clearTimers();const e="hover"===this.resolvedTrigger()?Math.max(0,Number(this.getAttribute("hide-delay")||80)):0;this.hideTimer=setTimeout(()=>this.setOpen(!1),e)}getTriggerRect(){const e=this.triggerEl||this.triggerWrap;return e?.getBoundingClientRect()}flipPlacementIfNeeded(e,t,i){const s=window.innerHeight,r=window.innerWidth,o=this.groupOf(e),n=t.top-i.height-8>=8,a=t.bottom+8+i.height<=s-8,h=t.left-i.width-8>=8,l=t.right+8+i.width<=r-8;return"top"===o&&!n&&a?e.replace(/^top/,"bottom"):"bottom"===o&&!a&&n?e.replace(/^bottom/,"top"):"left"===o&&!h&&l?e.replace(/^left/,"right"):"right"===o&&!l&&h?e.replace(/^right/,"left"):e}applyCoords(e,t,i){let s=0,r=0,o=0,n=0;const a=i.height,h=i.width,l=16;switch(e){case"top":s=t.top-i.height-8,r=t.left+t.width/2-i.width/2,o=a-5,n=h/2-5;break;case"top-start":s=t.top-i.height-8,r=t.left,o=a-5,n=11;break;case"top-end":s=t.top-i.height-8,r=t.right-i.width,o=a-5,n=h-l-5;break;case"bottom":s=t.bottom+8,r=t.left+t.width/2-i.width/2,o=-5,n=h/2-5;break;case"bottom-start":s=t.bottom+8,r=t.left,o=-5,n=11;break;case"bottom-end":s=t.bottom+8,r=t.right-i.width,o=-5,n=h-l-5;break;case"left":s=t.top+t.height/2-i.height/2,r=t.left-i.width-8,o=a/2-5,n=h-5;break;case"left-start":s=t.top,r=t.left-i.width-8,o=11,n=h-5;break;case"left-end":s=t.bottom-i.height,r=t.left-i.width-8,o=a-l-5,n=h-5;break;case"right":s=t.top+t.height/2-i.height/2,r=t.right+8,o=a/2-5,n=-5;break;case"right-start":s=t.top,r=t.right+8,o=11,n=-5;break;case"right-end":s=t.bottom-i.height,r=t.right+8,o=a-l-5,n=-5}const d=window.innerWidth,c=window.innerHeight;return r<8&&(r=8),r+i.width>d-8&&(r=d-i.width-8),s<8&&(s=8),s+i.height>c-8&&(s=c-i.height-8),{top:s,left:r,aTop:o,aLeft:n,placement:e}}positionPanel(){if(!this.panel)return;const t=this.getTriggerRect();if(!t)return;const i=Number(this.getAttribute("max-width")||300);this.panel.style.maxWidth=`${i}px`,this.panel.offsetHeight;const s=this.panel.getBoundingClientRect(),r=this.resolvedPlacement(),o=this.flipPlacementIfNeeded(r,t,s),{top:n,left:a,aTop:h,aLeft:l}=this.applyCoords(o,t,s);this.panel.style.top=`${n}px`,this.panel.style.left=`${a}px`,this.panel.dataset.placementGroup=this.groupOf(o),e.forEach(e=>{this.panel.classList.toggle(`designbase-wc-popover--${e}`,e===o)}),this.arrowEl&&(this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${o}`,this.arrowEl.style.top=`${h}px`,this.arrowEl.style.left=`${l}px`)}revealPanel(){this.panel&&(this.panel.classList.remove("designbase-wc-popover--visible"),this.positionPanel(),this.panel.offsetHeight,this.positionPanel(),this.panel.classList.add("designbase-wc-popover--visible"))}updatePanelMetadata(){if(!this.panel)return;const e=this.getAttribute("size")||"m",t=this.getAttribute("variant")||"default",i=this.resolvedPlacement();this.panel.className=["designbase-wc-popover",`designbase-wc-popover--${e}`,`designbase-wc-popover--${t}`,`designbase-wc-popover--${i}`,this.isOpen()?"designbase-wc-popover--visible":"",this.hasAttribute("disabled")?"designbase-wc-popover--disabled":""].filter(Boolean).join(" ")}ensurePanel(){if(this.panel)return;const e=document.createElement("div");e.className="designbase-wc-popover",e.setAttribute("data-wc-internal",""),e.setAttribute("role","dialog"),e.setAttribute("aria-modal","false"),e.style.position="fixed",e.style.zIndex="9999";const t=document.createElement("div");t.className="designbase-wc-popover__content";const i=document.createElement("div");i.className="designbase-wc-popover__header";const s=document.createElement("h3");s.className="designbase-wc-popover__title";const r=document.createElement("db-button");r.className="designbase-wc-popover__close-button",r.setAttribute("variant","ghost"),r.setAttribute("size","s"),r.setAttribute("icon-only",""),r.setAttribute("start-icon","close"),r.setAttribute("aria-label","팝오버 닫기"),r.addEventListener("db-click",e=>{e.stopPropagation(),this.setOpen(!1)}),i.append(s,r),this.bodyEl=document.createElement("div"),this.bodyEl.className="designbase-wc-popover__body",t.append(i,this.bodyEl),e.append(t),"false"!==this.getAttribute("show-arrow")&&(this.arrowEl=document.createElement("div"),this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${this.resolvedPlacement()}`,e.append(this.arrowEl)),this.panel=e,this.panel.querySelector(".designbase-wc-popover__title").textContent=this.getAttribute("title")||"",this.panel.querySelector(".designbase-wc-popover__title").hidden=!this.getAttribute("title"),document.body.append(e),e.addEventListener("mouseenter",()=>{"hover"===this.resolvedTrigger()&&this.clearTimers()}),e.addEventListener("mouseleave",()=>{"hover"===this.resolvedTrigger()&&this.scheduleClose()})}showPanel(){if(this.hasAttribute("disabled"))return;this.ensurePanel(),this.updatePanelMetadata();const e=this.collectBodyChildren();e.length>0?this.bodyEl.replaceChildren(...e.map(e=>e.cloneNode(!0))):this.bodyEl.textContent=this.getAttribute("content")||"";const t=this.panel.querySelector(".designbase-wc-popover__title");t.textContent=this.getAttribute("title")||"",t.hidden=!this.getAttribute("title"),requestAnimationFrame(()=>{this.revealPanel(),window.addEventListener("scroll",this.handleReposition,{capture:!0,passive:!0}),window.addEventListener("resize",this.handleReposition)})}hidePanel(){this.panel?.classList.remove("designbase-wc-popover--visible"),window.removeEventListener("scroll",this.handleReposition,!0),window.removeEventListener("resize",this.handleReposition),this.hasAttribute("always-show")||this.removePanel()}removePanel(){this.panel?.remove(),this.panel=void 0,this.bodyEl=void 0,this.arrowEl=void 0}render(){this.ensureTriggerWrap();const e=this.collectTriggerChildren();this.mountTriggerChildren(e);const t=Boolean(this.getAttribute("trigger-id"));this.triggerWrap&&(e.length>0||!t?this.triggerWrap.parentElement!==this&&this.append(this.triggerWrap):this.triggerWrap.parentElement===this&&this.triggerWrap.remove()),this.hasAttribute("always-show")&&this.showPanel()}}customElements.get("db-popover")||customElements.define("db-popover",DbPopover);export{DbPopover};
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";class DbProgressStep extends HTMLElement{static get observedAttributes(){return["items","size","layout","current-step","clickable","full-width","disabled"]}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}resolveStatus(e,t){const s=t.status??"pending";if("pending"!==s)return s;const n=Number(this.getAttribute("current-step")||0);return e<n?"completed":e===n?"active":"pending"}iconSize(e){return"s"===e?12:"l"===e?20:16}renderIndicatorContent(t,s,n){const i=document.createElement("div");if(i.className="designbase-wc-progress-step__icon","completed"===t)i.append(e("done",this.iconSize(n)));else if("error"===t)i.append(e("warning-filled",this.iconSize(n)));else{const e=document.createElement("span");e.className="designbase-wc-progress-step__number",e.textContent=String(s+1),i.append(e)}return i}handleStepClick(e,t){const s=this.hasAttribute("disabled"),n=this.hasAttribute("clickable");s||e.disabled||!n||this.dispatchEvent(new CustomEvent("db-step-click",{detail:{item:e,index:t},bubbles:!0,composed:!0}))}render(){const e=this.getAttribute("size")||"m",t=this.getAttribute("layout")||"horizontal",s=this.hasAttribute("clickable"),n=this.hasAttribute("disabled"),i=this.items;this.className=["designbase-wc-progress-step",`designbase-wc-progress-step--${e}`,`designbase-wc-progress-step--${t}`,s&&"designbase-wc-progress-step--clickable",this.hasAttribute("full-width")&&"designbase-wc-progress-step--full-width",n&&"designbase-wc-progress-step--disabled"].filter(Boolean).join(" "),this.replaceChildren(),i.forEach((t,r)=>{const a=this.resolveStatus(r,t),c=r===i.length-1,d=s&&!n&&!t.disabled,o="completed"===(r>0?this.resolveStatus(r-1,i[r-1]):"pending")?"completed":a,p=document.createElement("div");p.className=["designbase-wc-progress-step__item",`designbase-wc-progress-step__item--${a}`,d&&"designbase-wc-progress-step__item--clickable",t.disabled&&"designbase-wc-progress-step__item--disabled"].filter(Boolean).join(" ");const l=document.createElement("div");l.className="designbase-wc-progress-step__indicator-container";const m=document.createElement("div");if(m.className="designbase-wc-progress-step__indicator",d?(m.tabIndex=0,m.setAttribute("role","button"),m.setAttribute("aria-label",`${t.title} 단계로 이동`),m.addEventListener("click",()=>this.handleStepClick(t,r)),m.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleStepClick(t,r))})):m.tabIndex=-1,"active"===a){const e=document.createElement("div");e.className="designbase-wc-progress-step__pulse",m.append(e)}if(m.append(this.renderIndicatorContent(a,r,e)),l.append(m),!c){const e=document.createElement("div");e.className=["designbase-wc-progress-step__connector",`designbase-wc-progress-step__connector--${o}`].join(" "),l.append(e)}p.append(l);const b=document.createElement("div");b.className="designbase-wc-progress-step__content";const g=document.createElement("div");g.className="designbase-wc-progress-step__header";const u=document.createElement("h3");if(u.className="designbase-wc-progress-step__title",u.textContent=t.title,g.append(u),b.append(g),t.description){const e=document.createElement("p");e.className="designbase-wc-progress-step__description",e.textContent=t.description,b.append(e)}if(t.timestamp){const e=document.createElement("span");e.className="designbase-wc-progress-step__timestamp",e.textContent=t.timestamp,b.append(e)}p.append(b),this.append(p)})}}customElements.get("db-progress-step")||customElements.define("db-progress-step",DbProgressStep);export{DbProgressStep};
1
+ import{createDbIcon as e}from"./db-icons.js";class DbProgressStep extends HTMLElement{static get observedAttributes(){return["items","size","layout","current-step","clickable","full-width","disabled"]}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}resolveStatus(e,t){const s=t.status??"pending";if("pending"!==s)return s;const n=Number(this.getAttribute("current-step")||0);return e<n?"completed":e===n?"active":"pending"}iconSize(e){return"s"===e?12:"l"===e?20:16}renderIndicatorContent(t,s,n){const i=document.createElement("div");if(i.className="designbase-wc-progress-step__icon","completed"===t)i.append(e("done",this.iconSize(n)));else if("error"===t)i.append(e("warning-filled",this.iconSize(n)));else{const e=document.createElement("span");e.className="designbase-wc-progress-step__number",e.textContent=String(s+1),i.append(e)}return i}handleStepClick(e,t){const s=this.hasAttribute("disabled"),n=this.hasAttribute("clickable");s||e.disabled||!n||this.dispatchEvent(new CustomEvent("db-step-click",{detail:{item:e,index:t},bubbles:!0,composed:!0}))}render(){const e=this.getAttribute("size")||"m",t=this.getAttribute("layout")||"horizontal",s=this.hasAttribute("clickable"),n=this.hasAttribute("disabled"),i=this.items;this.className=["designbase-wc-progress-step",`designbase-wc-progress-step--${e}`,`designbase-wc-progress-step--${t}`,s&&"designbase-wc-progress-step--clickable",this.hasAttribute("full-width")&&"designbase-wc-progress-step--full-width",n&&"designbase-wc-progress-step--disabled"].filter(Boolean).join(" "),this.replaceChildren(),i.forEach((t,r)=>{const a=this.resolveStatus(r,t),c=r===i.length-1,d=s&&!n&&!t.disabled,o=s&&(n||Boolean(t.disabled)),p="completed"===(r>0?this.resolveStatus(r-1,i[r-1]):"pending")?"completed":a,l=document.createElement("div");l.className=["designbase-wc-progress-step__item",`designbase-wc-progress-step__item--${a}`,d&&"designbase-wc-progress-step__item--clickable",t.disabled&&"designbase-wc-progress-step__item--disabled"].filter(Boolean).join(" ");const b=document.createElement("div");b.className="designbase-wc-progress-step__indicator-container";const m=document.createElement("div");if(m.className="designbase-wc-progress-step__indicator",o&&(m.setAttribute("role","button"),m.setAttribute("aria-disabled","true")),d?(m.tabIndex=0,m.setAttribute("role","button"),m.setAttribute("aria-label",`${t.title} 단계로 이동`),m.addEventListener("click",()=>this.handleStepClick(t,r)),m.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleStepClick(t,r))})):m.tabIndex=-1,"active"===a){const e=document.createElement("div");e.className="designbase-wc-progress-step__pulse",m.append(e)}if(m.append(this.renderIndicatorContent(a,r,e)),b.append(m),!c){const e=document.createElement("div");e.className=["designbase-wc-progress-step__connector",`designbase-wc-progress-step__connector--${p}`].join(" "),b.append(e)}l.append(b);const g=document.createElement("div");g.className="designbase-wc-progress-step__content";const u=document.createElement("div");u.className="designbase-wc-progress-step__header";const h=document.createElement("h3");if(h.className="designbase-wc-progress-step__title",h.textContent=t.title,u.append(h),g.append(u),t.description){const e=document.createElement("p");e.className="designbase-wc-progress-step__description",e.textContent=t.description,g.append(e)}if(t.timestamp){const e=document.createElement("span");e.className="designbase-wc-progress-step__timestamp",e.textContent=t.timestamp,g.append(e)}l.append(g),this.append(l)})}}customElements.get("db-progress-step")||customElements.define("db-progress-step",DbProgressStep);export{DbProgressStep};