@designbasekorea/ui-wc 0.9.0 → 0.9.2

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 (104) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +18 -2
  3. package/dist/esm/components/date-picker-utils.js +1 -1
  4. package/dist/esm/components/db-accordion.js +1 -1
  5. package/dist/esm/components/db-achievement-list.js +1 -1
  6. package/dist/esm/components/db-achievement-modal.js +1 -1
  7. package/dist/esm/components/db-activity-heatmap.js +1 -1
  8. package/dist/esm/components/db-ad-banner.js +1 -1
  9. package/dist/esm/components/db-ai-chat.js +1 -1
  10. package/dist/esm/components/db-alert.js +1 -1
  11. package/dist/esm/components/db-app-badge.js +1 -1
  12. package/dist/esm/components/db-audio-player.js +1 -1
  13. package/dist/esm/components/db-boarding-pass-stack.js +1 -1
  14. package/dist/esm/components/db-boarding-pass.js +1 -1
  15. package/dist/esm/components/db-bottom-navigation.js +1 -1
  16. package/dist/esm/components/db-bottom-sheet.js +1 -1
  17. package/dist/esm/components/db-breadcrumbs.js +1 -1
  18. package/dist/esm/components/db-calendar.js +1 -1
  19. package/dist/esm/components/db-card.js +1 -1
  20. package/dist/esm/components/db-carousel.d.ts +3 -3
  21. package/dist/esm/components/db-carousel.js +1 -1
  22. package/dist/esm/components/db-chat-composer.js +1 -1
  23. package/dist/esm/components/db-chat-room.js +1 -1
  24. package/dist/esm/components/db-chat-widget.js +1 -1
  25. package/dist/esm/components/db-chip.js +1 -1
  26. package/dist/esm/components/db-code-block.js +1 -1
  27. package/dist/esm/components/db-color-picker.js +1 -1
  28. package/dist/esm/components/db-context-bar.js +1 -1
  29. package/dist/esm/components/db-credit-card.js +1 -1
  30. package/dist/esm/components/db-date-picker.js +1 -1
  31. package/dist/esm/components/db-design-canvas.js +1 -1
  32. package/dist/esm/components/db-design-toolbar.js +1 -1
  33. package/dist/esm/components/db-download-progress.js +1 -1
  34. package/dist/esm/components/db-drawer.js +1 -1
  35. package/dist/esm/components/db-dropzone.js +1 -1
  36. package/dist/esm/components/db-email-verify.d.ts +0 -6
  37. package/dist/esm/components/db-email-verify.js +1 -1
  38. package/dist/esm/components/db-file-uploader.js +1 -1
  39. package/dist/esm/components/db-flight-status.js +1 -1
  40. package/dist/esm/components/db-footer.js +1 -1
  41. package/dist/esm/components/db-gantt.js +1 -1
  42. package/dist/esm/components/db-image-list.d.ts +2 -0
  43. package/dist/esm/components/db-image-list.js +1 -1
  44. package/dist/esm/components/db-indicator.js +1 -1
  45. package/dist/esm/components/db-input.js +1 -1
  46. package/dist/esm/components/db-kanban.js +1 -1
  47. package/dist/esm/components/db-lightbox.d.ts +4 -0
  48. package/dist/esm/components/db-lightbox.js +1 -1
  49. package/dist/esm/components/db-markdown-editor.js +1 -1
  50. package/dist/esm/components/db-marquee.d.ts +2 -10
  51. package/dist/esm/components/db-marquee.js +1 -1
  52. package/dist/esm/components/db-navbar.js +1 -1
  53. package/dist/esm/components/db-node.js +1 -1
  54. package/dist/esm/components/db-onboarding-modal.js +1 -1
  55. package/dist/esm/components/db-otp-input.js +1 -1
  56. package/dist/esm/components/db-page-header.d.ts +8 -0
  57. package/dist/esm/components/db-page-header.js +1 -1
  58. package/dist/esm/components/db-pagination.js +1 -1
  59. package/dist/esm/components/db-phone-verify.js +1 -1
  60. package/dist/esm/components/db-popover.js +1 -1
  61. package/dist/esm/components/db-progress-step.js +1 -1
  62. package/dist/esm/components/db-receipt.js +1 -1
  63. package/dist/esm/components/db-resizable-panels.js +1 -1
  64. package/dist/esm/components/db-search-bar.js +1 -1
  65. package/dist/esm/components/db-section-testimonials.d.ts +1 -4
  66. package/dist/esm/components/db-section-testimonials.js +1 -1
  67. package/dist/esm/components/db-segment-control.d.ts +0 -4
  68. package/dist/esm/components/db-segment-control.js +1 -1
  69. package/dist/esm/components/db-select.js +1 -1
  70. package/dist/esm/components/db-share.js +1 -1
  71. package/dist/esm/components/db-sidebar.js +1 -1
  72. package/dist/esm/components/db-split-view.js +1 -1
  73. package/dist/esm/components/db-stepper.d.ts +0 -3
  74. package/dist/esm/components/db-stepper.js +1 -1
  75. package/dist/esm/components/db-table.js +1 -1
  76. package/dist/esm/components/db-testimonial.js +1 -1
  77. package/dist/esm/components/db-time-picker.js +1 -1
  78. package/dist/esm/components/db-top-banner.js +1 -1
  79. package/dist/esm/components/db-tutorial.js +1 -1
  80. package/dist/esm/components/db-two-factor.d.ts +4 -10
  81. package/dist/esm/components/db-two-factor.js +1 -1
  82. package/dist/esm/components/db-video-player.js +1 -1
  83. package/dist/esm/components/db-youtube-player.js +1 -1
  84. package/dist/esm/components/input-validation.js +1 -1
  85. package/dist/esm/components/paper-card.js +1 -1
  86. package/dist/esm/core/i18n-copy.js +1 -0
  87. package/dist/esm/core/i18n-en.js +1 -0
  88. package/dist/esm/core/i18n.d.ts +53 -1
  89. package/dist/esm/core/i18n.js +1 -1
  90. package/dist/esm/index.d.ts +1 -1
  91. package/dist/esm/index.js +1 -1
  92. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-AGE5BHQ4.js +1 -0
  93. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-GM4TCAP5.js +1 -0
  94. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-GSN4JZN7.js +1 -0
  95. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-VJJVQGV4.js +1 -0
  96. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-YWLMJGDH.js +1 -0
  97. package/dist/index.cjs +1 -1
  98. package/dist/index.css +1 -1
  99. package/dist/index.d.ts +75 -41
  100. package/dist/index.esm.js +1 -1
  101. package/dist/react/index.cjs +1 -1
  102. package/dist/react/index.d.ts +8 -0
  103. package/dist/react/index.esm.js +1 -1
  104. package/package.json +4 -3
@@ -1 +1 @@
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{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{PHONE_VERIFY_SIZES as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const s=[{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 e(this.getAttribute("size"),i,"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,i=this.step,r=this.hasAttribute("disabled"),n=function parseCarriers(t){if(!t)return s;try{const e=JSON.parse(t);return Array.isArray(e)&&e.length?e:s}catch{return s}}(this.getAttribute("carrier-options")),o=this.getAttribute("code-length")||"6";this.className=[t,`${t}--${e}`,`${t}--step-${i}`,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"===i);const d=this.getAttribute("phone")||"";this.phoneInput.value=d,this.phoneInput.setAttribute("size",e),this.phoneInput.toggleAttribute("disabled",r||"phone"!==i),this.phoneInput.toggleAttribute("error",this.hasAttribute("error")&&"phone"===i),this.sendBtn.setAttribute("size",e),this.sendBtn.textContent=this.getAttribute("send-label")||"인증번호 받기",this.sendBtn.toggleAttribute("disabled",r||"phone"!==i||!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"!==i),this.otpInput.toggleAttribute("error",this.hasAttribute("error")&&"code"===i),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"===i;this.querySelector('[data-role="verified"]').hidden="verified"!==i;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{dbFormat as t,dbText as e,t as i}from"../core/i18n.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import"./db-select.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{PHONE_VERIFY_SIZES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const DEFAULT_CARRIERS=()=>[{value:"skt",label:"SKT"},{value:"kt",label:"KT"},{value:"lgu",label:"LG U+"},{value:"mvno",label:e("알뜰폰")}];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 s(this.getAttribute("size"),r,"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 e=Math.max(0,Math.floor(this.remaining/60)),i=Math.max(0,this.remaining%60);this.timerEl.textContent=`${String(e).padStart(2,"0")}:${String(i).padStart(2,"0")}`,this.timerEl.setAttribute("aria-label",t("남은 시간 {0}분 {1}초",[e,i])),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 s=el("div",`${t}__header`),r=el("h3",`${t}__title`);r.dataset.role="title";const n=el("p",`${t}__description`);n.dataset.role="description",s.append(r,n);const o=el("div",`${t}__field`);this.carrierSelect=document.createElement("db-select"),this.carrierSelect.setAttribute("label","통신사"),this.carrierSelect.setAttribute("full-width",""),this.carrierSelect.setAttribute("placeholder",e("통신사 선택")),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}))}),o.append(this.carrierSelect);const h=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())}),h.append(this.phoneInput,this.sendBtn),this.codeBlock=el("div",`${t}__code`);const a=el("div",`${t}__code-head`),d=el("span",`${t}__code-label`);d.textContent=e("인증번호"),this.timerEl=el("span",`${t}__timer`),a.append(d,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 l=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()}),l.append(this.resendBtn,this.verifyBtn),this.codeBlock.append(a,this.otpInput,l),this.errorEl=el("p",`${t}__error`),this.errorEl.hidden=!0;const c=el("div",`${t}__verified`);c.dataset.role="verified";const u=el("span",`${t}__verified-badge`);u.textContent=i("verify.done");const p=document.createElement("p");p.className=`${t}__verified-text`,p.textContent=i("verify.phoneDone"),c.append(u,p),this.append(s,o,h,this.codeBlock,this.errorEl,c)}sync(){const t="designbase-wc-phone-verify",e=this.size,i=this.step,s=this.hasAttribute("disabled"),r=function parseCarriers(t){if(!t)return DEFAULT_CARRIERS();try{const e=JSON.parse(t);return Array.isArray(e)&&e.length?e:DEFAULT_CARRIERS()}catch{return DEFAULT_CARRIERS()}}(this.getAttribute("carrier-options")),n=this.getAttribute("code-length")||"6";this.className=[t,`${t}--${e}`,`${t}--step-${i}`,s&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" ");const o=this.querySelector('[data-role="title"]'),h=this.querySelector('[data-role="description"]');o.textContent=this.getAttribute("title")||"휴대폰 인증",h.textContent=this.getAttribute("description")||"본인 명의의 휴대폰 번호를 입력하고 인증번호를 받아 주세요.",this.carrierSelect.setAttribute("options",JSON.stringify(r)),this.carrierSelect.setAttribute("value",this.carrier),this.carrierSelect.setAttribute("size",e),this.carrierSelect.toggleAttribute("disabled",s||"verified"===i);const a=this.getAttribute("phone")||"";this.phoneInput.value=a,this.phoneInput.setAttribute("size",e),this.phoneInput.toggleAttribute("disabled",s||"phone"!==i),this.phoneInput.toggleAttribute("error",this.hasAttribute("error")&&"phone"===i),this.sendBtn.setAttribute("size",e),this.sendBtn.textContent=this.getAttribute("send-label")||"인증번호 받기",this.sendBtn.toggleAttribute("disabled",s||"phone"!==i||!this.isPhoneValid()),this.sendBtn.toggleAttribute("loading",this.hasAttribute("sending")),this.otpInput.setAttribute("length",n),this.otpInput.setAttribute("size",e),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",s||"code"!==i),this.otpInput.toggleAttribute("error",this.hasAttribute("error")&&"code"===i),this.resendBtn.textContent=this.getAttribute("resend-label")||"재전송",this.verifyBtn.setAttribute("size",e),this.verifyBtn.textContent=this.getAttribute("verify-label")||"인증하기",this.verifyBtn.toggleAttribute("disabled",s||(this.getAttribute("code")||"").length<Number(n)),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.codeBlock.hidden="phone"===i;this.querySelector('[data-role="verified"]').hidden="verified"!==i;const d=this.getAttribute("error-message")||"";this.errorEl.textContent=d,this.errorEl.hidden=!this.hasAttribute("error")||!d}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
- 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")||"content"===e.getAttribute("slot")||e===this.triggerWrap,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>"content"!==e.getAttribute("slot"))}ensureTriggerWrap(){this.triggerWrap||(this.triggerWrap=document.createElement("span"),this.triggerWrap.className="designbase-wc-popover__trigger",this.triggerWrap.setAttribute("data-wc-internal",""),this.triggerWrap.tabIndex=this.hasAttribute("trigger-id")?-1: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(':scope > [slot="content"]')),...Array.from(this.bodyEl?.querySelectorAll(':scope > [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):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.bodyEl?.querySelectorAll(':scope > [slot="content"]').forEach(e=>this.append(e)),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{dbText as e}from"../core/i18n.js";import{POPOVER_PLACEMENTS as t,POPOVER_TRIGGERS as i}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 e=this.getAttribute("position")||this.getAttribute("placement")||"top";return t.includes(e)?e:"top"}resolvedTrigger(){const e=this.getAttribute("trigger")||"click";return i.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")||"content"===e.getAttribute("slot")||e===this.triggerWrap,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>"content"!==e.getAttribute("slot"))}ensureTriggerWrap(){this.triggerWrap||(this.triggerWrap=document.createElement("span"),this.triggerWrap.className="designbase-wc-popover__trigger",this.triggerWrap.setAttribute("data-wc-internal",""),this.triggerWrap.tabIndex=this.hasAttribute("trigger-id")?-1: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(':scope > [slot="content"]')),...Array.from(this.bodyEl?.querySelectorAll(':scope > [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 e=this.getTriggerRect();if(!e)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,e,s),{top:n,left:a,aTop:h,aLeft:l}=this.applyCoords(o,e,s);this.panel.style.top=`${n}px`,this.panel.style.left=`${a}px`,this.panel.dataset.placementGroup=this.groupOf(o),t.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 t=document.createElement("div");t.className="designbase-wc-popover",t.setAttribute("data-wc-internal",""),t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.style.position="fixed",t.style.zIndex="9999";const i=document.createElement("div");i.className="designbase-wc-popover__content";const s=document.createElement("div");s.className="designbase-wc-popover__header";const r=document.createElement("h3");r.className="designbase-wc-popover__title";const o=document.createElement("db-button");o.className="designbase-wc-popover__close-button",o.setAttribute("variant","ghost"),o.setAttribute("size","s"),o.setAttribute("icon-only",""),o.setAttribute("start-icon","close"),o.setAttribute("aria-label",e("팝오버 닫기")),o.addEventListener("db-click",e=>{e.stopPropagation(),this.setOpen(!1)}),s.append(r,o),this.bodyEl=document.createElement("div"),this.bodyEl.className="designbase-wc-popover__body",i.append(s,this.bodyEl),t.append(i),"false"!==this.getAttribute("show-arrow")&&(this.arrowEl=document.createElement("div"),this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${this.resolvedPlacement()}`,t.append(this.arrowEl)),this.panel=t,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(t),t.addEventListener("mouseenter",()=>{"hover"===this.resolvedTrigger()&&this.clearTimers()}),t.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):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.bodyEl?.querySelectorAll(':scope > [slot="content"]').forEach(e=>this.append(e)),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";import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{PROGRESS_STEP_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.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=t(this.getAttribute("size"),s,"m"),n=this.getAttribute("layout")||"horizontal",i=this.hasAttribute("clickable"),r=this.hasAttribute("disabled"),a=this.items;this.className=["designbase-wc-progress-step",`designbase-wc-progress-step--${e}`,`designbase-wc-progress-step--${n}`,i&&"designbase-wc-progress-step--clickable",this.hasAttribute("full-width")&&"designbase-wc-progress-step--full-width",r&&"designbase-wc-progress-step--disabled"].filter(Boolean).join(" "),this.replaceChildren(),a.forEach((t,s)=>{const n=this.resolveStatus(s,t),c=s===a.length-1,d=i&&!r&&!t.disabled,o=i&&(r||Boolean(t.disabled)),p="completed"===(s>0?this.resolveStatus(s-1,a[s-1]):"pending")?"completed":n,l=document.createElement("div");l.className=["designbase-wc-progress-step__item",`designbase-wc-progress-step__item--${n}`,d&&"designbase-wc-progress-step__item--clickable",t.disabled&&"designbase-wc-progress-step__item--disabled"].filter(Boolean).join(" ");const m=document.createElement("div");m.className="designbase-wc-progress-step__indicator-container";const b=document.createElement("div");if(b.className="designbase-wc-progress-step__indicator",o&&(b.setAttribute("role","button"),b.setAttribute("aria-disabled","true")),d?(b.tabIndex=0,b.setAttribute("role","button"),b.setAttribute("aria-label",`${t.title} 단계로 이동`),b.addEventListener("click",()=>this.handleStepClick(t,s)),b.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleStepClick(t,s))})):b.tabIndex=-1,"active"===n){const e=document.createElement("div");e.className="designbase-wc-progress-step__pulse",b.append(e)}if(b.append(this.renderIndicatorContent(n,s,e)),m.append(b),!c){const e=document.createElement("div");e.className=["designbase-wc-progress-step__connector",`designbase-wc-progress-step__connector--${p}`].join(" "),m.append(e)}l.append(m);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};
1
+ import{dbFormat as e}from"../core/i18n.js";import{createDbIcon as t}from"./db-icons.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{PROGRESS_STEP_SIZES as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.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(e,s,n){const i=document.createElement("div");if(i.className="designbase-wc-progress-step__icon","completed"===e)i.append(t("done",this.iconSize(n)));else if("error"===e)i.append(t("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 t=s(this.getAttribute("size"),n,"m"),i=this.getAttribute("layout")||"horizontal",r=this.hasAttribute("clickable"),a=this.hasAttribute("disabled"),c=this.items;this.className=["designbase-wc-progress-step",`designbase-wc-progress-step--${t}`,`designbase-wc-progress-step--${i}`,r&&"designbase-wc-progress-step--clickable",this.hasAttribute("full-width")&&"designbase-wc-progress-step--full-width",a&&"designbase-wc-progress-step--disabled"].filter(Boolean).join(" "),this.replaceChildren(),c.forEach((s,n)=>{const i=this.resolveStatus(n,s),o=n===c.length-1,d=r&&!a&&!s.disabled,p=r&&(a||Boolean(s.disabled)),l="completed"===(n>0?this.resolveStatus(n-1,c[n-1]):"pending")?"completed":i,m=document.createElement("div");m.className=["designbase-wc-progress-step__item",`designbase-wc-progress-step__item--${i}`,d&&"designbase-wc-progress-step__item--clickable",s.disabled&&"designbase-wc-progress-step__item--disabled"].filter(Boolean).join(" ");const b=document.createElement("div");b.className="designbase-wc-progress-step__indicator-container";const g=document.createElement("div");if(g.className="designbase-wc-progress-step__indicator",p&&(g.setAttribute("role","button"),g.setAttribute("aria-disabled","true")),d?(g.tabIndex=0,g.setAttribute("role","button"),g.setAttribute("aria-label",e("{0} 단계로 이동",[s.title])),g.addEventListener("click",()=>this.handleStepClick(s,n)),g.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleStepClick(s,n))})):g.tabIndex=-1,"active"===i){const e=document.createElement("div");e.className="designbase-wc-progress-step__pulse",g.append(e)}if(g.append(this.renderIndicatorContent(i,n,t)),b.append(g),!o){const e=document.createElement("div");e.className=["designbase-wc-progress-step__connector",`designbase-wc-progress-step__connector--${l}`].join(" "),b.append(e)}m.append(b);const u=document.createElement("div");u.className="designbase-wc-progress-step__content";const h=document.createElement("div");h.className="designbase-wc-progress-step__header";const _=document.createElement("h3");if(_.className="designbase-wc-progress-step__title",_.textContent=s.title,h.append(_),u.append(h),s.description){const e=document.createElement("p");e.className="designbase-wc-progress-step__description",e.textContent=s.description,u.append(e)}if(s.timestamp){const e=document.createElement("span");e.className="designbase-wc-progress-step__timestamp",e.textContent=s.timestamp,u.append(e)}m.append(u),this.append(m)})}}customElements.get("db-progress-step")||customElements.define("db-progress-step",DbProgressStep);export{DbProgressStep};
@@ -1 +1 @@
1
- import{DbPaperCard as t,paperJson as e,paperNode as a,paperDetails as r}from"./paper-card.js";const i={quantity:"수량",subtotal:"소계",discount:"할인",tax:"세금",total:"합계",payment:"결제수단",empty:"표시할 품목이 없습니다.",invalid:"품목과 금액 정보를 확인해주세요."},minor=t=>"number"==typeof t&&Number.isSafeInteger(t)&&t>=0;class DbReceipt extends t{constructor(){super(...arguments),this.data=void 0,this.customLabels={}}static get observedAttributes(){return["variant","code-image-src","code-alt","merchant","merchant-detail","reference","issued-at","items","currency","locale","discount-amount","tax-amount","payment-method","note","edge","action-label","disabled"]}upgradeNames(){return["items","labels"]}get items(){const t=this.data??e(this.attr("items"));return Array.isArray(t)?t.map(t=>({...t})):[]}set items(t){this.data=null==t?void 0:Array.isArray(t)?t.map(t=>({...t})):t,this.isConnected&&this.render()}get labels(){return{...i,...this.customLabels}}set labels(t){this.customLabels={};for(const e of Object.keys(i))"string"==typeof t?.[e]&&(this.customLabels[e]=t[e]);this.isConnected&&this.render()}render(){const t="compact"===this.getAttribute("variant");this.dataset.variant=t?"compact":"default";const e=this.labels,i=a("section","db-paper__main");i.append(a("h3","db-paper__title",this.attr("merchant")||"영수증")),this.attr("merchant-detail")&&i.append(a("p","db-paper__description",this.attr("merchant-detail")));const s=a("div","db-paper__receipt-meta");let n;this.attr("issued-at")&&s.append(a("span","",this.attr("issued-at"))),!t&&this.attr("reference")&&s.append(a("span","",this.attr("reference"))),i.append(s);try{n=new Intl.NumberFormat(this.attr("locale")||"ko-KR",{style:"currency",currency:this.attr("currency")||"KRW"})}catch{n=new Intl.NumberFormat("ko-KR",{style:"currency",currency:"KRW"})}const p=n.resolvedOptions().maximumFractionDigits||0,o=BigInt(10**p),c=new Intl.NumberFormat(n.resolvedOptions().locale,{useGrouping:!1,minimumIntegerDigits:Math.max(1,p),maximumFractionDigits:0}),money=t=>{const e=BigInt(t);return n.formatToParts(e/o).map(t=>"fraction"===t.type?c.format(e%o):t.value).join("")};let d=this.data;if(void 0===d)try{d=this.hasAttribute("items")?JSON.parse(this.attr("items")):[]}catch{d=null}const u=Array.isArray(d)?d:[];let m=Array.isArray(d),l=0;for(const t of u){if(!t||"string"!=typeof t.name||!Number.isSafeInteger(t.quantity)||t.quantity<=0||!minor(t.unitAmount)||!Number.isSafeInteger(t.quantity*t.unitAmount)){m=!1;break}if(l+=t.quantity*t.unitAmount,!Number.isSafeInteger(l)){m=!1;break}}const amount=t=>this.hasAttribute(t)&&""===this.attr(t).trim()?NaN:Number(this.getAttribute(t)??0),b=amount("discount-amount"),h=amount("tax-amount");m=m&&minor(b)&&minor(h)&&b<=l&&Number.isSafeInteger(l-b+h);const y=a("div","db-paper__receipt-items");if(m)if(u.length)for(const t of u){const r=a("div","db-paper__receipt-item"),i=a("div","");i.append(a("strong","",t.name),a("span","db-paper__label",`${e.quantity} ${t.quantity} × ${money(t.unitAmount)}`)),r.append(i,a("span","",money(t.unitAmount*t.quantity))),y.append(r)}else y.append(a("p","db-paper__note",e.empty));else{const t=a("p","db-paper__error",e.invalid);t.setAttribute("role","alert"),y.append(t)}i.append(y);const f=a("div","db-paper__stub"),g=t?i:f;if(m&&(!t||b||h)){const t=[{label:e.subtotal,value:money(l)}];b&&t.push({label:e.discount,value:"−"+money(b)}),h&&t.push({label:e.tax,value:money(h)}),g.append(r(t))}const _=a("div","db-paper__receipt-total");_.append(a("strong","",e.total),a("strong","db-paper__amount",m?money(l-b+h):"—")),g.append(_),this.attr("payment-method")&&g.append(r([{label:e.payment,value:this.attr("payment-method")}])),this.attr("note")&&g.append(a("p","db-paper__note",this.attr("note"))),(t||this.attr("code-image-src"))&&f.append(this.code(this.attr("reference")));const v=this.action(this.attr("reference"));v&&(v.toggleAttribute("disabled",!m||this.hasAttribute("disabled")),f.append(v)),this.replace(i,f)}}customElements.get("db-receipt")||customElements.define("db-receipt",DbReceipt);export{DbReceipt};
1
+ import{t,getDbLocale as e}from"../core/i18n.js";import{DbPaperCard as a,paperJson as r,paperNode as i,paperDetails as s}from"./paper-card.js";const n={quantity:"수량",subtotal:"소계",discount:"할인",tax:"세금",total:"합계",payment:"결제수단",empty:"표시할 품목이 없습니다.",invalid:"품목과 금액 정보를 확인해주세요."},minor=t=>"number"==typeof t&&Number.isSafeInteger(t)&&t>=0;class DbReceipt extends a{constructor(){super(...arguments),this.data=void 0,this.customLabels={}}static get observedAttributes(){return["variant","code-image-src","code-alt","merchant","merchant-detail","reference","issued-at","items","currency","locale","discount-amount","tax-amount","payment-method","note","edge","action-label","disabled"]}upgradeNames(){return["items","labels"]}get items(){const t=this.data??r(this.attr("items"));return Array.isArray(t)?t.map(t=>({...t})):[]}set items(t){this.data=null==t?void 0:Array.isArray(t)?t.map(t=>({...t})):t,this.isConnected&&this.render()}get labels(){return{...Object.fromEntries(Object.entries(n).map(([e,a])=>[e,t(`receipt.${e}`,a)])),...this.customLabels}}set labels(t){this.customLabels={};for(const e of Object.keys(n))"string"==typeof t?.[e]&&(this.customLabels[e]=t[e]);this.isConnected&&this.render()}render(){const a="compact"===this.getAttribute("variant");this.dataset.variant=a?"compact":"default";const r=this.labels,n=i("section","db-paper__main");n.append(i("h3","db-paper__title",this.attr("merchant")||t("receipt.title"))),this.attr("merchant-detail")&&n.append(i("p","db-paper__description",this.attr("merchant-detail")));const o=i("div","db-paper__receipt-meta");let p;this.attr("issued-at")&&o.append(i("span","",this.attr("issued-at"))),!a&&this.attr("reference")&&o.append(i("span","",this.attr("reference"))),n.append(o);try{p=new Intl.NumberFormat(this.attr("locale")||("ko"===e()?"ko-KR":"en-US"),{style:"currency",currency:this.attr("currency")||"KRW"})}catch{p=new Intl.NumberFormat("ko"===e()?"ko-KR":"en-US",{style:"currency",currency:"KRW"})}const c=p.resolvedOptions().maximumFractionDigits||0,d=BigInt(10**c),m=new Intl.NumberFormat(p.resolvedOptions().locale,{useGrouping:!1,minimumIntegerDigits:Math.max(1,c),maximumFractionDigits:0}),money=t=>{const e=BigInt(t);return p.formatToParts(e/d).map(t=>"fraction"===t.type?m.format(e%d):t.value).join("")};let u=this.data;if(void 0===u)try{u=this.hasAttribute("items")?JSON.parse(this.attr("items")):[]}catch{u=null}const l=Array.isArray(u)?u:[];let b=Array.isArray(u),h=0;for(const t of l){if(!t||"string"!=typeof t.name||!Number.isSafeInteger(t.quantity)||t.quantity<=0||!minor(t.unitAmount)||!Number.isSafeInteger(t.quantity*t.unitAmount)){b=!1;break}if(h+=t.quantity*t.unitAmount,!Number.isSafeInteger(h)){b=!1;break}}const amount=t=>this.hasAttribute(t)&&""===this.attr(t).trim()?NaN:Number(this.getAttribute(t)??0),y=amount("discount-amount"),f=amount("tax-amount");b=b&&minor(y)&&minor(f)&&y<=h&&Number.isSafeInteger(h-y+f);const g=i("div","db-paper__receipt-items");if(b)if(l.length)for(const t of l){const e=i("div","db-paper__receipt-item"),a=i("div","");a.append(i("strong","",t.name),i("span","db-paper__label",`${r.quantity} ${t.quantity} × ${money(t.unitAmount)}`)),e.append(a,i("span","",money(t.unitAmount*t.quantity))),g.append(e)}else g.append(i("p","db-paper__note",r.empty));else{const t=i("p","db-paper__error",r.invalid);t.setAttribute("role","alert"),g.append(t)}n.append(g);const _=i("div","db-paper__stub"),v=a?n:_;if(b&&(!a||y||f)){const t=[{label:r.subtotal,value:money(h)}];y&&t.push({label:r.discount,value:"−"+money(y)}),f&&t.push({label:r.tax,value:money(f)}),v.append(s(t))}const A=i("div","db-paper__receipt-total");A.append(i("strong","",r.total),i("strong","db-paper__amount",b?money(h-y+f):"—")),v.append(A),this.attr("payment-method")&&v.append(s([{label:r.payment,value:this.attr("payment-method")}])),this.attr("note")&&v.append(i("p","db-paper__note",this.attr("note"))),(a||this.attr("code-image-src"))&&_.append(this.code(this.attr("reference")));const N=this.action(this.attr("reference"));N&&(N.toggleAttribute("disabled",!b||this.hasAttribute("disabled")),_.append(N)),this.replace(n,_)}}customElements.get("db-receipt")||customElements.define("db-receipt",DbReceipt);export{DbReceipt};
@@ -1 +1 @@
1
- const e=["both","horizontal","vertical"],t=["bottom-right","bottom-left","top-right","top-left","right","bottom"];class DbResizablePanels extends HTMLElement{constructor(){super(...arguments),this.isResizing=!1,this.startSize={width:0,height:0},this.startPos={x:0,y:0},this.currentSize={width:0,height:0},this.rafId=0,this.pendingPoint=null,this.onMouseDown=e=>{e.preventDefault(),this.startResize(e.clientX,e.clientY),document.addEventListener("mousemove",this.onMouseMove),document.addEventListener("mouseup",this.onMouseUp)},this.onTouchStart=e=>{e.preventDefault();const t=e.touches[0];this.startResize(t.clientX,t.clientY),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd)},this.onMouseMove=e=>{this.scheduleResize(e.clientX,e.clientY)},this.onTouchMove=e=>{e.preventDefault();const t=e.touches[0];this.scheduleResize(t.clientX,t.clientY)},this.onMouseUp=()=>{this.endResize(),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp)},this.onTouchEnd=()=>{this.endResize(),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd)}}static get observedAttributes(){return["initial-width","initial-height","min-width","min-height","max-width","max-height","direction","handle-position","handle-size","handle-color","handle-hover-color","snap-to-grid","show-guides","show-size-indicator","show-constraints","show-border","shadow","background-color","border-radius"]}connectedCallback(){this.ensureStructure(),this.initializeSize(),this.render()}disconnectedCallback(){this.detachDragListeners(),this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}detachDragListeners(){document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd)}attributeChangedCallback(){this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const i=this.getAttribute(e);return""===i||"true"===i}getNumber(e,t){const i=Number(this.getAttribute(e)??t);return Number.isFinite(i)?i:t}getDirection(){const t=this.getAttribute("direction");return t&&e.includes(t)?t:"both"}getHandlePosition(){const e=this.getAttribute("handle-position");return e&&t.includes(e)?e:"bottom-right"}initializeSize(){const e=this.parentElement?.getBoundingClientRect();if(!e)return;const t=this.getAttribute("initial-width")||"100%",i=this.getAttribute("initial-height")||"100%";this.currentSize={width:"string"==typeof t&&t.endsWith("%")?e.width*Number(t.replace("%",""))/100:Number(t)||e.width,height:"string"==typeof i&&i.endsWith("%")?e.height*Number(i.replace("%",""))/100:Number(i)||e.height}}getMinSize(){return{width:this.getNumber("min-width",200),height:this.getNumber("min-height",150)}}getMaxSize(){const e=this.parentElement?.getBoundingClientRect();if(!e)return{width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY};const t=this.getAttribute("max-width")||"100vw",i=this.getAttribute("max-height")||"100vh",toSize=(e,t,i)=>{if("100vw"===e||"100vh"===e)return t;if("100%"===e)return i;const s=Number(e);return Number.isFinite(s)?s:Number.POSITIVE_INFINITY};return{width:toSize(t,window.innerWidth,e.width),height:toSize(i,window.innerHeight,e.height)}}ensureStructure(){if(this.container)return;this.container=document.createElement("div"),this.container.className="designbase-wc-resizable-panels",this.guidesEl=document.createElement("div"),this.guidesEl.className="designbase-wc-resizable-panels__guides";const e=document.createElement("div");e.className="designbase-wc-resizable-panels__guide designbase-wc-resizable-panels__guide--horizontal";const t=document.createElement("div");t.className="designbase-wc-resizable-panels__guide designbase-wc-resizable-panels__guide--vertical",this.guidesEl.append(e,t),this.sizeIndicatorEl=document.createElement("div"),this.sizeIndicatorEl.className="designbase-wc-resizable-panels__size-indicator",this.constraintsEl=document.createElement("div"),this.constraintsEl.className="designbase-wc-resizable-panels__constraints",this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-resizable-panels__content",this.handleEl=document.createElement("div"),this.handleEl.className="designbase-wc-resizable-panels__handle",this.handleEl.addEventListener("mousedown",this.onMouseDown),this.handleEl.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.container.append(this.guidesEl,this.sizeIndicatorEl,this.constraintsEl,this.contentEl,this.handleEl),this.replaceChildren(this.container)}startResize(e,t){this.isResizing=!0,this.startSize={...this.currentSize},this.startPos={x:e,y:t},this.dispatchEvent(new CustomEvent("db-resize-start",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render()}scheduleResize(e,t){this.pendingPoint={x:e,y:t},this.rafId||(this.rafId=requestAnimationFrame(()=>{this.rafId=0;const e=this.pendingPoint;this.pendingPoint=null,e&&this.applyResize(e.x,e.y)}))}applyResize(e,t){if(!this.isResizing)return;const i=e-this.startPos.x,s=t-this.startPos.y,n=this.getDirection();let h=this.startSize.width,r=this.startSize.height;"both"!==n&&"horizontal"!==n||(h+=i),"both"!==n&&"vertical"!==n||(r+=s);const o=this.getNumber("snap-to-grid",0);o>0&&(h=Math.round(h/o)*o,r=Math.round(r/o)*o);const a=this.getMinSize(),l=this.getMaxSize();h=Math.max(a.width,Math.min(l.width,h)),r=Math.max(a.height,Math.min(l.height,r)),this.currentSize={width:h,height:r},this.dispatchEvent(new CustomEvent("db-resize",{detail:this.currentSize,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-size-change",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render()}endResize(){this.isResizing&&(this.isResizing=!1,this.dispatchEvent(new CustomEvent("db-resize-end",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render())}renderHandleStyle(){if(!this.handleEl)return;const e=this.getDirection(),t=this.getHandlePosition(),i=this.getAttribute("handle-color"),s=this.getAttribute("handle-hover-color");i?this.handleEl.style.setProperty("--db-resize-handle-color",i):this.handleEl.style.removeProperty("--db-resize-handle-color"),s?this.handleEl.style.setProperty("--db-resize-handle-hover-color",s):this.handleEl.style.removeProperty("--db-resize-handle-hover-color"),this.handleEl.style.top="",this.handleEl.style.right="",this.handleEl.style.bottom="",this.handleEl.style.left="",this.handleEl.style.transform="",this.handleEl.style.width="",this.handleEl.style.height="",this.handleEl.style.backgroundColor="",this.handleEl.onmouseenter=null,this.handleEl.onmouseleave=null;let n=`corner-${t}`;"vertical"===e?n="edge-bottom":"horizontal"===e&&(n="edge-right"),this.handleEl.className=`designbase-wc-resizable-panels__handle designbase-wc-resizable-panels__handle--${n}`,this.handleEl.setAttribute("role","separator"),this.handleEl.setAttribute("aria-label","크기 조절"),this.handleEl.replaceChildren()}render(){if(this.ensureStructure(),!(this.container&&this.contentEl&&this.guidesEl&&this.sizeIndicatorEl&&this.constraintsEl))return;const e=["designbase-wc-resizable-panels",this.isResizing&&"designbase-wc-resizable-panels--resizing",this.getBool("show-border",!0)&&"designbase-wc-resizable-panels--border",this.getBool("shadow",!0)&&"designbase-wc-resizable-panels--shadow"].filter(Boolean).join(" ");this.container.className=e,this.container.style.width=`${this.currentSize.width}px`,this.container.style.height=`${this.currentSize.height}px`;const t=this.getAttribute("background-color");this.container.style.backgroundColor=t||"";const i=this.getAttribute("border-radius")||"8px";if(this.container.style.borderRadius=/^\d+$/.test(i)?`${i}px`:i,0===this.contentEl.children.length){const e=Array.from(this.childNodes).filter(e=>e!==this.container);this.contentEl.append(...e)}if(this.guidesEl.style.display=this.getBool("show-guides",!0)&&this.isResizing?"":"none",this.sizeIndicatorEl.style.display=this.getBool("show-size-indicator",!0)&&this.isResizing?"":"none",this.sizeIndicatorEl.textContent=`${Math.round(this.currentSize.width)} × ${Math.round(this.currentSize.height)}`,this.constraintsEl.style.display=this.getBool("show-constraints",!0)&&this.isResizing?"":"none",this.constraintsEl.replaceChildren(),"none"!==this.constraintsEl.style.display){const e=this.getMinSize(),t=this.getMaxSize();this.currentSize.width<=e.width&&this.constraintsEl.append(this.makeConstraint("최소 너비 도달","min")),this.currentSize.height<=e.height&&this.constraintsEl.append(this.makeConstraint("최소 높이 도달","min")),this.currentSize.width>=t.width&&this.constraintsEl.append(this.makeConstraint("최대 너비 도달","max")),this.currentSize.height>=t.height&&this.constraintsEl.append(this.makeConstraint("최대 높이 도달","max"))}this.renderHandleStyle()}makeConstraint(e,t){const i=document.createElement("div");return i.className=`designbase-wc-resizable-panels__constraint designbase-wc-resizable-panels__constraint--${t}`,i.textContent=e,i}}customElements.get("db-resizable-panels")||customElements.define("db-resizable-panels",DbResizablePanels);export{DbResizablePanels};
1
+ import{dbText as e}from"../core/i18n.js";const t=["both","horizontal","vertical"],i=["bottom-right","bottom-left","top-right","top-left","right","bottom"];class DbResizablePanels extends HTMLElement{constructor(){super(...arguments),this.isResizing=!1,this.startSize={width:0,height:0},this.startPos={x:0,y:0},this.currentSize={width:0,height:0},this.rafId=0,this.pendingPoint=null,this.onMouseDown=e=>{e.preventDefault(),this.startResize(e.clientX,e.clientY),document.addEventListener("mousemove",this.onMouseMove),document.addEventListener("mouseup",this.onMouseUp)},this.onTouchStart=e=>{e.preventDefault();const t=e.touches[0];this.startResize(t.clientX,t.clientY),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd)},this.onMouseMove=e=>{this.scheduleResize(e.clientX,e.clientY)},this.onTouchMove=e=>{e.preventDefault();const t=e.touches[0];this.scheduleResize(t.clientX,t.clientY)},this.onMouseUp=()=>{this.endResize(),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp)},this.onTouchEnd=()=>{this.endResize(),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd)}}static get observedAttributes(){return["initial-width","initial-height","min-width","min-height","max-width","max-height","direction","handle-position","handle-size","handle-color","handle-hover-color","snap-to-grid","show-guides","show-size-indicator","show-constraints","show-border","shadow","background-color","border-radius"]}connectedCallback(){this.ensureStructure(),this.initializeSize(),this.render()}disconnectedCallback(){this.detachDragListeners(),this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}detachDragListeners(){document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd)}attributeChangedCallback(){this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const i=this.getAttribute(e);return""===i||"true"===i}getNumber(e,t){const i=Number(this.getAttribute(e)??t);return Number.isFinite(i)?i:t}getDirection(){const e=this.getAttribute("direction");return e&&t.includes(e)?e:"both"}getHandlePosition(){const e=this.getAttribute("handle-position");return e&&i.includes(e)?e:"bottom-right"}initializeSize(){const e=this.parentElement?.getBoundingClientRect();if(!e)return;const t=this.getAttribute("initial-width")||"100%",i=this.getAttribute("initial-height")||"100%";this.currentSize={width:"string"==typeof t&&t.endsWith("%")?e.width*Number(t.replace("%",""))/100:Number(t)||e.width,height:"string"==typeof i&&i.endsWith("%")?e.height*Number(i.replace("%",""))/100:Number(i)||e.height}}getMinSize(){return{width:this.getNumber("min-width",200),height:this.getNumber("min-height",150)}}getMaxSize(){const e=this.parentElement?.getBoundingClientRect();if(!e)return{width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY};const t=this.getAttribute("max-width")||"100vw",i=this.getAttribute("max-height")||"100vh",toSize=(e,t,i)=>{if("100vw"===e||"100vh"===e)return t;if("100%"===e)return i;const s=Number(e);return Number.isFinite(s)?s:Number.POSITIVE_INFINITY};return{width:toSize(t,window.innerWidth,e.width),height:toSize(i,window.innerHeight,e.height)}}ensureStructure(){if(this.container)return;this.container=document.createElement("div"),this.container.className="designbase-wc-resizable-panels",this.guidesEl=document.createElement("div"),this.guidesEl.className="designbase-wc-resizable-panels__guides";const e=document.createElement("div");e.className="designbase-wc-resizable-panels__guide designbase-wc-resizable-panels__guide--horizontal";const t=document.createElement("div");t.className="designbase-wc-resizable-panels__guide designbase-wc-resizable-panels__guide--vertical",this.guidesEl.append(e,t),this.sizeIndicatorEl=document.createElement("div"),this.sizeIndicatorEl.className="designbase-wc-resizable-panels__size-indicator",this.constraintsEl=document.createElement("div"),this.constraintsEl.className="designbase-wc-resizable-panels__constraints",this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-resizable-panels__content",this.handleEl=document.createElement("div"),this.handleEl.className="designbase-wc-resizable-panels__handle",this.handleEl.addEventListener("mousedown",this.onMouseDown),this.handleEl.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.container.append(this.guidesEl,this.sizeIndicatorEl,this.constraintsEl,this.contentEl,this.handleEl),this.replaceChildren(this.container)}startResize(e,t){this.isResizing=!0,this.startSize={...this.currentSize},this.startPos={x:e,y:t},this.dispatchEvent(new CustomEvent("db-resize-start",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render()}scheduleResize(e,t){this.pendingPoint={x:e,y:t},this.rafId||(this.rafId=requestAnimationFrame(()=>{this.rafId=0;const e=this.pendingPoint;this.pendingPoint=null,e&&this.applyResize(e.x,e.y)}))}applyResize(e,t){if(!this.isResizing)return;const i=e-this.startPos.x,s=t-this.startPos.y,n=this.getDirection();let h=this.startSize.width,r=this.startSize.height;"both"!==n&&"horizontal"!==n||(h+=i),"both"!==n&&"vertical"!==n||(r+=s);const o=this.getNumber("snap-to-grid",0);o>0&&(h=Math.round(h/o)*o,r=Math.round(r/o)*o);const a=this.getMinSize(),l=this.getMaxSize();h=Math.max(a.width,Math.min(l.width,h)),r=Math.max(a.height,Math.min(l.height,r)),this.currentSize={width:h,height:r},this.dispatchEvent(new CustomEvent("db-resize",{detail:this.currentSize,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-size-change",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render()}endResize(){this.isResizing&&(this.isResizing=!1,this.dispatchEvent(new CustomEvent("db-resize-end",{detail:this.currentSize,bubbles:!0,composed:!0})),this.render())}renderHandleStyle(){if(!this.handleEl)return;const t=this.getDirection(),i=this.getHandlePosition(),s=this.getAttribute("handle-color"),n=this.getAttribute("handle-hover-color");s?this.handleEl.style.setProperty("--db-resize-handle-color",s):this.handleEl.style.removeProperty("--db-resize-handle-color"),n?this.handleEl.style.setProperty("--db-resize-handle-hover-color",n):this.handleEl.style.removeProperty("--db-resize-handle-hover-color"),this.handleEl.style.top="",this.handleEl.style.right="",this.handleEl.style.bottom="",this.handleEl.style.left="",this.handleEl.style.transform="",this.handleEl.style.width="",this.handleEl.style.height="",this.handleEl.style.backgroundColor="",this.handleEl.onmouseenter=null,this.handleEl.onmouseleave=null;let h=`corner-${i}`;"vertical"===t?h="edge-bottom":"horizontal"===t&&(h="edge-right"),this.handleEl.className=`designbase-wc-resizable-panels__handle designbase-wc-resizable-panels__handle--${h}`,this.handleEl.setAttribute("role","separator"),this.handleEl.setAttribute("aria-label",e("크기 조절")),this.handleEl.replaceChildren()}render(){if(this.ensureStructure(),!(this.container&&this.contentEl&&this.guidesEl&&this.sizeIndicatorEl&&this.constraintsEl))return;const e=["designbase-wc-resizable-panels",this.isResizing&&"designbase-wc-resizable-panels--resizing",this.getBool("show-border",!0)&&"designbase-wc-resizable-panels--border",this.getBool("shadow",!0)&&"designbase-wc-resizable-panels--shadow"].filter(Boolean).join(" ");this.container.className=e,this.container.style.width=`${this.currentSize.width}px`,this.container.style.height=`${this.currentSize.height}px`;const t=this.getAttribute("background-color");this.container.style.backgroundColor=t||"";const i=this.getAttribute("border-radius")||"8px";if(this.container.style.borderRadius=/^\d+$/.test(i)?`${i}px`:i,0===this.contentEl.children.length){const e=Array.from(this.childNodes).filter(e=>e!==this.container);this.contentEl.append(...e)}if(this.guidesEl.style.display=this.getBool("show-guides",!0)&&this.isResizing?"":"none",this.sizeIndicatorEl.style.display=this.getBool("show-size-indicator",!0)&&this.isResizing?"":"none",this.sizeIndicatorEl.textContent=`${Math.round(this.currentSize.width)} × ${Math.round(this.currentSize.height)}`,this.constraintsEl.style.display=this.getBool("show-constraints",!0)&&this.isResizing?"":"none",this.constraintsEl.replaceChildren(),"none"!==this.constraintsEl.style.display){const e=this.getMinSize(),t=this.getMaxSize();this.currentSize.width<=e.width&&this.constraintsEl.append(this.makeConstraint("최소 너비 도달","min")),this.currentSize.height<=e.height&&this.constraintsEl.append(this.makeConstraint("최소 높이 도달","min")),this.currentSize.width>=t.width&&this.constraintsEl.append(this.makeConstraint("최대 너비 도달","max")),this.currentSize.height>=t.height&&this.constraintsEl.append(this.makeConstraint("최대 높이 도달","max"))}this.renderHandleStyle()}makeConstraint(e,t){const i=document.createElement("div");return i.className=`designbase-wc-resizable-panels__constraint designbase-wc-resizable-panels__constraint--${t}`,i.textContent=e,i}}customElements.get("db-resizable-panels")||customElements.define("db-resizable-panels",DbResizablePanels);export{DbResizablePanels};
@@ -1 +1 @@
1
- import{getDbComponentIconSize as e,createDbIcon as t}from"./db-icons.js";import{SEARCH_BAR_SIZES as s,SEARCH_BAR_RECENT_LAYOUTS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbSearchBar extends HTMLElement{constructor(){super(...arguments),this.recentSearches=[],this.isFocused=!1,this.currentSuggestion=0,this.scrollParents=[]}static get observedAttributes(){return["value","default-value","placeholder","size","appearance","disabled","readonly","full-width","show-shortcut","shortcut-label","enable-recent-searches","recent-searches-key","recent-searches-layout","suggested-searches","suggestion-rolling-interval","categories","selected-category","search-results","empty-state-message"]}getResolvedSize(){const e=this.getAttribute("size")||"m";return s.includes(e)?e:"m"}getIconPx(){return e(this.getResolvedSize())}syncIcons(){const e=this.getIconPx();this.querySelector(".designbase-wc-search-bar__search-icon")?.replaceChildren(t("search",e)),this.clearButton?.replaceChildren(t("close",e))}hasInputValue(){return Boolean((this.input?.value??this.getAttribute("value")??"").trim())}get value(){return this.input?.value??this.getAttribute("value")??""}set value(e){this.setAttribute("value",e),this.input&&(this.input.value=e)}connectedCallback(){this.loadRecentSearches(),this.render(),this.bindGlobalShortcut()}disconnectedCallback(){this.clearSuggestionInterval(),this.unbindGlobalShortcut(),this.detachDropdownPortal(),this.blurTimer&&clearTimeout(this.blurTimer)}attributeChangedCallback(e){if(this.isConnected)return"value"===e&&this.input?(this.input.value=this.getAttribute("value")||"",this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),void this.syncSuggestionRolling()):"disabled"===e||"readonly"===e||"placeholder"===e||"show-shortcut"===e||"shortcut-label"===e||"selected-category"===e||"search-results"===e||"empty-state-message"===e||"suggested-searches"===e?(this.syncAttributes(),this.syncPlaceholder(),this.updateDropdown(),void this.syncSuggestionRolling()):"enable-recent-searches"===e||"recent-searches-key"===e?(this.loadRecentSearches(),void this.updateDropdown()):void("categories"!==e&&"recent-searches-layout"!==e?this.render():this.updateDropdown())}focus(){this.input?.focus()}parseJsonArray(e){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}getRecentSearchesKey(){return this.getAttribute("recent-searches-key")||"searchbar-recent-searches"}loadRecentSearches(){if(this.hasAttribute("enable-recent-searches"))try{const e=localStorage.getItem(this.getRecentSearchesKey());this.recentSearches=e?JSON.parse(e):[],Array.isArray(this.recentSearches)||(this.recentSearches=[])}catch{this.recentSearches=[]}else this.recentSearches=[]}saveRecentSearches(){try{localStorage.setItem(this.getRecentSearchesKey(),JSON.stringify(this.recentSearches))}catch{}}clearSuggestionInterval(){this.suggestionInterval&&(clearInterval(this.suggestionInterval),this.suggestionInterval=void 0)}syncSuggestionRolling(){this.clearSuggestionInterval();const e=this.parseJsonArray("suggested-searches"),t=this.hasInputValue(),s=Number(this.getAttribute("suggestion-rolling-interval")||5e3);e.length>0&&!t&&(this.suggestionInterval=setInterval(()=>{this.currentSuggestion=(this.currentSuggestion+1)%e.length,this.syncPlaceholder(),this.updateDropdown()},s))}syncPlaceholder(){if(!this.input)return;const e=this.parseJsonArray("suggested-searches"),t=this.hasInputValue(),s=this.getAttribute("placeholder")||"검색...";e.length>0&&!t?this.input.placeholder=e[this.currentSuggestion]||s:this.input.placeholder=s}syncValueState(){const e=this.hasInputValue();this.classList.toggle("designbase-wc-search-bar--has-value",e),this.clearButton&&(this.clearButton.hidden=!e||this.hasAttribute("disabled")||this.hasAttribute("readonly")),this.shortcutBadge&&(this.shortcutBadge.hidden=!this.hasAttribute("show-shortcut")||e||this.hasAttribute("disabled")||this.hasAttribute("readonly")),this.syncIcons()}syncAttributes(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("disabled"),a=this.hasAttribute("readonly"),n=this.hasAttribute("show-shortcut");this.className=["designbase-wc-search-bar",`designbase-wc-search-bar--${s.includes(e)?e:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",t&&"designbase-wc-search-bar--disabled",a&&"designbase-wc-search-bar--readonly",this.hasAttribute("full-width")&&"designbase-wc-search-bar--full-width",Boolean(this.hasInputValue())&&"designbase-wc-search-bar--has-value"].filter(Boolean).join(" "),this.input&&(this.input.disabled=t,this.input.readOnly=a),this.shortcutBadge&&(this.shortcutBadge.hidden=!n||this.hasInputValue()||t||a,this.shortcutBadge.textContent=this.getAttribute("shortcut-label")||"⌘K"),this.syncValueState()}bindGlobalShortcut(){this.unbindGlobalShortcut(),!this.hasAttribute("show-shortcut")||this.hasAttribute("disabled")||this.hasAttribute("readonly")||(this.globalKeyHandler=e=>{if(e.defaultPrevented||e.isComposing||!this.getClientRects().length)return;const t=e.metaKey||e.ctrlKey;let s="k";const a=(this.getAttribute("shortcut-label")||"⌘K").slice(-1).toLowerCase();a&&(s=a),t&&e.key.toLowerCase()===s&&(e.preventDefault(),this.focus())},window.addEventListener("keydown",this.globalKeyHandler))}unbindGlobalShortcut(){this.globalKeyHandler&&(window.removeEventListener("keydown",this.globalKeyHandler),this.globalKeyHandler=void 0)}positionDropdown(){if(!this.dropdown||this.dropdown.hidden)return;const e=this.getBoundingClientRect(),t=this.input?.getBoundingClientRect(),s=t??e;this.dropdown.style.top=`${s.bottom+4}px`,this.dropdown.style.left=`${e.left}px`,this.dropdown.style.width=`${e.width}px`,this.dropdown.style.right="auto"}bindRepositionListeners(){if(this.repositionHandler)return;this.repositionHandler=()=>{requestAnimationFrame(()=>this.positionDropdown())},window.addEventListener("scroll",this.repositionHandler,{capture:!0,passive:!0}),window.addEventListener("resize",this.repositionHandler),this.scrollParents=[];let e=this.parentElement;for(;e&&e!==document.body;){const t=getComputedStyle(e),s=/(auto|scroll|overlay)/.test(t.overflowY),a=/(auto|scroll|overlay)/.test(t.overflow);(s||a)&&e.scrollHeight>e.clientHeight&&(e.addEventListener("scroll",this.repositionHandler,{passive:!0}),this.scrollParents.push(e)),e=e.parentElement}}unbindRepositionListeners(){this.repositionHandler&&(window.removeEventListener("scroll",this.repositionHandler,!0),window.removeEventListener("resize",this.repositionHandler),this.scrollParents.forEach(e=>e.removeEventListener("scroll",this.repositionHandler)),this.scrollParents=[],this.repositionHandler=void 0)}attachDropdownPortal(){this.dropdown&&!this.dropdown.hidden&&(this.dropdown.classList.add("designbase-wc-search-bar__dropdown--portal"),this.dropdown.parentElement!==document.body&&document.body.append(this.dropdown),requestAnimationFrame(()=>this.positionDropdown()),this.repositionHandler||this.bindRepositionListeners())}detachDropdownPortal(){this.unbindRepositionListeners(),this.dropdown&&(this.dropdown.classList.remove("designbase-wc-search-bar__dropdown--portal"),this.dropdown.style.top="",this.dropdown.style.left="",this.dropdown.style.width="",this.dropdown.style.right="",this.dropdown.parentElement===document.body&&this.isConnected&&this.append(this.dropdown))}shouldShowDropdown(){const e=this.hasInputValue(),t=this.parseJsonArray("categories"),s=this.parseJsonArray("suggested-searches"),a=this.getAttribute("search-results"),n=this.getAttribute("empty-state-message");return this.isFocused&&(t.length>0||this.hasAttribute("enable-recent-searches")&&this.recentSearches.length>0&&!e||s.length>0&&!e||null!==a&&e||Boolean(n)&&!e&&(!this.hasAttribute("enable-recent-searches")||0===this.recentSearches.length)&&0===s.length)}formatSearchResult(e){if("string"==typeof e||"number"==typeof e)return String(e);if(e&&"object"==typeof e){const t=e;if("string"==typeof t.title)return t.title;if("string"==typeof t.label)return t.label}return String(e)}handleSearch(e){const t=(e??this.value).trim();t&&(this.dispatchEvent(new CustomEvent("db-search",{detail:{value:t},bubbles:!0,composed:!0})),this.hasAttribute("enable-recent-searches")&&(this.recentSearches=[t,...this.recentSearches.filter(e=>e!==t)].slice(0,10),this.saveRecentSearches(),this.updateDropdown()))}updateDropdown(){if(!this.dropdown)return;const s=this.shouldShowDropdown();if(this.dropdown.hidden=!s,this.classList.toggle("designbase-wc-search-bar--dropdown-open",s),!s)return this.dropdown.replaceChildren(),void this.detachDropdownPortal();this.dropdown.replaceChildren();const n=this.hasInputValue(),r=this.parseJsonArray("categories"),i=this.parseJsonArray("suggested-searches"),o=this.getAttribute("selected-category")||"",c=this.parseJsonArray("search-results"),h=this.getAttribute("empty-state-message"),d=a.includes(this.getAttribute("recent-searches-layout")||"vertical")&&this.getAttribute("recent-searches-layout")||"vertical";if(r.length>0){const e=document.createElement("div");e.className="designbase-wc-search-bar__categories",r.forEach(t=>{const s=document.createElement("db-chip");s.setAttribute("label",t),s.setAttribute("size","s"),s.setAttribute("variant",t===o?"primary":"default"),s.setAttribute("clickable",""),s.addEventListener("mousedown",e=>{e.preventDefault(),this.setAttribute("selected-category",t),this.dispatchEvent(new CustomEvent("db-category-change",{detail:{category:t},bubbles:!0,composed:!0})),this.updateDropdown()}),e.append(s)}),this.dropdown.append(e)}if(n&&this.hasAttribute("search-results")){const e=document.createElement("div");if(e.className="designbase-wc-search-bar__results",c.length>0){const t=document.createElement("ul");t.className="designbase-wc-search-bar__results-list",c.forEach((e,s)=>{const a=document.createElement("li");a.className="designbase-wc-search-bar__result-item",a.textContent=this.formatSearchResult(e),a.addEventListener("mousedown",t=>{t.preventDefault(),this.isFocused=!1,this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-search-result-click",{detail:{result:e,index:s},bubbles:!0,composed:!0}))}),t.append(a)}),e.append(t)}else{const t=document.createElement("div");t.className="designbase-wc-search-bar__results-empty",t.textContent="검색 결과가 없습니다.",e.append(t)}return this.dropdown.append(e),void this.attachDropdownPortal()}if(this.hasAttribute("enable-recent-searches")&&!n&&this.recentSearches.length>0){const s=document.createElement("div");s.className=`designbase-wc-search-bar__recent-searches designbase-wc-search-bar__recent-searches--${d}`;const a=document.createElement("div");a.className="designbase-wc-search-bar__recent-header";const n=document.createElement("span");n.className="designbase-wc-search-bar__recent-title",n.textContent="최근 검색어";const r=document.createElement("button");r.type="button",r.className="designbase-wc-search-bar__clear-all-button",r.setAttribute("aria-label","모든 최근 검색어 삭제"),r.textContent="전체 삭제",r.addEventListener("mousedown",e=>{e.preventDefault(),this.recentSearches=[];try{localStorage.removeItem(this.getRecentSearchesKey())}catch{}this.updateDropdown()}),a.append(n,r);const i=document.createElement("div");i.className="designbase-wc-search-bar__recent-list",this.recentSearches.forEach(s=>{const a=document.createElement("div");a.className="designbase-wc-search-bar__recent-item";const n=document.createElement("button");n.type="button",n.className="designbase-wc-search-bar__recent-search-button",n.textContent=s,n.addEventListener("mousedown",e=>{if(e.preventDefault(),!this.input)return;this.input.value=s,this.setAttribute("value",s),this.syncValueState(),this.syncPlaceholder(),this.handleSearch(s);const t={value:s};this.dispatchEvent(new CustomEvent("db-input",{detail:t,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:t,bubbles:!0,composed:!0})),this.isFocused=!1,this.updateDropdown()});const r=document.createElement("button");r.type="button",r.className="designbase-wc-search-bar__recent-remove-button",r.setAttribute("aria-label",`${s} 삭제`),r.append(t("close",e("s"))),r.addEventListener("mousedown",e=>{e.preventDefault(),this.recentSearches=this.recentSearches.filter(e=>e!==s),this.saveRecentSearches(),this.updateDropdown()}),a.append(n,r),i.append(a)}),s.append(a,i),this.dropdown.append(s)}if(i.length>0&&!n){const e=document.createElement("div");e.className="designbase-wc-search-bar__suggestions";const t=document.createElement("div");t.className="designbase-wc-search-bar__suggestions-header";const s=document.createElement("span");s.className="designbase-wc-search-bar__suggestions-title",s.textContent="추천 검색어",t.append(s);const a=document.createElement("div");a.className="designbase-wc-search-bar__suggestions-list",i.forEach((e,t)=>{const s=document.createElement("button");s.type="button",s.className=["designbase-wc-search-bar__suggestion-item",t===this.currentSuggestion&&"designbase-wc-search-bar__suggestion-item--active"].filter(Boolean).join(" "),s.textContent=e,s.addEventListener("mousedown",t=>{if(t.preventDefault(),!this.input)return;this.clearSuggestionInterval(),this.input.value=e,this.setAttribute("value",e),this.syncValueState(),this.syncPlaceholder(),this.handleSearch(e);const s={value:e};this.dispatchEvent(new CustomEvent("db-input",{detail:s,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:s,bubbles:!0,composed:!0})),this.isFocused=!1,this.updateDropdown()}),a.append(s)}),e.append(t,a),this.dropdown.append(e)}if(h&&!n&&(!this.hasAttribute("enable-recent-searches")||0===this.recentSearches.length)&&0===i.length){const e=document.createElement("div");e.className="designbase-wc-search-bar__empty-state",e.textContent=h,this.dropdown.append(e)}this.attachDropdownPortal()}render(){const e=this.getAttribute("size")||"m",a=this.hasAttribute("disabled"),n=this.hasAttribute("readonly"),r=this.hasAttribute("full-width"),i=this.hasAttribute("show-shortcut"),o=this.getAttribute("value")??this.getAttribute("default-value")??"",c=Boolean(o.trim()),h=this.getIconPx();this.className=["designbase-wc-search-bar",`designbase-wc-search-bar--${s.includes(e)?e:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",a&&"designbase-wc-search-bar--disabled",n&&"designbase-wc-search-bar--readonly",r&&"designbase-wc-search-bar--full-width",c&&"designbase-wc-search-bar--has-value",this.shouldShowDropdown()&&"designbase-wc-search-bar--dropdown-open"].filter(Boolean).join(" "),this.setAttribute("role","search"),this.clearSuggestionInterval(),this.detachDropdownPortal(),this.replaceChildren();const d=document.createElement("div");d.className="designbase-wc-search-bar__container";const l=document.createElement("div");l.className="designbase-wc-search-bar__search-icon",l.setAttribute("aria-hidden","true"),l.append(t("search",h));const u=document.createElement("input");if(u.type="text",u.className="designbase-wc-search-bar__input",u.value=o,u.disabled=a,u.readOnly=n,u.setAttribute("aria-label","검색어 입력"),this.input=u,i){const t=document.createElement("db-badge");t.className="designbase-wc-search-bar__shortcut-badge",t.setAttribute("size","l"===e?"m":"s"),t.setAttribute("variant","secondary"),t.setAttribute("type","text"),t.setAttribute("aria-hidden","true"),t.textContent=this.getAttribute("shortcut-label")||"⌘K",t.hidden=c||a||n,this.shortcutBadge=t,d.append(l,u,t)}else d.append(l,u);const b=document.createElement("button");b.type="button",b.className="designbase-wc-search-bar__clear-button",b.setAttribute("aria-label","검색어 지우기"),b.hidden=!c||a||n,b.append(t("close",h)),this.clearButton=b,d.append(b);const p=document.createElement("div");p.className="designbase-wc-search-bar__dropdown",p.hidden=!0,p.addEventListener("mousedown",e=>{e.preventDefault()}),this.dropdown=p,u.addEventListener("input",()=>{this.setAttribute("value",u.value),this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),this.syncSuggestionRolling();const e={value:u.value};this.dispatchEvent(new CustomEvent("db-input",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0}))}),u.addEventListener("keydown",e=>{"Enter"===e.key&&this.handleSearch()}),u.addEventListener("focus",()=>{this.isFocused=!0,this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-focus",{bubbles:!0,composed:!0}))}),u.addEventListener("blur",()=>{this.isFocused=!1,this.blurTimer&&clearTimeout(this.blurTimer),this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-blur",{bubbles:!0,composed:!0}))}),b.addEventListener("click",()=>{u.value="",this.setAttribute("value",""),this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),this.syncSuggestionRolling(),u.focus(),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0}));const e={value:""};this.dispatchEvent(new CustomEvent("db-input",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0}))}),this.append(d,p),this.syncIcons(),this.syncPlaceholder(),this.syncSuggestionRolling(),this.bindGlobalShortcut(),this.updateDropdown()}}customElements.get("db-search-bar")||customElements.define("db-search-bar",DbSearchBar);export{DbSearchBar};
1
+ import{dbText as e,dbFormat as t}from"../core/i18n.js";import{getDbComponentIconSize as s,createDbIcon as a}from"./db-icons.js";import{SEARCH_BAR_SIZES as n,SEARCH_BAR_RECENT_LAYOUTS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbSearchBar extends HTMLElement{constructor(){super(...arguments),this.recentSearches=[],this.isFocused=!1,this.currentSuggestion=0,this.scrollParents=[]}static get observedAttributes(){return["value","default-value","placeholder","size","appearance","disabled","readonly","full-width","show-shortcut","shortcut-label","enable-recent-searches","recent-searches-key","recent-searches-layout","suggested-searches","suggestion-rolling-interval","categories","selected-category","search-results","empty-state-message"]}getResolvedSize(){const e=this.getAttribute("size")||"m";return n.includes(e)?e:"m"}getIconPx(){return s(this.getResolvedSize())}syncIcons(){const e=this.getIconPx();this.querySelector(".designbase-wc-search-bar__search-icon")?.replaceChildren(a("search",e)),this.clearButton?.replaceChildren(a("close",e))}hasInputValue(){return Boolean((this.input?.value??this.getAttribute("value")??"").trim())}get value(){return this.input?.value??this.getAttribute("value")??""}set value(e){this.setAttribute("value",e),this.input&&(this.input.value=e)}connectedCallback(){this.loadRecentSearches(),this.render(),this.bindGlobalShortcut()}disconnectedCallback(){this.clearSuggestionInterval(),this.unbindGlobalShortcut(),this.detachDropdownPortal(),this.blurTimer&&clearTimeout(this.blurTimer)}attributeChangedCallback(e){if(this.isConnected)return"value"===e&&this.input?(this.input.value=this.getAttribute("value")||"",this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),void this.syncSuggestionRolling()):"disabled"===e||"readonly"===e||"placeholder"===e||"show-shortcut"===e||"shortcut-label"===e||"selected-category"===e||"search-results"===e||"empty-state-message"===e||"suggested-searches"===e?(this.syncAttributes(),this.syncPlaceholder(),this.updateDropdown(),void this.syncSuggestionRolling()):"enable-recent-searches"===e||"recent-searches-key"===e?(this.loadRecentSearches(),void this.updateDropdown()):void("categories"!==e&&"recent-searches-layout"!==e?this.render():this.updateDropdown())}focus(){this.input?.focus()}parseJsonArray(e){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}getRecentSearchesKey(){return this.getAttribute("recent-searches-key")||"searchbar-recent-searches"}loadRecentSearches(){if(this.hasAttribute("enable-recent-searches"))try{const e=localStorage.getItem(this.getRecentSearchesKey());this.recentSearches=e?JSON.parse(e):[],Array.isArray(this.recentSearches)||(this.recentSearches=[])}catch{this.recentSearches=[]}else this.recentSearches=[]}saveRecentSearches(){try{localStorage.setItem(this.getRecentSearchesKey(),JSON.stringify(this.recentSearches))}catch{}}clearSuggestionInterval(){this.suggestionInterval&&(clearInterval(this.suggestionInterval),this.suggestionInterval=void 0)}syncSuggestionRolling(){this.clearSuggestionInterval();const e=this.parseJsonArray("suggested-searches"),t=this.hasInputValue(),s=Number(this.getAttribute("suggestion-rolling-interval")||5e3);e.length>0&&!t&&(this.suggestionInterval=setInterval(()=>{this.currentSuggestion=(this.currentSuggestion+1)%e.length,this.syncPlaceholder(),this.updateDropdown()},s))}syncPlaceholder(){if(!this.input)return;const e=this.parseJsonArray("suggested-searches"),t=this.hasInputValue(),s=this.getAttribute("placeholder")||"검색...";e.length>0&&!t?this.input.placeholder=e[this.currentSuggestion]||s:this.input.placeholder=s}syncValueState(){const e=this.hasInputValue();this.classList.toggle("designbase-wc-search-bar--has-value",e),this.clearButton&&(this.clearButton.hidden=!e||this.hasAttribute("disabled")||this.hasAttribute("readonly")),this.shortcutBadge&&(this.shortcutBadge.hidden=!this.hasAttribute("show-shortcut")||e||this.hasAttribute("disabled")||this.hasAttribute("readonly")),this.syncIcons()}syncAttributes(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("disabled"),s=this.hasAttribute("readonly"),a=this.hasAttribute("show-shortcut");this.className=["designbase-wc-search-bar",`designbase-wc-search-bar--${n.includes(e)?e:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",t&&"designbase-wc-search-bar--disabled",s&&"designbase-wc-search-bar--readonly",this.hasAttribute("full-width")&&"designbase-wc-search-bar--full-width",Boolean(this.hasInputValue())&&"designbase-wc-search-bar--has-value"].filter(Boolean).join(" "),this.input&&(this.input.disabled=t,this.input.readOnly=s),this.shortcutBadge&&(this.shortcutBadge.hidden=!a||this.hasInputValue()||t||s,this.shortcutBadge.textContent=this.getAttribute("shortcut-label")||"⌘K"),this.syncValueState()}bindGlobalShortcut(){this.unbindGlobalShortcut(),!this.hasAttribute("show-shortcut")||this.hasAttribute("disabled")||this.hasAttribute("readonly")||(this.globalKeyHandler=e=>{if(e.defaultPrevented||e.isComposing||!this.getClientRects().length)return;const t=e.metaKey||e.ctrlKey;let s="k";const a=(this.getAttribute("shortcut-label")||"⌘K").slice(-1).toLowerCase();a&&(s=a),t&&e.key.toLowerCase()===s&&(e.preventDefault(),this.focus())},window.addEventListener("keydown",this.globalKeyHandler))}unbindGlobalShortcut(){this.globalKeyHandler&&(window.removeEventListener("keydown",this.globalKeyHandler),this.globalKeyHandler=void 0)}positionDropdown(){if(!this.dropdown||this.dropdown.hidden)return;const e=this.getBoundingClientRect(),t=this.input?.getBoundingClientRect(),s=t??e;this.dropdown.style.top=`${s.bottom+4}px`,this.dropdown.style.left=`${e.left}px`,this.dropdown.style.width=`${e.width}px`,this.dropdown.style.right="auto"}bindRepositionListeners(){if(this.repositionHandler)return;this.repositionHandler=()=>{requestAnimationFrame(()=>this.positionDropdown())},window.addEventListener("scroll",this.repositionHandler,{capture:!0,passive:!0}),window.addEventListener("resize",this.repositionHandler),this.scrollParents=[];let e=this.parentElement;for(;e&&e!==document.body;){const t=getComputedStyle(e),s=/(auto|scroll|overlay)/.test(t.overflowY),a=/(auto|scroll|overlay)/.test(t.overflow);(s||a)&&e.scrollHeight>e.clientHeight&&(e.addEventListener("scroll",this.repositionHandler,{passive:!0}),this.scrollParents.push(e)),e=e.parentElement}}unbindRepositionListeners(){this.repositionHandler&&(window.removeEventListener("scroll",this.repositionHandler,!0),window.removeEventListener("resize",this.repositionHandler),this.scrollParents.forEach(e=>e.removeEventListener("scroll",this.repositionHandler)),this.scrollParents=[],this.repositionHandler=void 0)}attachDropdownPortal(){this.dropdown&&!this.dropdown.hidden&&(this.dropdown.classList.add("designbase-wc-search-bar__dropdown--portal"),this.dropdown.parentElement!==document.body&&document.body.append(this.dropdown),requestAnimationFrame(()=>this.positionDropdown()),this.repositionHandler||this.bindRepositionListeners())}detachDropdownPortal(){this.unbindRepositionListeners(),this.dropdown&&(this.dropdown.classList.remove("designbase-wc-search-bar__dropdown--portal"),this.dropdown.style.top="",this.dropdown.style.left="",this.dropdown.style.width="",this.dropdown.style.right="",this.dropdown.parentElement===document.body&&this.isConnected&&this.append(this.dropdown))}shouldShowDropdown(){const e=this.hasInputValue(),t=this.parseJsonArray("categories"),s=this.parseJsonArray("suggested-searches"),a=this.getAttribute("search-results"),n=this.getAttribute("empty-state-message");return this.isFocused&&(t.length>0||this.hasAttribute("enable-recent-searches")&&this.recentSearches.length>0&&!e||s.length>0&&!e||null!==a&&e||Boolean(n)&&!e&&(!this.hasAttribute("enable-recent-searches")||0===this.recentSearches.length)&&0===s.length)}formatSearchResult(e){if("string"==typeof e||"number"==typeof e)return String(e);if(e&&"object"==typeof e){const t=e;if("string"==typeof t.title)return t.title;if("string"==typeof t.label)return t.label}return String(e)}handleSearch(e){const t=(e??this.value).trim();t&&(this.dispatchEvent(new CustomEvent("db-search",{detail:{value:t},bubbles:!0,composed:!0})),this.hasAttribute("enable-recent-searches")&&(this.recentSearches=[t,...this.recentSearches.filter(e=>e!==t)].slice(0,10),this.saveRecentSearches(),this.updateDropdown()))}updateDropdown(){if(!this.dropdown)return;const n=this.shouldShowDropdown();if(this.dropdown.hidden=!n,this.classList.toggle("designbase-wc-search-bar--dropdown-open",n),!n)return this.dropdown.replaceChildren(),void this.detachDropdownPortal();this.dropdown.replaceChildren();const i=this.hasInputValue(),o=this.parseJsonArray("categories"),c=this.parseJsonArray("suggested-searches"),h=this.getAttribute("selected-category")||"",d=this.parseJsonArray("search-results"),l=this.getAttribute("empty-state-message"),u=r.includes(this.getAttribute("recent-searches-layout")||"vertical")&&this.getAttribute("recent-searches-layout")||"vertical";if(o.length>0){const e=document.createElement("div");e.className="designbase-wc-search-bar__categories",o.forEach(t=>{const s=document.createElement("db-chip");s.setAttribute("label",t),s.setAttribute("size","s"),s.setAttribute("variant",t===h?"primary":"default"),s.setAttribute("clickable",""),s.addEventListener("mousedown",e=>{e.preventDefault(),this.setAttribute("selected-category",t),this.dispatchEvent(new CustomEvent("db-category-change",{detail:{category:t},bubbles:!0,composed:!0})),this.updateDropdown()}),e.append(s)}),this.dropdown.append(e)}if(i&&this.hasAttribute("search-results")){const t=document.createElement("div");if(t.className="designbase-wc-search-bar__results",d.length>0){const e=document.createElement("ul");e.className="designbase-wc-search-bar__results-list",d.forEach((t,s)=>{const a=document.createElement("li");a.className="designbase-wc-search-bar__result-item",a.textContent=this.formatSearchResult(t),a.addEventListener("mousedown",e=>{e.preventDefault(),this.isFocused=!1,this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-search-result-click",{detail:{result:t,index:s},bubbles:!0,composed:!0}))}),e.append(a)}),t.append(e)}else{const s=document.createElement("div");s.className="designbase-wc-search-bar__results-empty",s.textContent=e("검색 결과가 없습니다."),t.append(s)}return this.dropdown.append(t),void this.attachDropdownPortal()}if(this.hasAttribute("enable-recent-searches")&&!i&&this.recentSearches.length>0){const n=document.createElement("div");n.className=`designbase-wc-search-bar__recent-searches designbase-wc-search-bar__recent-searches--${u}`;const r=document.createElement("div");r.className="designbase-wc-search-bar__recent-header";const i=document.createElement("span");i.className="designbase-wc-search-bar__recent-title",i.textContent=e("최근 검색어");const o=document.createElement("button");o.type="button",o.className="designbase-wc-search-bar__clear-all-button",o.setAttribute("aria-label",e("모든 최근 검색어 삭제")),o.textContent=e("전체 삭제"),o.addEventListener("mousedown",e=>{e.preventDefault(),this.recentSearches=[];try{localStorage.removeItem(this.getRecentSearchesKey())}catch{}this.updateDropdown()}),r.append(i,o);const c=document.createElement("div");c.className="designbase-wc-search-bar__recent-list",this.recentSearches.forEach(e=>{const n=document.createElement("div");n.className="designbase-wc-search-bar__recent-item";const r=document.createElement("button");r.type="button",r.className="designbase-wc-search-bar__recent-search-button",r.textContent=e,r.addEventListener("mousedown",t=>{if(t.preventDefault(),!this.input)return;this.input.value=e,this.setAttribute("value",e),this.syncValueState(),this.syncPlaceholder(),this.handleSearch(e);const s={value:e};this.dispatchEvent(new CustomEvent("db-input",{detail:s,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:s,bubbles:!0,composed:!0})),this.isFocused=!1,this.updateDropdown()});const i=document.createElement("button");i.type="button",i.className="designbase-wc-search-bar__recent-remove-button",i.setAttribute("aria-label",t("{0} 삭제",[e])),i.append(a("close",s("s"))),i.addEventListener("mousedown",t=>{t.preventDefault(),this.recentSearches=this.recentSearches.filter(t=>t!==e),this.saveRecentSearches(),this.updateDropdown()}),n.append(r,i),c.append(n)}),n.append(r,c),this.dropdown.append(n)}if(c.length>0&&!i){const t=document.createElement("div");t.className="designbase-wc-search-bar__suggestions";const s=document.createElement("div");s.className="designbase-wc-search-bar__suggestions-header";const a=document.createElement("span");a.className="designbase-wc-search-bar__suggestions-title",a.textContent=e("추천 검색어"),s.append(a);const n=document.createElement("div");n.className="designbase-wc-search-bar__suggestions-list",c.forEach((e,t)=>{const s=document.createElement("button");s.type="button",s.className=["designbase-wc-search-bar__suggestion-item",t===this.currentSuggestion&&"designbase-wc-search-bar__suggestion-item--active"].filter(Boolean).join(" "),s.textContent=e,s.addEventListener("mousedown",t=>{if(t.preventDefault(),!this.input)return;this.clearSuggestionInterval(),this.input.value=e,this.setAttribute("value",e),this.syncValueState(),this.syncPlaceholder(),this.handleSearch(e);const s={value:e};this.dispatchEvent(new CustomEvent("db-input",{detail:s,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:s,bubbles:!0,composed:!0})),this.isFocused=!1,this.updateDropdown()}),n.append(s)}),t.append(s,n),this.dropdown.append(t)}if(l&&!i&&(!this.hasAttribute("enable-recent-searches")||0===this.recentSearches.length)&&0===c.length){const e=document.createElement("div");e.className="designbase-wc-search-bar__empty-state",e.textContent=l,this.dropdown.append(e)}this.attachDropdownPortal()}render(){const t=this.getAttribute("size")||"m",s=this.hasAttribute("disabled"),r=this.hasAttribute("readonly"),i=this.hasAttribute("full-width"),o=this.hasAttribute("show-shortcut"),c=this.getAttribute("value")??this.getAttribute("default-value")??"",h=Boolean(c.trim()),d=this.getIconPx();this.className=["designbase-wc-search-bar",`designbase-wc-search-bar--${n.includes(t)?t:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",s&&"designbase-wc-search-bar--disabled",r&&"designbase-wc-search-bar--readonly",i&&"designbase-wc-search-bar--full-width",h&&"designbase-wc-search-bar--has-value",this.shouldShowDropdown()&&"designbase-wc-search-bar--dropdown-open"].filter(Boolean).join(" "),this.setAttribute("role","search"),this.clearSuggestionInterval(),this.detachDropdownPortal(),this.replaceChildren();const l=document.createElement("div");l.className="designbase-wc-search-bar__container";const u=document.createElement("div");u.className="designbase-wc-search-bar__search-icon",u.setAttribute("aria-hidden","true"),u.append(a("search",d));const b=document.createElement("input");if(b.type="text",b.className="designbase-wc-search-bar__input",b.value=c,b.disabled=s,b.readOnly=r,b.setAttribute("aria-label",e("검색어 입력")),this.input=b,o){const e=document.createElement("db-badge");e.className="designbase-wc-search-bar__shortcut-badge",e.setAttribute("size","l"===t?"m":"s"),e.setAttribute("variant","secondary"),e.setAttribute("type","text"),e.setAttribute("aria-hidden","true"),e.textContent=this.getAttribute("shortcut-label")||"⌘K",e.hidden=h||s||r,this.shortcutBadge=e,l.append(u,b,e)}else l.append(u,b);const p=document.createElement("button");p.type="button",p.className="designbase-wc-search-bar__clear-button",p.setAttribute("aria-label",e("검색어 지우기")),p.hidden=!h||s||r,p.append(a("close",d)),this.clearButton=p,l.append(p);const g=document.createElement("div");g.className="designbase-wc-search-bar__dropdown",g.hidden=!0,g.addEventListener("mousedown",e=>{e.preventDefault()}),this.dropdown=g,b.addEventListener("input",()=>{this.setAttribute("value",b.value),this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),this.syncSuggestionRolling();const e={value:b.value};this.dispatchEvent(new CustomEvent("db-input",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0}))}),b.addEventListener("keydown",e=>{"Enter"===e.key&&this.handleSearch()}),b.addEventListener("focus",()=>{this.isFocused=!0,this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-focus",{bubbles:!0,composed:!0}))}),b.addEventListener("blur",()=>{this.isFocused=!1,this.blurTimer&&clearTimeout(this.blurTimer),this.updateDropdown(),this.dispatchEvent(new CustomEvent("db-blur",{bubbles:!0,composed:!0}))}),p.addEventListener("click",()=>{b.value="",this.setAttribute("value",""),this.syncValueState(),this.syncPlaceholder(),this.updateDropdown(),this.syncSuggestionRolling(),b.focus(),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0}));const e={value:""};this.dispatchEvent(new CustomEvent("db-input",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0}))}),this.append(l,g),this.syncIcons(),this.syncPlaceholder(),this.syncSuggestionRolling(),this.bindGlobalShortcut(),this.updateDropdown()}}customElements.get("db-search-bar")||customElements.define("db-search-bar",DbSearchBar);export{DbSearchBar};
@@ -5,10 +5,8 @@ declare class DbSectionTestimonials extends HTMLElement {
5
5
  private innerEl?;
6
6
  private headerEl?;
7
7
  private contentEl?;
8
- private carouselViewport?;
9
- private carouselTrack?;
8
+ private carouselEngine?;
10
9
  private carouselIndicator?;
11
- private resizeObserver?;
12
10
  connectedCallback(): void;
13
11
  disconnectedCallback(): void;
14
12
  attributeChangedCallback(): void;
@@ -19,7 +17,6 @@ declare class DbSectionTestimonials extends HTMLElement {
19
17
  private createTestimonialEl;
20
18
  private updateHeader;
21
19
  private clampCarouselIndex;
22
- private updateCarouselTransform;
23
20
  private goToCarouselSlide;
24
21
  private renderGrid;
25
22
  private renderCarousel;
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";import{applySectionBlockHeader as t}from"./section-block-header-utils.js";import{syncMarketingBlockHost as s}from"./marketing-block-host-utils.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SECTION_ALIGNS as r,SECTION_TESTIMONIALS_VARIANTS as a,SECTION_TESTIMONIALS_SIZES as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const o="designbase-wc-section-testimonials";class DbSectionTestimonials extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.carouselIndex=0}static get observedAttributes(){return["headline","subtitle","description","badge","items","variant","columns","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}disconnectedCallback(){this.resizeObserver?.disconnect(),this.resizeObserver=void 0}attributeChangedCallback(){this.built&&(this.carouselIndex=0,this.updateUI())}parseItems(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}buildHeader(e){this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header";const t=document.createElement("db-badge");t.className="designbase-wc-section-block-header__badge",t.hidden=!0,t.dataset.role="badge";const s=document.createElement("h2");s.className="designbase-wc-section-block-header__headline",s.dataset.role="headline";const i=document.createElement("p");i.className="designbase-wc-section-block-header__subtitle",i.dataset.role="subtitle";const r=document.createElement("p");r.className="designbase-wc-section-block-header__description",r.dataset.role="description",this.headerEl.append(t,s,i,r),e.append(this.headerEl)}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${o}__inner`,this.buildHeader(this.innerEl),this.contentEl=document.createElement("div"),this.contentEl.className=`${o}__grid`,this.innerEl.append(this.contentEl),this.append(this.innerEl)}createTestimonialEl(e){const t=document.createElement("db-testimonial");return t.setAttribute("variant","card"),t.setAttribute("quote",e.quote),t.setAttribute("author",e.author),e.role&&t.setAttribute("role",e.role),e.company&&t.setAttribute("company",e.company),e.avatar&&t.setAttribute("avatar",e.avatar),null!=e.rating&&t.setAttribute("rating",String(e.rating)),t}updateHeader(){this.headerEl&&t(this.headerEl,{headline:this.getAttribute("headline")||"고객 후기",subtitle:this.getAttribute("subtitle")||"",description:this.getAttribute("description")||"",badge:this.parseBadge(),align:i(this.getAttribute("align"),r,"center")})}clampCarouselIndex(e){e<=0?this.carouselIndex=0:(this.carouselIndex>=e&&(this.carouselIndex=0),this.carouselIndex<0&&(this.carouselIndex=0))}updateCarouselTransform(){if(!this.carouselViewport||!this.carouselTrack)return;const e=this.carouselViewport.clientWidth;this.carouselTrack.style.transform=`translate3d(-${this.carouselIndex*e}px, 0, 0)`,this.carouselIndicator&&this.carouselIndicator.setAttribute("current",String(this.carouselIndex))}goToCarouselSlide(e,t){t<=0||(this.carouselIndex=Math.max(0,Math.min(e,t-1)),this.updateCarouselTransform())}renderGrid(e){this.contentEl&&(this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.carouselViewport=void 0,this.carouselTrack=void 0,this.carouselIndicator=void 0,this.contentEl.className=`${o}__grid`,this.contentEl.replaceChildren(),e.forEach(e=>{this.contentEl.append(this.createTestimonialEl(e))}))}renderCarousel(t){if(!this.contentEl)return;if(this.contentEl.replaceChildren(),this.contentEl.className=`${o}__carousel`,this.clampCarouselIndex(t.length),0===t.length)return;const s=document.createElement("div");s.className=`${o}__carousel-viewport`;const i=document.createElement("div");if(i.className=`${o}__carousel-track`,t.forEach(e=>{const t=document.createElement("div");t.className=`${o}__carousel-slide`,t.append(this.createTestimonialEl(e)),i.append(t)}),s.append(i),this.carouselViewport=s,this.carouselTrack=i,t.length>1){const i=document.createElement("button");i.type="button",i.className=`${o}__carousel-nav ${o}__carousel-nav--prev`,i.setAttribute("aria-label","이전 후기"),i.append(e("chevron-left",20)),i.addEventListener("click",()=>{const e=this.carouselIndex-1;this.goToCarouselSlide(e<0?t.length-1:e,t.length)});const r=document.createElement("button");r.type="button",r.className=`${o}__carousel-nav ${o}__carousel-nav--next`,r.setAttribute("aria-label","다음 후기"),r.append(e("chevron-right",20)),r.addEventListener("click",()=>{const e=this.carouselIndex+1;this.goToCarouselSlide(e>=t.length?0:e,t.length)}),s.append(i,r);const a=document.createElement("div");a.className=`${o}__carousel-controls`;const n=document.createElement("db-indicator");n.className=`${o}__carousel-indicator`,n.setAttribute("current",String(this.carouselIndex)),n.setAttribute("total",String(t.length)),n.setAttribute("type","dots"),n.setAttribute("size","s"),n.setAttribute("clickable",""),n.addEventListener("db-step-click",e=>{const s=e;this.goToCarouselSlide(s.detail.index,t.length)}),this.carouselIndicator=n,a.append(n),this.contentEl.append(s,a)}else this.contentEl.append(s);this.resizeObserver?.disconnect(),this.resizeObserver=new ResizeObserver(()=>this.updateCarouselTransform()),this.resizeObserver.observe(s),requestAnimationFrame(()=>this.updateCarouselTransform())}updateUI(){const e=i(this.getAttribute("variant"),a,"grid"),t=i(this.getAttribute("size"),n,"m"),r=this.getAttribute("columns")||"3",l=this.getAttribute("content-padding")||"l",c=this.parseItems();this.className=[o,`${o}--${e}`,`${o}--cols-${r}`,`${o}--padding-${l}`,`${o}--size-${t}`].join(" "),s(this,o),this.updateHeader(),"carousel"===e?this.renderCarousel(c):this.renderGrid(c)}}customElements.get("db-section-testimonials")||customElements.define("db-section-testimonials",DbSectionTestimonials);export{DbSectionTestimonials};
1
+ import{dbText as e}from"../core/i18n.js";import{b as t}from"../node_modules/@designbasekorea/carousel/dist/chunks/chunk-AGE5BHQ4.js";import{createDbIcon as s}from"./db-icons.js";import{applySectionBlockHeader as i}from"./section-block-header-utils.js";import{syncMarketingBlockHost as n}from"./marketing-block-host-utils.js";import{coerceToContract as a}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SECTION_ALIGNS as r,SECTION_TESTIMONIALS_VARIANTS as o,SECTION_TESTIMONIALS_SIZES as c}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const l="designbase-wc-section-testimonials";class DbSectionTestimonials extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.carouselIndex=0}static get observedAttributes(){return["headline","subtitle","description","badge","items","variant","columns","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}disconnectedCallback(){this.carouselEngine?.destroy(),this.carouselEngine=void 0}attributeChangedCallback(){this.built&&(this.carouselIndex=0,this.updateUI())}parseItems(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}buildHeader(e){this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header";const t=document.createElement("db-badge");t.className="designbase-wc-section-block-header__badge",t.hidden=!0,t.dataset.role="badge";const s=document.createElement("h2");s.className="designbase-wc-section-block-header__headline",s.dataset.role="headline";const i=document.createElement("p");i.className="designbase-wc-section-block-header__subtitle",i.dataset.role="subtitle";const n=document.createElement("p");n.className="designbase-wc-section-block-header__description",n.dataset.role="description",this.headerEl.append(t,s,i,n),e.append(this.headerEl)}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${l}__inner`,this.buildHeader(this.innerEl),this.contentEl=document.createElement("div"),this.contentEl.className=`${l}__grid`,this.innerEl.append(this.contentEl),this.append(this.innerEl)}createTestimonialEl(e){const t=document.createElement("db-testimonial");return t.setAttribute("variant","card"),t.setAttribute("quote",e.quote),t.setAttribute("author",e.author),e.role&&t.setAttribute("role",e.role),e.company&&t.setAttribute("company",e.company),e.avatar&&t.setAttribute("avatar",e.avatar),null!=e.rating&&t.setAttribute("rating",String(e.rating)),t}updateHeader(){this.headerEl&&i(this.headerEl,{headline:this.getAttribute("headline")||"고객 후기",subtitle:this.getAttribute("subtitle")||"",description:this.getAttribute("description")||"",badge:this.parseBadge(),align:a(this.getAttribute("align"),r,"center")})}clampCarouselIndex(e){e<=0?this.carouselIndex=0:(this.carouselIndex>=e&&(this.carouselIndex=0),this.carouselIndex<0&&(this.carouselIndex=0))}goToCarouselSlide(e){this.carouselEngine?.goTo(e)}renderGrid(e){this.contentEl&&(this.carouselEngine?.destroy(),this.carouselEngine=void 0,this.carouselIndicator=void 0,this.contentEl.className=`${l}__grid`,this.contentEl.replaceChildren(),e.forEach(e=>{this.contentEl.append(this.createTestimonialEl(e))}))}renderCarousel(i){if(!this.contentEl)return;if(this.contentEl.replaceChildren(),this.contentEl.className=`${l}__carousel`,this.clampCarouselIndex(i.length),0===i.length)return;const n=document.createElement("div");n.className=`${l}__carousel-viewport`;const a=document.createElement("div");if(a.className=`${l}__carousel-track db-slide__viewport`,i.forEach(e=>{const t=document.createElement("div");t.className=`${l}__carousel-slide`,t.append(this.createTestimonialEl(e)),a.append(t)}),n.append(a),i.length>1){const t=document.createElement("button");t.type="button",t.className=`${l}__carousel-nav ${l}__carousel-nav--prev`,t.setAttribute("aria-label",e("이전 후기")),t.append(s("chevron-left",20)),t.addEventListener("click",()=>this.carouselEngine?.prev());const a=document.createElement("button");a.type="button",a.className=`${l}__carousel-nav ${l}__carousel-nav--next`,a.setAttribute("aria-label",e("다음 후기")),a.append(s("chevron-right",20)),a.addEventListener("click",()=>this.carouselEngine?.next()),n.append(t,a);const r=document.createElement("div");r.className=`${l}__carousel-controls`;const o=document.createElement("db-indicator");o.className=`${l}__carousel-indicator`,o.setAttribute("current",String(this.carouselIndex)),o.setAttribute("total",String(i.length)),o.setAttribute("type","dots"),o.setAttribute("size","s"),o.setAttribute("clickable",""),o.addEventListener("db-step-click",e=>{const t=e;this.goToCarouselSlide(t.detail.index)}),this.carouselIndicator=o,r.append(o),this.contentEl.append(n,r)}else this.contentEl.append(n);this.carouselEngine=t(this.contentEl,{startIndex:this.carouselIndex,slidesPerView:1,gap:0,rewind:!0,label:this.getAttribute("headline")||"고객 후기"});const sync=()=>{this.carouselIndex=this.carouselEngine.getState().index,this.carouselIndicator?.getAttribute("current")!==String(this.carouselIndex)&&this.carouselIndicator?.setAttribute("current",String(this.carouselIndex))};this.carouselEngine.on("change",sync),this.carouselEngine.on("refresh",sync),sync()}updateUI(){this.carouselEngine?.destroy(),this.carouselEngine=void 0;const e=a(this.getAttribute("variant"),o,"grid"),t=a(this.getAttribute("size"),c,"m"),s=this.getAttribute("columns")||"3",i=this.getAttribute("content-padding")||"l",r=this.parseItems();this.className=[l,`${l}--${e}`,`${l}--cols-${s}`,`${l}--padding-${i}`,`${l}--size-${t}`].join(" "),n(this,l),this.updateHeader(),"carousel"===e?this.renderCarousel(r):this.renderGrid(r)}}customElements.get("db-section-testimonials")||customElements.define("db-section-testimonials",DbSectionTestimonials);export{DbSectionTestimonials};
@@ -1,7 +1,3 @@
1
- /**
2
- * SegmentControl Web Component
3
- * packages/ui SegmentControl.tsx와 DOM·동작·스타일 1:1 동기화
4
- */
5
1
  interface DbSegmentOptionData {
6
2
  value: string;
7
3
  label: string;
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";const t="designbase-wc-segment-control",i={bar:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="12" width="4" height="8"/><rect x="10" y="8" width="4" height="12"/><rect x="17" y="4" width="4" height="16"/></svg>',line:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 16 9 10 14 13 20 6"/></svg>',pie:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v10l8.66 5"/><circle cx="12" cy="12" r="10"/></svg>',donut:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></svg>',radar:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 20 8 17 20 7 20 4 8"/></svg>'};class DbSegmentControl extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.indicatorEl=null,this.segmentButtons=[],this.focusedIndex=-1,this.boundKeyDown=e=>this.handleKeyDown(e),this.boundResize=()=>this.updateIndicator(),this.resizeObserver=null}static get observedAttributes(){return["options","value","default-value","size","variant","appearance","full-width","disabled"]}connectedCallback(){this.built||(this.built=!0),this.render(),this.addEventListener("keydown",this.boundKeyDown),window.addEventListener("resize",this.boundResize),this.resizeObserver=new ResizeObserver(()=>this.updateIndicator()),this.resizeObserver.observe(this)}disconnectedCallback(){this.removeEventListener("keydown",this.boundKeyDown),window.removeEventListener("resize",this.boundResize),this.resizeObserver?.disconnect(),this.resizeObserver=null}attributeChangedCallback(e){this.built&&("value"!==e?this.render():this.updateSelection())}get options(){return this.parseOptions(this.getAttribute("options"))}set options(e){const t="string"==typeof e?e:JSON.stringify(e);this.getAttribute("options")!==t&&this.setAttribute("options",t)}get value(){return this.getAttribute("value")||this.getAttribute("default-value")||this.options[0]?.value||""}set value(e){this.setAttribute("value",e)}parseOptions(e){if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}render(){const s=this.getAttribute("size")||"m",n=this.getAttribute("variant")||"default",r=this.getAttribute("appearance")||"default",a=this.hasAttribute("disabled"),o=this.options,l=this.value;this.className=[t,`${t}--${s}`,`${t}--${n}`,"pill"===r&&`${t}--appearance-pill`,"rounded"===r&&`${t}--appearance-rounded`,this.hasAttribute("full-width")&&`${t}--full-width`,a&&`${t}--disabled`].filter(Boolean).join(" "),this.setAttribute("role","tablist"),this.hasAttribute("aria-label")||this.setAttribute("aria-label","세그먼트 컨트롤"),this.replaceChildren(),this.segmentButtons=[],o.forEach((s,r)=>{const o=s.value===l,d=Boolean(a||s.disabled),h=document.createElement("button");if(h.type="button",h.className=[`${t}__segment`,o&&`${t}__segment--selected`,d&&`${t}__segment--disabled`].filter(Boolean).join(" "),h.setAttribute("role","tab"),h.setAttribute("aria-selected",String(o)),h.setAttribute("aria-disabled",String(d)),h.setAttribute("tabindex",o?"0":"-1"),h.disabled=d,s.icon&&(i[s.icon]||["desktop","tablet","mobile"].includes(s.icon))){const n=document.createElement("span");n.className=`${t}__segment-icon`,"desktop"===s.icon||"tablet"===s.icon||"mobile"===s.icon?n.append(e(s.icon,18)):n.innerHTML=i[s.icon],h.appendChild(n)}const u=document.createElement("span");u.className=`${t}__segment-label`,u.textContent=s.label,"icon-only"===n&&(h.setAttribute("aria-label",s.label),h.title=s.label,u.setAttribute("aria-label",s.label)),h.appendChild(u),h.addEventListener("click",()=>this.select(s.value)),h.addEventListener("focus",()=>{this.focusedIndex=r,h.classList.add(`${t}__segment--focused`)}),h.addEventListener("blur",()=>{this.focusedIndex=-1,h.classList.remove(`${t}__segment--focused`)}),this.appendChild(h),this.segmentButtons.push(h)}),this.indicatorEl=document.createElement("div"),this.indicatorEl.className=`${t}__indicator`,this.appendChild(this.indicatorEl),this.updateSelection()}updateSelection(){const e=this.options,i=this.value,s=e.findIndex(e=>e.value===i);this.segmentButtons.forEach((s,n)=>{const r=e[n],a=r?.value===i;s.classList.toggle(`${t}__segment--selected`,a),s.setAttribute("aria-selected",String(a)),s.setAttribute("tabindex",a?"0":"-1")}),this.indicatorEl&&e.length>0&&s>=0&&requestAnimationFrame(()=>this.updateIndicator())}updateIndicator(){const e=this.options.findIndex(e=>e.value===this.value),t=this.segmentButtons[e];this.indicatorEl&&t&&(this.indicatorEl.style.width=`${t.offsetWidth}px`,this.indicatorEl.style.transform=`translateX(${t.offsetLeft}px)`)}select(e){if(this.hasAttribute("disabled"))return;const t=this.options.find(t=>t.value===e);t&&!t.disabled&&(this.setAttribute("value",e),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e},bubbles:!0,composed:!0})))}handleKeyDown(e){if(this.hasAttribute("disabled"))return;const t=this.options,i=this.focusedIndex>=0?this.focusedIndex:t.findIndex(e=>e.value===this.value);if(-1===i)return;let s=i;switch(e.key){case"ArrowLeft":e.preventDefault(),s=i>0?i-1:t.length-1;break;case"ArrowRight":e.preventDefault(),s=i<t.length-1?i+1:0;break;case"Home":e.preventDefault(),s=0;break;case"End":e.preventDefault(),s=t.length-1;break;case"Enter":case" ":return e.preventDefault(),void this.select(t[s]?.value??this.value);default:return}for(;s!==i;){const i=t[s];if(i&&!i.disabled){this.segmentButtons[s]?.focus();break}s="ArrowLeft"===e.key||"Home"===e.key?s>0?s-1:t.length-1:s<t.length-1?s+1:0}}}customElements.get("db-segment-control")||customElements.define("db-segment-control",DbSegmentControl);export{DbSegmentControl};
1
+ import{dbText as e}from"../core/i18n.js";import{createDbIcon as t}from"./db-icons.js";const i="designbase-wc-segment-control",s={bar:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="12" width="4" height="8"/><rect x="10" y="8" width="4" height="12"/><rect x="17" y="4" width="4" height="16"/></svg>',line:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 16 9 10 14 13 20 6"/></svg>',pie:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v10l8.66 5"/><circle cx="12" cy="12" r="10"/></svg>',donut:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></svg>',radar:'<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 20 8 17 20 7 20 4 8"/></svg>'};class DbSegmentControl extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.indicatorEl=null,this.segmentButtons=[],this.focusedIndex=-1,this.boundKeyDown=e=>this.handleKeyDown(e),this.boundResize=()=>this.updateIndicator(),this.resizeObserver=null}static get observedAttributes(){return["options","value","default-value","size","variant","appearance","full-width","disabled"]}connectedCallback(){this.built||(this.built=!0),this.render(),this.addEventListener("keydown",this.boundKeyDown),window.addEventListener("resize",this.boundResize),this.resizeObserver=new ResizeObserver(()=>this.updateIndicator()),this.resizeObserver.observe(this)}disconnectedCallback(){this.removeEventListener("keydown",this.boundKeyDown),window.removeEventListener("resize",this.boundResize),this.resizeObserver?.disconnect(),this.resizeObserver=null}attributeChangedCallback(e){this.built&&("value"!==e?this.render():this.updateSelection())}get options(){return this.parseOptions(this.getAttribute("options"))}set options(e){const t="string"==typeof e?e:JSON.stringify(e);this.getAttribute("options")!==t&&this.setAttribute("options",t)}get value(){return this.getAttribute("value")||this.getAttribute("default-value")||this.options[0]?.value||""}set value(e){this.setAttribute("value",e)}parseOptions(e){if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}render(){const n=this.getAttribute("size")||"m",r=this.getAttribute("variant")||"default",a=this.getAttribute("appearance")||"default",o=this.hasAttribute("disabled"),l=this.options,d=this.value;this.className=[i,`${i}--${n}`,`${i}--${r}`,"pill"===a&&`${i}--appearance-pill`,"rounded"===a&&`${i}--appearance-rounded`,this.hasAttribute("full-width")&&`${i}--full-width`,o&&`${i}--disabled`].filter(Boolean).join(" "),this.setAttribute("role","tablist"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",e("세그먼트 컨트롤")),this.replaceChildren(),this.segmentButtons=[],l.forEach((e,n)=>{const a=e.value===d,l=Boolean(o||e.disabled),h=document.createElement("button");if(h.type="button",h.className=[`${i}__segment`,a&&`${i}__segment--selected`,l&&`${i}__segment--disabled`].filter(Boolean).join(" "),h.setAttribute("role","tab"),h.setAttribute("aria-selected",String(a)),h.setAttribute("aria-disabled",String(l)),h.setAttribute("tabindex",a?"0":"-1"),h.disabled=l,e.icon&&(s[e.icon]||["desktop","tablet","mobile"].includes(e.icon))){const n=document.createElement("span");n.className=`${i}__segment-icon`,"desktop"===e.icon||"tablet"===e.icon||"mobile"===e.icon?n.append(t(e.icon,18)):n.innerHTML=s[e.icon],h.appendChild(n)}const u=document.createElement("span");u.className=`${i}__segment-label`,u.textContent=e.label,"icon-only"===r&&(h.setAttribute("aria-label",e.label),h.title=e.label,u.setAttribute("aria-label",e.label)),h.appendChild(u),h.addEventListener("click",()=>this.select(e.value)),h.addEventListener("focus",()=>{this.focusedIndex=n,h.classList.add(`${i}__segment--focused`)}),h.addEventListener("blur",()=>{this.focusedIndex=-1,h.classList.remove(`${i}__segment--focused`)}),this.appendChild(h),this.segmentButtons.push(h)}),this.indicatorEl=document.createElement("div"),this.indicatorEl.className=`${i}__indicator`,this.appendChild(this.indicatorEl),this.updateSelection()}updateSelection(){const e=this.options,t=this.value,s=e.findIndex(e=>e.value===t);this.segmentButtons.forEach((s,n)=>{const r=e[n],a=r?.value===t;s.classList.toggle(`${i}__segment--selected`,a),s.setAttribute("aria-selected",String(a)),s.setAttribute("tabindex",a?"0":"-1")}),this.indicatorEl&&e.length>0&&s>=0&&requestAnimationFrame(()=>this.updateIndicator())}updateIndicator(){const e=this.options.findIndex(e=>e.value===this.value),t=this.segmentButtons[e];this.indicatorEl&&t&&(this.indicatorEl.style.width=`${t.offsetWidth}px`,this.indicatorEl.style.transform=`translateX(${t.offsetLeft}px)`)}select(e){if(this.hasAttribute("disabled"))return;const t=this.options.find(t=>t.value===e);t&&!t.disabled&&(this.setAttribute("value",e),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e},bubbles:!0,composed:!0})))}handleKeyDown(e){if(this.hasAttribute("disabled"))return;const t=this.options,i=this.focusedIndex>=0?this.focusedIndex:t.findIndex(e=>e.value===this.value);if(-1===i)return;let s=i;switch(e.key){case"ArrowLeft":e.preventDefault(),s=i>0?i-1:t.length-1;break;case"ArrowRight":e.preventDefault(),s=i<t.length-1?i+1:0;break;case"Home":e.preventDefault(),s=0;break;case"End":e.preventDefault(),s=t.length-1;break;case"Enter":case" ":return e.preventDefault(),void this.select(t[s]?.value??this.value);default:return}for(;s!==i;){const i=t[s];if(i&&!i.disabled){this.segmentButtons[s]?.focus();break}s="ArrowLeft"===e.key||"Home"===e.key?s>0?s-1:t.length-1:s<t.length-1?s+1:0}}}customElements.get("db-segment-control")||customElements.define("db-segment-control",DbSegmentControl);export{DbSegmentControl};
@@ -1 +1 @@
1
- import{getDbComponentIconSize as e,createDbIcon as t}from"./db-icons.js";import"./db-checkbox.js";import{dbUid as s}from"../core/uid.js";import{labelFrom as i,t as a}from"../core/i18n.js";import{SELECT_SIZES as r,SELECT_POSITIONS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as l}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbSelect extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.built=!1,this.searchTerm="",this.focusedIndex=-1,this.handleTriggerClick=()=>{this.hasAttribute("disabled")||this.hasAttribute("readonly")||(this.open=!this.open,this.open&&this.searchable&&setTimeout(()=>this.searchInput?.focus(),0))},this.handleTriggerFocus=()=>{this.trigger?.classList.add("designbase-wc-select__trigger--focused")},this.handleTriggerBlur=()=>{this.trigger?.classList.remove("designbase-wc-select__trigger--focused")},this.handleClear=e=>{e.stopPropagation();const t=[];this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)},this.handleSearchInput=()=>{this.searchTerm=this.searchInput?.value||"",this.focusedIndex=-1,this.syncOptions()},this.handleDocumentMouseDown=e=>{this.contains(e.target)||(this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions())},this.handleDocumentKeyDown=e=>{if(!this.contains(document.activeElement))return;if(!this.open)return void("Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.open=!0));const t=this.getFilteredOptions();switch(e.key){case"Escape":e.preventDefault(),this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions();break;case"ArrowDown":e.preventDefault(),this.focusedIndex=Math.min(this.focusedIndex+1,t.length-1),this.syncOptions();break;case"ArrowUp":e.preventDefault(),this.focusedIndex=Math.max(this.focusedIndex-1,0),this.syncOptions();break;case"Enter":e.preventDefault(),this.focusedIndex>=0&&t[this.focusedIndex]&&this.selectOption(t[this.focusedIndex])}}}static get observedAttributes(){return["options","value","placeholder","label","size","full-width","disabled","readonly","required","error","error-message","helper-text","multiple","searchable","show-clear-button","open","max-height","position","dropdown-width","name"]}get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get open(){return this.hasAttribute("open")}set open(e){this.toggleAttribute("open",e),this.syncOpenState()}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value"),this.syncTrigger(),this.syncOptions(),this.syncFormValue()}connectedCallback(){this.built||this.build(),this.syncState(),queueMicrotask(()=>{this.isConnected&&this.syncFormValue()}),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}formAssociatedCallback(){this.syncFormValue()}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)}formResetCallback(){this.removeAttribute("value"),this.internals.setFormValue(null),this.built&&(this.syncTrigger(),this.syncOptions(),this.syncFormValue())}formDisabledCallback(e){this.toggleAttribute("disabled",e)}attributeChangedCallback(e){if(this.built){if("open"!==e)return"value"===e?(this.syncTrigger(),this.syncOptions(),void this.syncFormValue()):void this.syncState();this.syncOpenState()}}get multiple(){return this.hasAttribute("multiple")}set multiple(e){this.toggleAttribute("multiple",Boolean(e))}get searchable(){return this.hasAttribute("searchable")}set searchable(e){this.toggleAttribute("searchable",Boolean(e))}get showClearButton(){return!this.hasAttribute("show-clear-button")||"false"!==this.getAttribute("show-clear-button")}parseOptions(){const e=this.getAttribute("options")||"[]";try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>({value:e,label:e}))}}parseSelectedValues(){const e=this.getAttribute("value")||"";if(!e)return[];if(this.multiple)try{const t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean)}return e?[e]:[]}setSelectedValues(e){this.multiple?e.length?this.setAttribute("value",JSON.stringify(e)):this.removeAttribute("value"):e[0]?this.setAttribute("value",e[0]):this.removeAttribute("value")}syncFormValue(){const e=this.parseSelectedValues();if(this.multiple){const t=new FormData;return e.forEach(e=>t.append(this.name||"select",e)),void this.internals.setFormValue(e.length?t:null)}this.internals.setFormValue(e[0]||null)}getIconSize(){const t=this.getAttribute("size")||"m";return e(r.includes(t)?t:"m")}syncIndicatorIcons(){const e=this.getIconSize();this.clearButton?.replaceChildren(t("close",e)),this.chevronEl&&this.chevronEl.replaceChildren(t(this.open?"chevron-up":"chevron-down",e))}build(){const e=this.getAttribute("id")||s("db-select"),a=`${e}-listbox`;this.hasAttribute("id")||this.setAttribute("id",e),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-select__label",this.trigger=document.createElement("div"),this.trigger.className="designbase-wc-select__trigger",this.trigger.tabIndex=0,this.trigger.setAttribute("role","combobox"),this.trigger.setAttribute("aria-haspopup","listbox"),this.trigger.setAttribute("aria-controls",a),this.trigger.addEventListener("click",this.handleTriggerClick),this.trigger.addEventListener("focus",this.handleTriggerFocus),this.trigger.addEventListener("blur",this.handleTriggerBlur),this.valueEl=document.createElement("div"),this.valueEl.className="designbase-wc-select__value",this.indicatorsEl=document.createElement("div"),this.indicatorsEl.className="designbase-wc-select__indicators",this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-select__clear-button",this.clearButton.setAttribute("aria-label",i(this,"label-clear","clearAll")),this.clearButton.hidden=!0,this.clearButton.appendChild(t("close",this.getIconSize())),this.clearButton.addEventListener("click",this.handleClear),this.chevronEl=document.createElement("div"),this.chevronEl.className="designbase-wc-select__chevron",this.indicatorsEl.append(this.clearButton,this.chevronEl),this.trigger.append(this.valueEl,this.indicatorsEl),this.dropdown=document.createElement("div"),this.dropdown.className="designbase-wc-select__dropdown",this.searchWrap=document.createElement("div"),this.searchWrap.className="designbase-wc-select__search",this.searchWrap.hidden=!0,this.searchInput=document.createElement("input"),this.searchInput.type="text",this.searchInput.className="designbase-wc-select__search-input",this.searchInput.placeholder=i(this,"label-search","search.label"),this.searchInput.addEventListener("input",this.handleSearchInput),this.searchInput.addEventListener("mousedown",e=>e.stopPropagation()),this.searchInput.addEventListener("click",e=>e.stopPropagation()),this.searchWrap.appendChild(this.searchInput),this.optionsEl=document.createElement("div"),this.optionsEl.className="designbase-wc-select__options",this.optionsEl.id=a,this.optionsEl.setAttribute("role","listbox"),this.dropdown.append(this.searchWrap,this.optionsEl),this.helperEl=document.createElement("p"),this.helperEl.className="designbase-wc-select__helper-text",this.errorEl=document.createElement("p"),this.errorEl.className="designbase-wc-select__error-message",this.append(this.labelEl,this.trigger,this.dropdown,this.helperEl,this.errorEl),this.built=!0}getFilteredOptions(){const e=this.parseOptions();if(!this.searchable||!this.searchTerm)return e;const t=this.searchTerm.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(t))}selectOption(e){if(e.disabled)return;const t=this.parseSelectedValues();let s;this.multiple?s=t.includes(e.value)?t.filter(t=>t!==e.value):[...t,e.value]:(s=[e.value],this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1),this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s)}dispatchChange(e){const t=this.parseOptions();if(this.multiple)return this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,labels:e.map(e=>t.find(t=>t.value===e)?.label||e)},bubbles:!0,composed:!0}));const s=e[0]||"",i=t.find(e=>e.value===s)?.label||"";this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:s,label:i},bubbles:!0,composed:!0}))}syncAccessibleName(e){if(!this.trigger)return;if(e&&this.labelEl)return this.labelEl.id||(this.labelEl.id=s("db-select-label")),this.trigger.setAttribute("aria-labelledby",this.labelEl.id),void this.trigger.removeAttribute("aria-label");this.trigger.removeAttribute("aria-labelledby");const t=this.getAttribute("aria-label")||this.getAttribute("placeholder")||a("select.placeholder");this.trigger.setAttribute("aria-label",t)}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const e=l(this.getAttribute("size"),r,"m"),t=l(this.getAttribute("position"),n,"bottom"),s="full"===this.getAttribute("dropdown-width")?"full":"auto",i=Number(this.getAttribute("max-height")||200),a=this.getAttribute("label")||"",h=this.getAttribute("helper-text")||"",c=this.getAttribute("error-message")||"",o=this.hasAttribute("error"),d=this.getAttribute("id")||"";this.className=["designbase-wc-select",`designbase-wc-select--${e}`,this.open&&"designbase-wc-select--open",o&&"designbase-wc-select--error",this.hasAttribute("disabled")&&"designbase-wc-select--disabled",this.hasAttribute("readonly")&&"designbase-wc-select--readonly",this.hasAttribute("full-width")&&"designbase-wc-select--full-width",this.multiple&&"designbase-wc-select--multiple",this.searchable&&"designbase-wc-select--searchable"].filter(Boolean).join(" ");const u=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",u.length>0),this.labelEl){const e=this.hasAttribute("required")?'<span class="designbase-wc-select__required" aria-hidden="true">*</span>':"";this.labelEl.innerHTML=a?`${this.escape(a)}${e}`:"",this.labelEl.hidden=!a}this.syncAccessibleName(a),this.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${s}`,`designbase-wc-select__dropdown--${t}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${i}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const p=`${d}-helper`,b=`${d}-error`;o&&c?(this.errorEl.id=b,this.errorEl.textContent=c,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",b),this.trigger.setAttribute("aria-invalid","true")):h?(this.helperEl.id=p,this.helperEl.textContent=h,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",p),this.trigger.removeAttribute("aria-invalid")):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.trigger.removeAttribute("aria-describedby"),this.trigger.removeAttribute("aria-invalid")),this.hasAttribute("disabled")||this.hasAttribute("readonly")?this.trigger.tabIndex=-1:this.trigger.tabIndex=0,this.syncOpenState(),this.syncTrigger(),this.syncOptions(),this.syncFormValue(),this.syncIndicatorIcons()}syncOpenState(){this.trigger&&this.dropdown&&this.chevronEl&&(this.trigger.setAttribute("aria-expanded",String(this.open)),this.classList.toggle("designbase-wc-select--open",this.open),this.dropdown.classList.toggle("designbase-wc-select__dropdown--open",this.open),this.syncIndicatorIcons())}syncTrigger(){if(!this.valueEl||!this.clearButton)return;const e=this.parseOptions(),s=this.parseSelectedValues(),i=this.getAttribute("placeholder")||a("select.placeholder"),r=s.length>0,n=r&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===s.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=i,this.valueEl.appendChild(e)}else{const i=document.createElement("div");i.className="designbase-wc-select__tags",s.forEach(a=>{const r=e.find(e=>e.value===a),n=document.createElement("span");n.className="designbase-wc-select__tag";const l=document.createElement("span");l.className="designbase-wc-select__tag-label",l.textContent=r?.label||a;const h=document.createElement("button");h.type="button",h.className="designbase-wc-select__tag-remove",h.setAttribute("aria-label",`${r?.label||a} 제거`),h.appendChild(t("close",12)),h.addEventListener("click",e=>{e.stopPropagation();const t=s.filter(e=>e!==a);this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)}),n.append(l,h),i.appendChild(n)}),this.valueEl.appendChild(i)}else{const t=document.createElement("span");t.className="designbase-wc-select__single-value";const a=e.find(e=>e.value===s[0]);t.textContent=r?a?.label||s[0]:i,r||t.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(t)}this.clearButton.hidden=!n,this.clearButton.setAttribute("aria-hidden",n?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",r)}syncOptions(){if(!this.optionsEl)return;const e=this.getFilteredOptions(),t=this.parseSelectedValues(),s=this.getAttribute("id")||"db-select";if(this.optionsEl.replaceChildren(),0===e.length){const e=document.createElement("div");return e.className="designbase-wc-select__no-options",e.textContent=this.searchTerm?i(this,"label-no-results","select.noResults"):i(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(e)}e.forEach((e,i)=>{const a=t.includes(e.value),r=i===this.focusedIndex,n=document.createElement("div");if(n.className=["designbase-wc-select__option",a&&"designbase-wc-select__option--selected",r&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),n.id=`${s}-option-${i}`,n.setAttribute("role","option"),n.setAttribute("aria-selected",String(a)),n.setAttribute("aria-disabled",String(Boolean(e.disabled))),n.addEventListener("click",()=>this.selectOption(e)),this.multiple){const t=document.createElement("div");t.className="designbase-wc-select__checkbox";const s=document.createElement("db-checkbox");s.setAttribute("size","s"),s.setAttribute("has-label","false"),a&&s.setAttribute("checked",""),e.disabled&&s.setAttribute("disabled",""),t.appendChild(s),n.appendChild(t)}const l=document.createElement("span");l.className="designbase-wc-select__option-label",l.textContent=e.label,n.appendChild(l),this.optionsEl.appendChild(n)}),this.focusedIndex>=0?this.trigger?.setAttribute("aria-activedescendant",`${s}-option-${this.focusedIndex}`):this.trigger?.removeAttribute("aria-activedescendant")}escape(e){return e.replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e]||e))}}DbSelect.formAssociated=!0,customElements.get("db-select")||customElements.define("db-select",DbSelect);export{DbSelect};
1
+ import{labelFrom as e,t,dbFormat as s}from"../core/i18n.js";import{getDbComponentIconSize as i,createDbIcon as a}from"./db-icons.js";import"./db-checkbox.js";import{dbUid as r}from"../core/uid.js";import{SELECT_SIZES as n,SELECT_POSITIONS as l}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as h}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbSelect extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.built=!1,this.searchTerm="",this.focusedIndex=-1,this.handleTriggerClick=()=>{this.hasAttribute("disabled")||this.hasAttribute("readonly")||(this.open=!this.open,this.open&&this.searchable&&setTimeout(()=>this.searchInput?.focus(),0))},this.handleTriggerFocus=()=>{this.trigger?.classList.add("designbase-wc-select__trigger--focused")},this.handleTriggerBlur=()=>{this.trigger?.classList.remove("designbase-wc-select__trigger--focused")},this.handleClear=e=>{e.stopPropagation();const t=[];this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)},this.handleSearchInput=()=>{this.searchTerm=this.searchInput?.value||"",this.focusedIndex=-1,this.syncOptions()},this.handleDocumentMouseDown=e=>{this.contains(e.target)||(this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions())},this.handleDocumentKeyDown=e=>{if(!this.contains(document.activeElement))return;if(!this.open)return void("Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.open=!0));const t=this.getFilteredOptions();switch(e.key){case"Escape":e.preventDefault(),this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions();break;case"ArrowDown":e.preventDefault(),this.focusedIndex=Math.min(this.focusedIndex+1,t.length-1),this.syncOptions();break;case"ArrowUp":e.preventDefault(),this.focusedIndex=Math.max(this.focusedIndex-1,0),this.syncOptions();break;case"Enter":e.preventDefault(),this.focusedIndex>=0&&t[this.focusedIndex]&&this.selectOption(t[this.focusedIndex])}}}static get observedAttributes(){return["options","value","placeholder","label","size","full-width","disabled","readonly","required","error","error-message","helper-text","multiple","searchable","show-clear-button","open","max-height","position","dropdown-width","name"]}get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get open(){return this.hasAttribute("open")}set open(e){this.toggleAttribute("open",e),this.syncOpenState()}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value"),this.syncTrigger(),this.syncOptions(),this.syncFormValue()}connectedCallback(){this.built||this.build(),this.syncState(),queueMicrotask(()=>{this.isConnected&&this.syncFormValue()}),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}formAssociatedCallback(){this.syncFormValue()}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)}formResetCallback(){this.removeAttribute("value"),this.internals.setFormValue(null),this.built&&(this.syncTrigger(),this.syncOptions(),this.syncFormValue())}formDisabledCallback(e){this.toggleAttribute("disabled",e)}attributeChangedCallback(e){if(this.built){if("open"!==e)return"value"===e?(this.syncTrigger(),this.syncOptions(),void this.syncFormValue()):void this.syncState();this.syncOpenState()}}get multiple(){return this.hasAttribute("multiple")}set multiple(e){this.toggleAttribute("multiple",Boolean(e))}get searchable(){return this.hasAttribute("searchable")}set searchable(e){this.toggleAttribute("searchable",Boolean(e))}get showClearButton(){return!this.hasAttribute("show-clear-button")||"false"!==this.getAttribute("show-clear-button")}parseOptions(){const e=this.getAttribute("options")||"[]";try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>({value:e,label:e}))}}parseSelectedValues(){const e=this.getAttribute("value")||"";if(!e)return[];if(this.multiple)try{const t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean)}return e?[e]:[]}setSelectedValues(e){this.multiple?e.length?this.setAttribute("value",JSON.stringify(e)):this.removeAttribute("value"):e[0]?this.setAttribute("value",e[0]):this.removeAttribute("value")}syncFormValue(){const e=this.parseSelectedValues();if(this.multiple){const t=new FormData;return e.forEach(e=>t.append(this.name||"select",e)),void this.internals.setFormValue(e.length?t:null)}this.internals.setFormValue(e[0]||null)}getIconSize(){const e=this.getAttribute("size")||"m";return i(n.includes(e)?e:"m")}syncIndicatorIcons(){const e=this.getIconSize();this.clearButton?.replaceChildren(a("close",e)),this.chevronEl&&this.chevronEl.replaceChildren(a(this.open?"chevron-up":"chevron-down",e))}build(){const t=this.getAttribute("id")||r("db-select"),s=`${t}-listbox`;this.hasAttribute("id")||this.setAttribute("id",t),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-select__label",this.trigger=document.createElement("div"),this.trigger.className="designbase-wc-select__trigger",this.trigger.tabIndex=0,this.trigger.setAttribute("role","combobox"),this.trigger.setAttribute("aria-haspopup","listbox"),this.trigger.setAttribute("aria-controls",s),this.trigger.addEventListener("click",this.handleTriggerClick),this.trigger.addEventListener("focus",this.handleTriggerFocus),this.trigger.addEventListener("blur",this.handleTriggerBlur),this.valueEl=document.createElement("div"),this.valueEl.className="designbase-wc-select__value",this.indicatorsEl=document.createElement("div"),this.indicatorsEl.className="designbase-wc-select__indicators",this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-select__clear-button",this.clearButton.setAttribute("aria-label",e(this,"label-clear","clearAll")),this.clearButton.hidden=!0,this.clearButton.appendChild(a("close",this.getIconSize())),this.clearButton.addEventListener("click",this.handleClear),this.chevronEl=document.createElement("div"),this.chevronEl.className="designbase-wc-select__chevron",this.indicatorsEl.append(this.clearButton,this.chevronEl),this.trigger.append(this.valueEl,this.indicatorsEl),this.dropdown=document.createElement("div"),this.dropdown.className="designbase-wc-select__dropdown",this.searchWrap=document.createElement("div"),this.searchWrap.className="designbase-wc-select__search",this.searchWrap.hidden=!0,this.searchInput=document.createElement("input"),this.searchInput.type="text",this.searchInput.className="designbase-wc-select__search-input",this.searchInput.placeholder=e(this,"label-search","search.label"),this.searchInput.addEventListener("input",this.handleSearchInput),this.searchInput.addEventListener("mousedown",e=>e.stopPropagation()),this.searchInput.addEventListener("click",e=>e.stopPropagation()),this.searchWrap.appendChild(this.searchInput),this.optionsEl=document.createElement("div"),this.optionsEl.className="designbase-wc-select__options",this.optionsEl.id=s,this.optionsEl.setAttribute("role","listbox"),this.dropdown.append(this.searchWrap,this.optionsEl),this.helperEl=document.createElement("p"),this.helperEl.className="designbase-wc-select__helper-text",this.errorEl=document.createElement("p"),this.errorEl.className="designbase-wc-select__error-message",this.append(this.labelEl,this.trigger,this.dropdown,this.helperEl,this.errorEl),this.built=!0}getFilteredOptions(){const e=this.parseOptions();if(!this.searchable||!this.searchTerm)return e;const t=this.searchTerm.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(t))}selectOption(e){if(e.disabled)return;const t=this.parseSelectedValues();let s;this.multiple?s=t.includes(e.value)?t.filter(t=>t!==e.value):[...t,e.value]:(s=[e.value],this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1),this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s)}dispatchChange(e){const t=this.parseOptions();if(this.multiple)return this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,labels:e.map(e=>t.find(t=>t.value===e)?.label||e)},bubbles:!0,composed:!0}));const s=e[0]||"",i=t.find(e=>e.value===s)?.label||"";this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:s,label:i},bubbles:!0,composed:!0}))}syncAccessibleName(e){if(!this.trigger)return;if(e&&this.labelEl)return this.labelEl.id||(this.labelEl.id=r("db-select-label")),this.trigger.setAttribute("aria-labelledby",this.labelEl.id),void this.trigger.removeAttribute("aria-label");this.trigger.removeAttribute("aria-labelledby");const s=this.getAttribute("aria-label")||this.getAttribute("placeholder")||t("select.placeholder");this.trigger.setAttribute("aria-label",s)}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const e=h(this.getAttribute("size"),n,"m"),t=h(this.getAttribute("position"),l,"bottom"),s="full"===this.getAttribute("dropdown-width")?"full":"auto",i=Number(this.getAttribute("max-height")||200),a=this.getAttribute("label")||"",r=this.getAttribute("helper-text")||"",c=this.getAttribute("error-message")||"",o=this.hasAttribute("error"),d=this.getAttribute("id")||"";this.className=["designbase-wc-select",`designbase-wc-select--${e}`,this.open&&"designbase-wc-select--open",o&&"designbase-wc-select--error",this.hasAttribute("disabled")&&"designbase-wc-select--disabled",this.hasAttribute("readonly")&&"designbase-wc-select--readonly",this.hasAttribute("full-width")&&"designbase-wc-select--full-width",this.multiple&&"designbase-wc-select--multiple",this.searchable&&"designbase-wc-select--searchable"].filter(Boolean).join(" ");const u=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",u.length>0),this.labelEl){const e=this.hasAttribute("required")?'<span class="designbase-wc-select__required" aria-hidden="true">*</span>':"";this.labelEl.innerHTML=a?`${this.escape(a)}${e}`:"",this.labelEl.hidden=!a}this.syncAccessibleName(a),this.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${s}`,`designbase-wc-select__dropdown--${t}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${i}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const p=`${d}-helper`,b=`${d}-error`;o&&c?(this.errorEl.id=b,this.errorEl.textContent=c,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",b),this.trigger.setAttribute("aria-invalid","true")):r?(this.helperEl.id=p,this.helperEl.textContent=r,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",p),this.trigger.removeAttribute("aria-invalid")):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.trigger.removeAttribute("aria-describedby"),this.trigger.removeAttribute("aria-invalid")),this.hasAttribute("disabled")||this.hasAttribute("readonly")?this.trigger.tabIndex=-1:this.trigger.tabIndex=0,this.syncOpenState(),this.syncTrigger(),this.syncOptions(),this.syncFormValue(),this.syncIndicatorIcons()}syncOpenState(){this.trigger&&this.dropdown&&this.chevronEl&&(this.trigger.setAttribute("aria-expanded",String(this.open)),this.classList.toggle("designbase-wc-select--open",this.open),this.dropdown.classList.toggle("designbase-wc-select__dropdown--open",this.open),this.syncIndicatorIcons())}syncTrigger(){if(!this.valueEl||!this.clearButton)return;const e=this.parseOptions(),i=this.parseSelectedValues(),r=this.getAttribute("placeholder")||t("select.placeholder"),n=i.length>0,l=n&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===i.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=r,this.valueEl.appendChild(e)}else{const t=document.createElement("div");t.className="designbase-wc-select__tags",i.forEach(r=>{const n=e.find(e=>e.value===r),l=document.createElement("span");l.className="designbase-wc-select__tag";const h=document.createElement("span");h.className="designbase-wc-select__tag-label",h.textContent=n?.label||r;const c=document.createElement("button");c.type="button",c.className="designbase-wc-select__tag-remove",c.setAttribute("aria-label",s("{0} 제거",[n?.label||r])),c.appendChild(a("close",12)),c.addEventListener("click",e=>{e.stopPropagation();const t=i.filter(e=>e!==r);this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)}),l.append(h,c),t.appendChild(l)}),this.valueEl.appendChild(t)}else{const t=document.createElement("span");t.className="designbase-wc-select__single-value";const s=e.find(e=>e.value===i[0]);t.textContent=n?s?.label||i[0]:r,n||t.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(t)}this.clearButton.hidden=!l,this.clearButton.setAttribute("aria-hidden",l?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",n)}syncOptions(){if(!this.optionsEl)return;const t=this.getFilteredOptions(),s=this.parseSelectedValues(),i=this.getAttribute("id")||"db-select";if(this.optionsEl.replaceChildren(),0===t.length){const t=document.createElement("div");return t.className="designbase-wc-select__no-options",t.textContent=this.searchTerm?e(this,"label-no-results","select.noResults"):e(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(t)}t.forEach((e,t)=>{const a=s.includes(e.value),r=t===this.focusedIndex,n=document.createElement("div");if(n.className=["designbase-wc-select__option",a&&"designbase-wc-select__option--selected",r&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),n.id=`${i}-option-${t}`,n.setAttribute("role","option"),n.setAttribute("aria-selected",String(a)),n.setAttribute("aria-disabled",String(Boolean(e.disabled))),n.addEventListener("click",()=>this.selectOption(e)),this.multiple){const t=document.createElement("div");t.className="designbase-wc-select__checkbox";const s=document.createElement("db-checkbox");s.setAttribute("size","s"),s.setAttribute("has-label","false"),a&&s.setAttribute("checked",""),e.disabled&&s.setAttribute("disabled",""),t.appendChild(s),n.appendChild(t)}const l=document.createElement("span");l.className="designbase-wc-select__option-label",l.textContent=e.label,n.appendChild(l),this.optionsEl.appendChild(n)}),this.focusedIndex>=0?this.trigger?.setAttribute("aria-activedescendant",`${i}-option-${this.focusedIndex}`):this.trigger?.removeAttribute("aria-activedescendant")}escape(e){return e.replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e]||e))}}DbSelect.formAssociated=!0,customElements.get("db-select")||customElements.define("db-select",DbSelect);export{DbSelect};