@designbasekorea/ui-wc 0.9.2 → 0.9.4

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 (75) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/esm/components/date-picker-utils.js +1 -1
  3. package/dist/esm/components/db-activity-heatmap.js +1 -1
  4. package/dist/esm/components/db-ai-chat-list.js +1 -1
  5. package/dist/esm/components/db-ai-file-tree.js +1 -1
  6. package/dist/esm/components/db-alert.d.ts +12 -0
  7. package/dist/esm/components/db-alert.js +1 -1
  8. package/dist/esm/components/db-backdrop.js +1 -1
  9. package/dist/esm/components/db-bottom-sheet.js +1 -1
  10. package/dist/esm/components/db-calendar.d.ts +2 -1
  11. package/dist/esm/components/db-calendar.js +1 -1
  12. package/dist/esm/components/db-carousel.d.ts +2 -0
  13. package/dist/esm/components/db-carousel.js +1 -1
  14. package/dist/esm/components/db-chat-composer.js +1 -1
  15. package/dist/esm/components/db-checkbox.d.ts +15 -1
  16. package/dist/esm/components/db-checkbox.js +1 -1
  17. package/dist/esm/components/db-code-block.js +1 -1
  18. package/dist/esm/components/db-confirm.d.ts +2 -0
  19. package/dist/esm/components/db-confirm.js +1 -1
  20. package/dist/esm/components/db-context-menu.js +1 -1
  21. package/dist/esm/components/db-credit-card.d.ts +3 -4
  22. package/dist/esm/components/db-credit-card.js +1 -1
  23. package/dist/esm/components/db-cursor-follower.js +1 -1
  24. package/dist/esm/components/db-date-picker.d.ts +2 -1
  25. package/dist/esm/components/db-date-picker.js +1 -1
  26. package/dist/esm/components/db-design-toolbar.js +1 -1
  27. package/dist/esm/components/db-device-mockup.js +1 -1
  28. package/dist/esm/components/db-drawer.d.ts +1 -0
  29. package/dist/esm/components/db-drawer.js +1 -1
  30. package/dist/esm/components/db-dropdown.js +1 -1
  31. package/dist/esm/components/db-flight-status.d.ts +2 -2
  32. package/dist/esm/components/db-flight-status.js +1 -1
  33. package/dist/esm/components/db-gantt.js +1 -1
  34. package/dist/esm/components/db-indicator.d.ts +1 -0
  35. package/dist/esm/components/db-indicator.js +1 -1
  36. package/dist/esm/components/db-kanban.js +1 -1
  37. package/dist/esm/components/db-lightbox.js +1 -1
  38. package/dist/esm/components/db-modal.js +1 -1
  39. package/dist/esm/components/db-node.d.ts +1 -3
  40. package/dist/esm/components/db-node.js +1 -1
  41. package/dist/esm/components/db-onboarding-modal.js +1 -1
  42. package/dist/esm/components/db-popover.js +1 -1
  43. package/dist/esm/components/db-radio.d.ts +19 -1
  44. package/dist/esm/components/db-radio.js +1 -1
  45. package/dist/esm/components/db-receipt.js +1 -1
  46. package/dist/esm/components/db-search-bar.js +1 -1
  47. package/dist/esm/components/db-select.js +1 -1
  48. package/dist/esm/components/db-tabs.js +1 -1
  49. package/dist/esm/components/db-textarea.js +1 -1
  50. package/dist/esm/components/db-time-picker.js +1 -1
  51. package/dist/esm/components/db-tool-button.js +1 -1
  52. package/dist/esm/components/db-tooltip.js +1 -1
  53. package/dist/esm/components/db-tutorial.js +1 -1
  54. package/dist/esm/components/db-voice-control.js +1 -1
  55. package/dist/esm/core/ai-element.d.ts +2 -1
  56. package/dist/esm/core/ai-element.js +1 -1
  57. package/dist/esm/core/focus-trap.js +1 -1
  58. package/dist/esm/core/host-class.js +1 -0
  59. package/dist/esm/core/i18n-copy.js +1 -1
  60. package/dist/esm/core/i18n-en.js +1 -1
  61. package/dist/esm/core/i18n.d.ts +16 -0
  62. package/dist/esm/core/i18n.js +1 -1
  63. package/dist/esm/core/theme-scope.js +1 -0
  64. package/dist/esm/index.d.ts +2 -2
  65. package/dist/esm/index.js +1 -1
  66. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  67. package/dist/esm/ui-contracts/dist/components.d.d.ts +9 -2
  68. package/dist/index.cjs +1 -1
  69. package/dist/index.css +1 -1
  70. package/dist/index.d.ts +83 -13
  71. package/dist/index.esm.js +1 -1
  72. package/dist/react/index.cjs +1 -1
  73. package/dist/react/index.d.ts +35 -9
  74. package/dist/react/index.esm.js +1 -1
  75. package/package.json +3 -2
@@ -1 +1 @@
1
- import{dbText as t}from"../core/i18n.js";import{createDbIcon as e}from"./db-icons.js";import{createFocusTrap as i}from"../core/focus-trap.js";import{lockScroll as s,unlockScroll as n}from"../core/scroll-lock.js";class DbOnboardingModal extends HTMLElement{constructor(){super(...arguments),this.scrollLocked=!1,this.internalStep=0,this.keyHandler=null,this.isMounted=!1,this.handlePrev=()=>{this.getCurrentStep()>0&&this.goToStep(this.getCurrentStep()-1)},this.handleNext=()=>{const t=this.getSteps(),e=this.getCurrentStep();e>=t.length-1?this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})):this.goToStep(e+1)}}static get observedAttributes(){return["open","steps","current-step","show-close-button","show-indicator","indicator-type","indicator-size"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}get steps(){return this.parseSteps()}set steps(t){const e="string"==typeof t?t:JSON.stringify(t);this.getAttribute("steps")!==e&&this.setAttribute("steps",e)}connectedCallback(){this.style.display="contents",this.syncStepFromAttribute(),this.syncOpenState()}disconnectedCallback(){this.detachKeyHandler(),this.unmount()}attributeChangedCallback(t){this.isConnected&&("open"!==t?("current-step"===t&&this.syncStepFromAttribute(),"steps"!==t?this.isMounted&&this.render():this.isOpenRequested()&&(this.isMounted?this.render():this.syncOpenState())):this.syncOpenState())}isOpenRequested(){return this.open}parseSteps(){const t=this.getAttribute("steps");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}syncStepFromAttribute(){if(!this.hasAttribute("current-step"))return;const t=Number(this.getAttribute("current-step")||0);Number.isFinite(t)&&(this.internalStep=Math.max(0,t))}getSteps(){return this.parseSteps()}getCurrentStep(){const t=this.getSteps();return t.length?Math.min(Math.max(this.internalStep,0),t.length-1):0}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}emitStepChange(t){this.dispatchEvent(new CustomEvent("db-step-change",{bubbles:!0,composed:!0,detail:{step:t}}))}goToStep(t){const e=this.getSteps();if(!e.length)return;const i=Math.min(Math.max(t,0),e.length-1);this.internalStep=i,this.emitStepChange(i),this.render()}attachKeyHandler(){this.keyHandler||(this.keyHandler=t=>{"Escape"!==t.key?"ArrowLeft"===t.key&&this.getCurrentStep()>0?this.handlePrev():"ArrowRight"===t.key&&this.getCurrentStep()<this.getSteps().length-1&&this.handleNext():this.close()},document.addEventListener("keydown",this.keyHandler))}detachKeyHandler(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}syncOpenState(){if(this.isOpenRequested())return this.mount(),void this.attachKeyHandler();this.detachKeyHandler(),this.unmount()}mount(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-onboarding-modal",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.tabIndex=-1,this.ensureStructure()),this.root.isConnected||document.body.append(this.root),this.isMounted=!0,this.render(),this.scrollLocked||(s(),this.scrollLocked=!0),this.root&&!this.focusTrap&&(this.focusTrap=i(this.root),requestAnimationFrame(()=>this.focusTrap?.activate()))}unmount(){this.isMounted=!1,this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.scrollLocked&&(this.scrollLocked=!1,n())}ensureStructure(){this.root&&(this.contentEl&&this.root.contains(this.contentEl)||(this.overlayEl=void 0,this.contentEl=void 0,this.closeButtonEl=void 0,this.mainEl=void 0,this.imageWrapEl=void 0,this.imageEl=void 0,this.textEl=void 0,this.titleEl=void 0,this.descriptionEl=void 0,this.navigationEl=void 0,this.prevButtonEl=void 0,this.nextButtonEl=void 0,this.indicatorEl=void 0,this.root.replaceChildren(),this.overlayEl=document.createElement("div"),this.overlayEl.className="designbase-wc-onboarding-modal__overlay",this.overlayEl.addEventListener("click",()=>this.close()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-onboarding-modal__content",this.closeButtonEl=document.createElement("button"),this.closeButtonEl.type="button",this.closeButtonEl.className="designbase-wc-onboarding-modal__close-button",this.closeButtonEl.setAttribute("aria-label",t("닫기")),this.closeButtonEl.append(e("close",20)),this.closeButtonEl.addEventListener("click",()=>this.close()),this.mainEl=document.createElement("div"),this.mainEl.className="designbase-wc-onboarding-modal__main",this.imageWrapEl=document.createElement("div"),this.imageWrapEl.className="designbase-wc-onboarding-modal__image",this.imageEl=document.createElement("img"),this.imageWrapEl.append(this.imageEl),this.textEl=document.createElement("div"),this.textEl.className="designbase-wc-onboarding-modal__text",this.titleEl=document.createElement("h2"),this.titleEl.id="onboarding-title",this.titleEl.className="designbase-wc-onboarding-modal__title",this.descriptionEl=document.createElement("p"),this.descriptionEl.id="onboarding-description",this.descriptionEl.className="designbase-wc-onboarding-modal__description",this.textEl.append(this.titleEl,this.descriptionEl),this.mainEl.append(this.imageWrapEl,this.textEl),this.navigationEl=document.createElement("div"),this.navigationEl.className="designbase-wc-onboarding-modal__navigation",this.prevButtonEl=document.createElement("db-button"),this.prevButtonEl.setAttribute("variant","secondary"),this.prevButtonEl.setAttribute("size","m"),this.prevButtonEl.setAttribute("start-icon","chevron-left"),this.prevButtonEl.setAttribute("aria-label",t("이전")),this.prevButtonEl.addEventListener("db-click",this.handlePrev),this.indicatorEl=document.createElement("db-indicator"),this.indicatorEl.addEventListener("db-step-click",t=>{const e=t.detail;this.goToStep(e.index??e.current)}),this.nextButtonEl=document.createElement("db-button"),this.nextButtonEl.setAttribute("variant","primary"),this.nextButtonEl.setAttribute("size","m"),this.nextButtonEl.addEventListener("db-click",this.handleNext),this.navigationEl.append(this.prevButtonEl,this.indicatorEl,this.nextButtonEl),this.contentEl.append(this.closeButtonEl,this.mainEl,this.navigationEl),this.root.append(this.overlayEl,this.contentEl)))}render(){if(!this.root||!this.isMounted)return;this.ensureStructure();const e=this.getSteps(),i=this.getCurrentStep(),s=e[i];if(!s)return;const n=!this.hasAttribute("show-close-button")||"false"!==this.getAttribute("show-close-button"),o=!this.hasAttribute("show-indicator")||"false"!==this.getAttribute("show-indicator"),r=this.getAttribute("indicator-type")||"dots",a=this.getAttribute("indicator-size")||"m",l=0===i,h=i===e.length-1;if(this.root.setAttribute("aria-labelledby","onboarding-title"),this.root.setAttribute("aria-describedby","onboarding-description"),this.closeButtonEl&&(this.closeButtonEl.style.display=n?"":"none"),this.imageWrapEl&&this.imageEl&&(s.image?(this.imageEl.src=s.image,this.imageEl.alt=s.title||"온보딩 이미지",this.imageWrapEl.style.display=""):this.imageWrapEl.style.display="none"),this.titleEl&&(this.titleEl.textContent=s.title||"",this.titleEl.style.display=s.title?"":"none"),this.descriptionEl&&(this.descriptionEl.textContent=s.description||"",this.descriptionEl.style.display=s.description?"":"none"),this.prevButtonEl&&(this.prevButtonEl.textContent=t("이전"),l?this.prevButtonEl.setAttribute("disabled",""):this.prevButtonEl.removeAttribute("disabled")),this.nextButtonEl&&(this.nextButtonEl.textContent=h?"완료":"다음",this.nextButtonEl.setAttribute("aria-label",h?"완료":"다음"),h?this.nextButtonEl.removeAttribute("end-icon"):this.nextButtonEl.setAttribute("end-icon","chevron-right")),this.indicatorEl){const t=o&&e.length>1;this.indicatorEl.style.display=t?"":"none",t&&(this.indicatorEl.setAttribute("total",String(e.length)),this.indicatorEl.setAttribute("current",String(i)),this.indicatorEl.setAttribute("indicator-type",r),this.indicatorEl.setAttribute("size",a),this.indicatorEl.setAttribute("clickable",""))}}}customElements.get("db-onboarding-modal")||customElements.define("db-onboarding-modal",DbOnboardingModal);export{DbOnboardingModal};
1
+ import{inheritThemeScope as t}from"../core/theme-scope.js";import{dbText as e}from"../core/i18n.js";import{createDbIcon as i}from"./db-icons.js";import{createFocusTrap as s}from"../core/focus-trap.js";import{lockScroll as n,unlockScroll as o}from"../core/scroll-lock.js";class DbOnboardingModal extends HTMLElement{constructor(){super(...arguments),this.scrollLocked=!1,this.internalStep=0,this.keyHandler=null,this.isMounted=!1,this.handlePrev=()=>{this.getCurrentStep()>0&&this.goToStep(this.getCurrentStep()-1)},this.handleNext=()=>{const t=this.getSteps(),e=this.getCurrentStep();e>=t.length-1?this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})):this.goToStep(e+1)}}static get observedAttributes(){return["open","steps","current-step","show-close-button","show-indicator","indicator-type","indicator-size"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}get steps(){return this.parseSteps()}set steps(t){const e="string"==typeof t?t:JSON.stringify(t);this.getAttribute("steps")!==e&&this.setAttribute("steps",e)}connectedCallback(){this.style.display="contents",this.syncStepFromAttribute(),this.syncOpenState()}disconnectedCallback(){this.detachKeyHandler(),this.unmount()}attributeChangedCallback(t){this.isConnected&&("open"!==t?("current-step"===t&&this.syncStepFromAttribute(),"steps"!==t?this.isMounted&&this.render():this.isOpenRequested()&&(this.isMounted?this.render():this.syncOpenState())):this.syncOpenState())}isOpenRequested(){return this.open}parseSteps(){const t=this.getAttribute("steps");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}syncStepFromAttribute(){if(!this.hasAttribute("current-step"))return;const t=Number(this.getAttribute("current-step")||0);Number.isFinite(t)&&(this.internalStep=Math.max(0,t))}getSteps(){return this.parseSteps()}getCurrentStep(){const t=this.getSteps();return t.length?Math.min(Math.max(this.internalStep,0),t.length-1):0}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}emitStepChange(t){this.dispatchEvent(new CustomEvent("db-step-change",{bubbles:!0,composed:!0,detail:{step:t}}))}goToStep(t){const e=this.getSteps();if(!e.length)return;const i=Math.min(Math.max(t,0),e.length-1);this.internalStep=i,this.emitStepChange(i),this.render()}attachKeyHandler(){this.keyHandler||(this.keyHandler=t=>{"Escape"!==t.key?"ArrowLeft"===t.key&&this.getCurrentStep()>0?this.handlePrev():"ArrowRight"===t.key&&this.getCurrentStep()<this.getSteps().length-1&&this.handleNext():this.close()},document.addEventListener("keydown",this.keyHandler))}detachKeyHandler(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}syncOpenState(){if(this.isOpenRequested())return this.mount(),void this.attachKeyHandler();this.detachKeyHandler(),this.unmount()}mount(){this.root||(this.root=document.createElement("div"),this.root.className="designbase-wc-onboarding-modal",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.tabIndex=-1,this.ensureStructure()),this.root.isConnected||(t(this,this.root),document.body.append(this.root)),this.isMounted=!0,this.render(),this.scrollLocked||(n(),this.scrollLocked=!0),this.root&&!this.focusTrap&&(this.focusTrap=s(this.root),requestAnimationFrame(()=>this.focusTrap?.activate()))}unmount(){this.isMounted=!1,this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.scrollLocked&&(this.scrollLocked=!1,o())}ensureStructure(){this.root&&(this.contentEl&&this.root.contains(this.contentEl)||(this.overlayEl=void 0,this.contentEl=void 0,this.closeButtonEl=void 0,this.mainEl=void 0,this.imageWrapEl=void 0,this.imageEl=void 0,this.textEl=void 0,this.titleEl=void 0,this.descriptionEl=void 0,this.navigationEl=void 0,this.prevButtonEl=void 0,this.nextButtonEl=void 0,this.indicatorEl=void 0,this.root.replaceChildren(),this.overlayEl=document.createElement("div"),this.overlayEl.className="designbase-wc-onboarding-modal__overlay",this.overlayEl.addEventListener("click",()=>this.close()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-onboarding-modal__content",this.closeButtonEl=document.createElement("button"),this.closeButtonEl.type="button",this.closeButtonEl.className="designbase-wc-onboarding-modal__close-button",this.closeButtonEl.setAttribute("aria-label",e("닫기")),this.closeButtonEl.append(i("close",20)),this.closeButtonEl.addEventListener("click",()=>this.close()),this.mainEl=document.createElement("div"),this.mainEl.className="designbase-wc-onboarding-modal__main",this.imageWrapEl=document.createElement("div"),this.imageWrapEl.className="designbase-wc-onboarding-modal__image",this.imageEl=document.createElement("img"),this.imageWrapEl.append(this.imageEl),this.textEl=document.createElement("div"),this.textEl.className="designbase-wc-onboarding-modal__text",this.titleEl=document.createElement("h2"),this.titleEl.id="onboarding-title",this.titleEl.className="designbase-wc-onboarding-modal__title",this.descriptionEl=document.createElement("p"),this.descriptionEl.id="onboarding-description",this.descriptionEl.className="designbase-wc-onboarding-modal__description",this.textEl.append(this.titleEl,this.descriptionEl),this.mainEl.append(this.imageWrapEl,this.textEl),this.navigationEl=document.createElement("div"),this.navigationEl.className="designbase-wc-onboarding-modal__navigation",this.prevButtonEl=document.createElement("db-button"),this.prevButtonEl.setAttribute("variant","secondary"),this.prevButtonEl.setAttribute("size","m"),this.prevButtonEl.setAttribute("start-icon","chevron-left"),this.prevButtonEl.setAttribute("aria-label",e("이전")),this.prevButtonEl.addEventListener("db-click",this.handlePrev),this.indicatorEl=document.createElement("db-indicator"),this.indicatorEl.addEventListener("db-step-click",t=>{const e=t.detail;this.goToStep(e.index??e.current)}),this.nextButtonEl=document.createElement("db-button"),this.nextButtonEl.setAttribute("variant","primary"),this.nextButtonEl.setAttribute("size","m"),this.nextButtonEl.addEventListener("db-click",this.handleNext),this.navigationEl.append(this.prevButtonEl,this.indicatorEl,this.nextButtonEl),this.contentEl.append(this.closeButtonEl,this.mainEl,this.navigationEl),this.root.append(this.overlayEl,this.contentEl)))}render(){if(!this.root||!this.isMounted)return;this.ensureStructure();const t=this.getSteps(),i=this.getCurrentStep(),s=t[i];if(!s)return;const n=!this.hasAttribute("show-close-button")||"false"!==this.getAttribute("show-close-button"),o=!this.hasAttribute("show-indicator")||"false"!==this.getAttribute("show-indicator"),r=this.getAttribute("indicator-type")||"dots",a=this.getAttribute("indicator-size")||"m",l=0===i,h=i===t.length-1;if(this.root.setAttribute("aria-labelledby","onboarding-title"),this.root.setAttribute("aria-describedby","onboarding-description"),this.closeButtonEl&&(this.closeButtonEl.style.display=n?"":"none"),this.imageWrapEl&&this.imageEl&&(s.image?(this.imageEl.src=s.image,this.imageEl.alt=s.title||"온보딩 이미지",this.imageWrapEl.style.display=""):this.imageWrapEl.style.display="none"),this.titleEl&&(this.titleEl.textContent=s.title||"",this.titleEl.style.display=s.title?"":"none"),this.descriptionEl&&(this.descriptionEl.textContent=s.description||"",this.descriptionEl.style.display=s.description?"":"none"),this.prevButtonEl&&(this.prevButtonEl.textContent=e("이전"),l?this.prevButtonEl.setAttribute("disabled",""):this.prevButtonEl.removeAttribute("disabled")),this.nextButtonEl&&(this.nextButtonEl.textContent=h?"완료":"다음",this.nextButtonEl.setAttribute("aria-label",h?"완료":"다음"),h?this.nextButtonEl.removeAttribute("end-icon"):this.nextButtonEl.setAttribute("end-icon","chevron-right")),this.indicatorEl){const e=o&&t.length>1;this.indicatorEl.style.display=e?"":"none",e&&(this.indicatorEl.setAttribute("total",String(t.length)),this.indicatorEl.setAttribute("current",String(i)),this.indicatorEl.setAttribute("indicator-type",r),this.indicatorEl.setAttribute("size",a),this.indicatorEl.setAttribute("clickable",""))}}}customElements.get("db-onboarding-modal")||customElements.define("db-onboarding-modal",DbOnboardingModal);export{DbOnboardingModal};
@@ -1 +1 @@
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
+ import{inheritThemeScope as e}from"../core/theme-scope.js";import{dbText as t}from"../core/i18n.js";import{POPOVER_PLACEMENTS as i,POPOVER_TRIGGERS as s}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 i.includes(e)?e:"top"}resolvedTrigger(){const e=this.getAttribute("trigger")||"click";return s.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 t=Number(this.getAttribute("max-width")||300);this.panel.style.maxWidth=`${t}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),i.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 i=document.createElement("div");i.className="designbase-wc-popover",i.setAttribute("data-wc-internal",""),i.setAttribute("role","dialog"),i.setAttribute("aria-modal","false"),i.style.position="fixed",i.style.zIndex="9999";const s=document.createElement("div");s.className="designbase-wc-popover__content";const r=document.createElement("div");r.className="designbase-wc-popover__header";const o=document.createElement("h3");o.className="designbase-wc-popover__title";const n=document.createElement("db-button");n.className="designbase-wc-popover__close-button",n.setAttribute("variant","ghost"),n.setAttribute("size","s"),n.setAttribute("icon-only",""),n.setAttribute("start-icon","close"),n.setAttribute("aria-label",t("팝오버 닫기")),n.addEventListener("db-click",e=>{e.stopPropagation(),this.setOpen(!1)}),r.append(o,n),this.bodyEl=document.createElement("div"),this.bodyEl.className="designbase-wc-popover__body",s.append(r,this.bodyEl),i.append(s),"false"!==this.getAttribute("show-arrow")&&(this.arrowEl=document.createElement("div"),this.arrowEl.className=`designbase-wc-popover__arrow designbase-wc-popover__arrow--${this.resolvedPlacement()}`,i.append(this.arrowEl)),this.panel=i,this.panel.querySelector(".designbase-wc-popover__title").textContent=this.getAttribute("title")||"",this.panel.querySelector(".designbase-wc-popover__title").hidden=!this.getAttribute("title"),e(this,i),document.body.append(i),i.addEventListener("mouseenter",()=>{"hover"===this.resolvedTrigger()&&this.clearTimers()}),i.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};
@@ -7,8 +7,22 @@ declare class DbRadio extends HTMLElement {
7
7
  private labelEl?;
8
8
  private built;
9
9
  private userInteracted;
10
+ private resetChecked?;
11
+ private readonly cleanups;
12
+ focus(options?: FocusOptions): void;
13
+ get name(): string;
14
+ set name(value: string);
15
+ get value(): string;
16
+ set value(value: string);
17
+ get defaultChecked(): boolean;
18
+ set defaultChecked(value: boolean);
19
+ get defaultSelected(): boolean;
20
+ set defaultSelected(value: boolean);
21
+ private upgradeProperties;
10
22
  get checked(): boolean;
11
23
  set checked(value: boolean);
24
+ get selected(): boolean;
25
+ set selected(value: boolean);
12
26
  get disabled(): boolean;
13
27
  set disabled(value: boolean);
14
28
  get readOnly(): boolean;
@@ -18,10 +32,14 @@ declare class DbRadio extends HTMLElement {
18
32
  get size(): string;
19
33
  set size(value: string);
20
34
  connectedCallback(): void;
35
+ disconnectedCallback(): void;
21
36
  attributeChangedCallback(name: string): void;
22
- private get hasLabel();
37
+ get hasLabel(): boolean;
38
+ set hasLabel(value: boolean);
23
39
  private build;
24
40
  private handleChange;
41
+ private groupPeers;
42
+ private syncGroup;
25
43
  private syncState;
26
44
  private syncVisual;
27
45
  private syncClasses;
@@ -1 +1 @@
1
- import{RADIO_SIZES as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbRadio extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.userInteracted=!1,this.handleChange=()=>{if(!this.input||this.disabled||this.readOnly)return;this.userInteracted=!0;const t=this.input.checked;this.toggleAttribute("checked",t),this.syncVisual(),this.syncClasses(),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:t,selected:t,value:this.getAttribute("value")||""},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","size","disabled","readonly","required","name","value","has-label"]}get checked(){return this.input?.checked??(this.hasAttribute("checked")||this.hasAttribute("selected"))}set checked(t){this.toggleAttribute("checked",t),this.input&&(this.input.checked=t,this.syncVisual(),this.syncClasses())}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t),this.input&&(this.input.disabled=t),this.syncClasses()}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t),this.input&&(this.input.readOnly=t),this.syncClasses()}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",t),this.input&&(this.input.required=t)}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}connectedCallback(){this.style.display="contents",this.built||this.build(),this.syncState()}attributeChangedCallback(t){if(this.built)return"checked"===t||"selected"===t?(this.input&&(this.input.checked=this.hasAttribute("checked")||this.hasAttribute("selected")),this.syncVisual(),void this.syncClasses()):void this.syncState()}get hasLabel(){return!this.hasAttribute("has-label")||"false"!==this.getAttribute("has-label")}build(){for(this.root=document.createElement("label"),this.root.className="designbase-wc-radio",this.input=document.createElement("input"),this.input.type="radio",this.input.className="designbase-wc-radio__input",this.visual=document.createElement("span"),this.visual.className="designbase-wc-radio__visual",this.visual.setAttribute("aria-hidden","true"),this.dot=document.createElement("span"),this.dot.className="designbase-wc-radio__dot",this.visual.appendChild(this.dot),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-radio__label";this.firstChild;)this.labelEl.appendChild(this.firstChild);this.root.append(this.input,this.visual,this.labelEl),this.appendChild(this.root),this.input.addEventListener("change",this.handleChange),this.built=!0}syncState(){if(!this.root||!this.input||!this.visual)return;const t=this.hasAttribute("checked")||this.hasAttribute("selected")||!this.userInteracted&&(this.hasAttribute("default-checked")||this.hasAttribute("default-selected"));this.input.checked=t,this.input.disabled=this.disabled,this.input.readOnly=this.readOnly,this.input.required=this.required,this.input.name=this.getAttribute("name")||"",this.input.value=this.getAttribute("value")||"",this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncVisual(),this.syncClasses()}syncVisual(){}syncClasses(){if(!this.root||!this.input)return;const e=t.includes(this.size)?this.size:"m",s=this.hasLabel&&Boolean(this.labelEl?.textContent?.trim());this.root.className=["designbase-wc-radio",`designbase-wc-radio--${e}`,this.input.checked&&"designbase-wc-radio--selected",this.disabled&&"designbase-wc-radio--disabled",this.readOnly&&"designbase-wc-radio--readonly",!s&&"designbase-wc-radio--no-label"].filter(Boolean).join(" ")}}customElements.get("db-radio")||customElements.define("db-radio",DbRadio);export{DbRadio};
1
+ import{CleanupBag as t}from"../core/dom.js";import{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RADIO_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbRadio extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.userInteracted=!1,this.cleanups=new t,this.handleChange=()=>{if(!this.input||this.disabled||this.readOnly)return;this.userInteracted=!0;const t=this.input.checked;this.removeAttribute("selected"),this.toggleAttribute("checked",t),this.syncGroup(),this.syncVisual(),this.syncClasses(),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:t,selected:t,value:this.input.value},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","size","disabled","readonly","required","name","value","has-label","aria-label","aria-labelledby","aria-describedby"]}focus(t){this.input?.focus(t)}get name(){return this.getAttribute("name")||""}set name(t){this.setAttribute("name",t)}get value(){return this.getAttribute("value")??"on"}set value(t){this.setAttribute("value",t)}get defaultChecked(){return this.hasAttribute("default-checked")||this.hasAttribute("default-selected")}set defaultChecked(t){this.removeAttribute("default-selected"),this.toggleAttribute("default-checked",t)}get defaultSelected(){return this.defaultChecked}set defaultSelected(t){this.defaultChecked=t}upgradeProperties(){for(const t of["checked","selected","defaultChecked","defaultSelected","name","value","disabled","readOnly","required","hasLabel","size"]){if(!Object.prototype.hasOwnProperty.call(this,t))continue;const e=this,s=e[t];delete e[t],e[t]=s}}get checked(){return this.input?.checked??(this.hasAttribute("checked")||this.hasAttribute("selected"))}set checked(t){this.userInteracted=!0,this.removeAttribute("selected"),this.toggleAttribute("checked",t),this.input&&(this.input.checked=t,this.syncVisual(),this.syncClasses(),this.syncGroup())}get selected(){return this.checked}set selected(t){this.checked=t}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t),this.input&&(this.input.disabled=t),this.syncClasses()}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t),this.input&&(this.input.readOnly=t),this.syncClasses()}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",t),this.input&&(this.input.required=t)}get size(){return e(this.getAttribute("size"),s,"m")}set size(t){this.setAttribute("size",t)}connectedCallback(){this.upgradeProperties(),this.style.display="contents",this.built||this.build(),this.syncState(),this.input?.form&&this.cleanups.listen(this.input.form,"reset",()=>{window.setTimeout(()=>{this.input&&this.isConnected&&(this.toggleAttribute("checked",this.input.checked),this.removeAttribute("selected"),this.syncClasses())},0)})}disconnectedCallback(){this.cleanups.run()}attributeChangedCallback(t){if(this.built){if("default-checked"!==t&&"default-selected"!==t||(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),"checked"===t||"selected"===t)return this.userInteracted=!0,this.input&&(this.input.checked=this.hasAttribute("checked")||this.hasAttribute("selected")),this.syncVisual(),this.syncClasses(),void this.syncGroup();this.syncState()}}get hasLabel(){return!this.hasAttribute("has-label")||"false"!==this.getAttribute("has-label")}set hasLabel(t){this.setAttribute("has-label",String(t))}build(){for(this.root=document.createElement("label"),this.root.className="designbase-wc-radio",this.input=document.createElement("input"),this.input.type="radio",this.input.className="designbase-wc-radio__input",this.visual=document.createElement("span"),this.visual.className="designbase-wc-radio__visual",this.visual.setAttribute("aria-hidden","true"),this.dot=document.createElement("span"),this.dot.className="designbase-wc-radio__dot",this.visual.appendChild(this.dot),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-radio__label";this.firstChild;)this.labelEl.appendChild(this.firstChild);this.root.append(this.input,this.visual,this.labelEl),this.appendChild(this.root),this.input.addEventListener("click",t=>{this.readOnly&&t.preventDefault()}),this.input.addEventListener("keydown",t=>{const e=["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"];if(this.readOnly&&(" "===t.key||e.includes(t.key)))return void t.preventDefault();const s=this.groupPeers();if(!e.includes(t.key)||!s.some(t=>t.readOnly))return;const i=s.filter(t=>!t.disabled&&!t.readOnly);if(!i.length)return;t.preventDefault();const r="rtl"===getComputedStyle(this).direction,a="ArrowDown"===t.key||t.key===(r?"ArrowLeft":"ArrowRight"),h=i[(i.indexOf(this)+(a?1:-1)+i.length)%i.length];h.input?.focus(),h.input?.click()}),this.input.addEventListener("change",this.handleChange),this.built=!0}groupPeers(){if(!this.input?.name)return[this];const t=this.getRootNode();return Array.from(t.querySelectorAll("db-radio")).filter(t=>t.input?.name===this.input.name&&t.input?.form===this.input.form)}syncGroup(){if(this.input?.checked&&this.input.name){const t=this.getRootNode();for(const e of t.querySelectorAll("db-radio"))e!==this&&e.input&&e.input.name===this.input.name&&e.input.form===this.input.form&&(e.userInteracted=!0,e.removeAttribute("checked"),e.removeAttribute("selected"),e.syncClasses())}}syncState(){if(!this.root||!this.input||!this.visual)return;const t=this.hasAttribute("checked")||this.hasAttribute("selected")||!this.userInteracted&&(this.hasAttribute("default-checked")||this.hasAttribute("default-selected"));this.resetChecked??(this.resetChecked=t),this.input.defaultChecked=this.resetChecked,this.input.checked=t,this.input.disabled=this.disabled,this.input.readOnly=this.readOnly,this.input.setAttribute("aria-disabled",String(this.disabled||this.readOnly)),this.input.required=this.required,this.input.name=this.getAttribute("name")||"",this.input.value=this.getAttribute("value")??"on";for(const t of["aria-label","aria-labelledby","aria-describedby"]){const e=this.getAttribute(t);e?this.input.setAttribute(t,e):this.input.removeAttribute(t)}this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncVisual(),this.syncClasses()}syncVisual(){}syncClasses(){if(!this.root||!this.input)return;const t=s.includes(this.size)?this.size:"m",e=this.hasLabel&&Boolean(this.labelEl?.textContent?.trim());this.root.className=["designbase-wc-radio",`designbase-wc-radio--${t}`,this.input.checked&&"designbase-wc-radio--selected",this.disabled&&"designbase-wc-radio--disabled",this.readOnly&&"designbase-wc-radio--readonly",!e&&"designbase-wc-radio--no-label"].filter(Boolean).join(" ")}}customElements.get("db-radio")||customElements.define("db-radio",DbRadio);export{DbRadio};
@@ -1 +1 @@
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
+ 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";import{coerceToContract as n}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RECEIPT_VARIANTS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const p={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(p).map(([e,a])=>[e,t(`receipt.${e}`,a)])),...this.customLabels}}set labels(t){this.customLabels={};for(const e of Object.keys(p))"string"==typeof t?.[e]&&(this.customLabels[e]=t[e]);this.isConnected&&this.render()}render(){const a="compact"===n(this.getAttribute("variant"),o,"default");this.dataset.variant=a?"compact":"default";const r=this.labels,p=i("section","db-paper__main");p.append(i("h3","db-paper__title",this.attr("merchant")||t("receipt.title"))),this.attr("merchant-detail")&&p.append(i("p","db-paper__description",this.attr("merchant-detail")));const c=i("div","db-paper__receipt-meta");let d;this.attr("issued-at")&&c.append(i("span","",this.attr("issued-at"))),!a&&this.attr("reference")&&c.append(i("span","",this.attr("reference"))),p.append(c);try{d=new Intl.NumberFormat(this.attr("locale")||("ko"===e()?"ko-KR":"en-US"),{style:"currency",currency:this.attr("currency")||"KRW"})}catch{d=new Intl.NumberFormat("ko"===e()?"ko-KR":"en-US",{style:"currency",currency:"KRW"})}const m=d.resolvedOptions().maximumFractionDigits||0,u=BigInt(10**m),l=new Intl.NumberFormat(d.resolvedOptions().locale,{useGrouping:!1,minimumIntegerDigits:Math.max(1,m),maximumFractionDigits:0}),money=t=>{const e=BigInt(t);return d.formatToParts(e/u).map(t=>"fraction"===t.type?l.format(e%u):t.value).join("")};let b=this.data;if(void 0===b)try{b=this.hasAttribute("items")?JSON.parse(this.attr("items")):[]}catch{b=null}const h=Array.isArray(b)?b:[];let y=Array.isArray(b),f=0;for(const t of h){if(!t||"string"!=typeof t.name||!Number.isSafeInteger(t.quantity)||t.quantity<=0||!minor(t.unitAmount)||!Number.isSafeInteger(t.quantity*t.unitAmount)){y=!1;break}if(f+=t.quantity*t.unitAmount,!Number.isSafeInteger(f)){y=!1;break}}const amount=t=>this.hasAttribute(t)&&""===this.attr(t).trim()?NaN:Number(this.getAttribute(t)??0),g=amount("discount-amount"),_=amount("tax-amount");y=y&&minor(g)&&minor(_)&&g<=f&&Number.isSafeInteger(f-g+_);const v=i("div","db-paper__receipt-items");if(y)if(h.length)for(const t of h){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))),v.append(e)}else v.append(i("p","db-paper__note",r.empty));else{const t=i("p","db-paper__error",r.invalid);t.setAttribute("role","alert"),v.append(t)}p.append(v);const A=i("div","db-paper__stub"),N=a?p:A;if(y&&(!a||g||_)){const t=[{label:r.subtotal,value:money(f)}];g&&t.push({label:r.discount,value:"−"+money(g)}),_&&t.push({label:r.tax,value:money(_)}),N.append(s(t))}const I=i("div","db-paper__receipt-total");I.append(i("strong","",r.total),i("strong","db-paper__amount",y?money(f-g+_):"—")),N.append(I),this.attr("payment-method")&&N.append(s([{label:r.payment,value:this.attr("payment-method")}])),this.attr("note")&&N.append(i("p","db-paper__note",this.attr("note"))),(a||this.attr("code-image-src"))&&A.append(this.code(this.attr("reference")));const k=this.action(this.attr("reference"));k&&(k.toggleAttribute("disabled",!y||this.hasAttribute("disabled")),A.append(k)),this.replace(p,A)}}customElements.get("db-receipt")||customElements.define("db-receipt",DbReceipt);export{DbReceipt};
@@ -1 +1 @@
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};
1
+ import{inheritThemeScope as e}from"../core/theme-scope.js";import{dbText as t,dbFormat as s}from"../core/i18n.js";import{getDbComponentIconSize as a,createDbIcon as n}from"./db-icons.js";import{SEARCH_BAR_SIZES as r,SEARCH_BAR_RECENT_LAYOUTS as i}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 r.includes(e)?e:"m"}getIconPx(){return a(this.getResolvedSize())}syncIcons(){const e=this.getIconPx();this.querySelector(".designbase-wc-search-bar__search-icon")?.replaceChildren(n("search",e)),this.clearButton?.replaceChildren(n("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--${r.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&&(e(this,this.dropdown),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 e=this.shouldShowDropdown();if(this.dropdown.hidden=!e,this.classList.toggle("designbase-wc-search-bar--dropdown-open",e),!e)return this.dropdown.replaceChildren(),void this.detachDropdownPortal();this.dropdown.replaceChildren();const r=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=i.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(r&&this.hasAttribute("search-results")){const e=document.createElement("div");if(e.className="designbase-wc-search-bar__results",d.length>0){const t=document.createElement("ul");t.className="designbase-wc-search-bar__results-list",d.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 s=document.createElement("div");s.className="designbase-wc-search-bar__results-empty",s.textContent=t("검색 결과가 없습니다."),e.append(s)}return this.dropdown.append(e),void this.attachDropdownPortal()}if(this.hasAttribute("enable-recent-searches")&&!r&&this.recentSearches.length>0){const e=document.createElement("div");e.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=t("최근 검색어");const o=document.createElement("button");o.type="button",o.className="designbase-wc-search-bar__clear-all-button",o.setAttribute("aria-label",t("모든 최근 검색어 삭제")),o.textContent=t("전체 삭제"),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 t=document.createElement("div");t.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",s("{0} 삭제",[e])),i.append(n("close",a("s"))),i.addEventListener("mousedown",t=>{t.preventDefault(),this.recentSearches=this.recentSearches.filter(t=>t!==e),this.saveRecentSearches(),this.updateDropdown()}),t.append(r,i),c.append(t)}),e.append(r,c),this.dropdown.append(e)}if(c.length>0&&!r){const e=document.createElement("div");e.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=t("추천 검색어"),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)}),e.append(s,n),this.dropdown.append(e)}if(l&&!r&&(!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 e=this.getAttribute("size")||"m",s=this.hasAttribute("disabled"),a=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--${r.includes(e)?e:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",s&&"designbase-wc-search-bar--disabled",a&&"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(n("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=a,b.setAttribute("aria-label",t("검색어 입력")),this.input=b,o){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=h||s||a,this.shortcutBadge=t,l.append(u,b,t)}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",t("검색어 지우기")),p.hidden=!h||s||a,p.append(n("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};
@@ -1 +1 @@
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};
1
+ import{setHostClasses as e}from"../core/host-class.js";import{labelFrom as t,t as s,dbFormat as i}from"../core/i18n.js";import{getDbComponentIconSize as r,createDbIcon as a}from"./db-icons.js";import"./db-checkbox.js";import{dbUid as n}from"../core/uid.js";import{SELECT_SIZES as l,SELECT_POSITIONS as h}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as c}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 r(l.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 e=this.getAttribute("id")||n("db-select"),s=`${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",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",t(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=t(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=n("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")||s("select.placeholder");this.trigger.setAttribute("aria-label",t)}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const t=c(this.getAttribute("size"),l,"m"),s=c(this.getAttribute("position"),h,"bottom"),i="full"===this.getAttribute("dropdown-width")?"full":"auto",r=Number(this.getAttribute("max-height")||200),a=this.getAttribute("label")||"",n=this.getAttribute("helper-text")||"",o=this.getAttribute("error-message")||"",d=this.hasAttribute("error"),u=this.getAttribute("id")||"";e(this,["designbase-wc-select",`designbase-wc-select--${t}`,this.open&&"designbase-wc-select--open",d&&"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"]);const p=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",p.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--${i}`,`designbase-wc-select__dropdown--${s}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${r}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const b=`${u}-helper`,g=`${u}-error`;d&&o?(this.errorEl.id=g,this.errorEl.textContent=o,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",g),this.trigger.setAttribute("aria-invalid","true")):n?(this.helperEl.id=b,this.helperEl.textContent=n,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",b),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(),t=this.parseSelectedValues(),r=this.getAttribute("placeholder")||s("select.placeholder"),n=t.length>0,l=n&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===t.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=r,this.valueEl.appendChild(e)}else{const s=document.createElement("div");s.className="designbase-wc-select__tags",t.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",i("{0} 제거",[n?.label||r])),c.appendChild(a("close",12)),c.addEventListener("click",e=>{e.stopPropagation();const s=t.filter(e=>e!==r);this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s)}),l.append(h,c),s.appendChild(l)}),this.valueEl.appendChild(s)}else{const s=document.createElement("span");s.className="designbase-wc-select__single-value";const i=e.find(e=>e.value===t[0]);s.textContent=n?i?.label||t[0]:r,n||s.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(s)}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 e=this.getFilteredOptions(),s=this.parseSelectedValues(),i=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?t(this,"label-no-results","select.noResults"):t(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(e)}e.forEach((e,t)=>{const r=s.includes(e.value),a=t===this.focusedIndex,n=document.createElement("div");if(n.className=["designbase-wc-select__option",r&&"designbase-wc-select__option--selected",a&&"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(r)),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"),r&&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};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";import{labelFrom as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TABS_ORIENTATIONS as i,TABS_SIZES as a,TABS_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.tabButtons=[],this.inactivePanels=document.createDocumentFragment(),this.isRendering=!1,this.handleResize=()=>{this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.isRendering||(this.handleListScroll(),this.updateIndicator(!1))})},this.handleListScroll=()=>{if(!this.list)return;const t=this.list.scrollWidth>this.list.clientWidth,e=this.list.scrollLeft+this.list.clientWidth>=this.list.scrollWidth-5;this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",t&&!e&&"horizontal"===this.orientation)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width"]}get labels(){const t=this.tabItems.map(t=>t.label);return t.length?t:(this.getAttribute("labels")||"").split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?t.join(","):t)}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}set tabItems(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get activeIndex(){const t=this.getAttribute("selected-id");if(t){const e=this.tabItems.findIndex((e,s)=>(e.id||String(s))===t);if(e>=0)return e}return Number(this.getAttribute("active-index")||0)}set activeIndex(t){this.setAttribute("active-index",String(t))}get orientation(){return s(this.getAttribute("orientation"),i,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return s(this.getAttribute("size"),a,"m")}set size(t){this.setAttribute("size",t)}get variant(){return s(this.getAttribute("variant"),n,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",Boolean(t))}connectedCallback(){this.render(),this.list?.addEventListener("scroll",this.handleListScroll,{passive:!0}),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this),this.childObserver=new MutationObserver(t=>{if(this.isRendering)return;t.some(t=>Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&(t.hasAttribute("slot")||void 0!==t.dataset.panelIndex)))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.list?.removeEventListener("scroll",this.handleListScroll),window.removeEventListener("resize",this.handleResize),this.resizeObserver?.disconnect(),this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.childObserver?.disconnect()}attributeChangedCallback(){this.isConnected&&this.render()}collectPanelContent(){const t=new Map,register=(e,s)=>{if(!(e instanceof HTMLElement)||"SLOT"===e.tagName)return;t.has(s)||t.set(s,[]);const i=t.get(s);i.includes(e)||i.push(e)};return Array.from(this.children).forEach(t=>{const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/);if(e)return void register(t,Number(e[1]));const s=t.dataset.panelIndex;void 0!==s&&register(t,Number(s))}),this.panel?.querySelectorAll(":scope > .designbase-wc-tabs__panel-inner > [data-panel-index]").forEach(t=>{t instanceof HTMLElement&&register(t,Number(t.dataset.panelIndex))}),Array.from(this.inactivePanels.children).forEach(t=>{t instanceof HTMLElement&&void 0!==t.dataset.panelIndex&&register(t,Number(t.dataset.panelIndex))}),t}render(){this.isRendering=!0;const s=this.collectPanelContent(),i=this.labels,a=this.tabItems,n=Math.min(Math.max(this.activeIndex,0),Math.max(i.length-1,0)),r=this.size,l=this.orientation,o=this.variant,d="default"===o;this.className=["designbase-wc-tabs",`designbase-wc-tabs--${l}`,`designbase-wc-tabs--${r}`,`designbase-wc-tabs--${o}`,this.fullWidth&&"designbase-wc-tabs--full-width"].filter(Boolean).join(" "),this.querySelectorAll(":scope > .designbase-wc-tabs__list, :scope > .designbase-wc-tabs__panel").forEach(t=>t.remove()),this.list=document.createElement("div"),this.list.className=["designbase-wc-tabs__list",`designbase-wc-tabs__list--${l}`,this.fullWidth&&"designbase-wc-tabs__list--full-width"].filter(Boolean).join(" "),this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",l),this.list.setAttribute("aria-label",e(this,"label-tablist","tabs.label")),this.tabButtons=[],i.forEach((e,s)=>{const i=a[s],l=Boolean(i?.disabled),o=s===n,d=document.createElement("button");if(d.type="button",d.className=["designbase-wc-tabs__tab",o&&"designbase-wc-tabs__tab--selected",l&&"designbase-wc-tabs__tab--disabled"].filter(Boolean).join(" "),d.setAttribute("role","tab"),d.setAttribute("aria-selected",String(o)),d.setAttribute("aria-controls",`panel-${s}`),d.id=`tab-${s}`,d.tabIndex=o?0:-1,d.disabled=l,i?.icon){const e=document.createElement("span");e.className="designbase-wc-tabs__tab-icon";const s="s"===r?16:"l"===r?20:18;e.setAttribute("aria-hidden","true"),e.append(t(i.icon,s)),d.append(e)}const c=document.createElement("span");c.className="designbase-wc-tabs__tab-label",c.textContent=e,d.append(c),d.addEventListener("click",()=>this.select(s)),d.addEventListener("keydown",t=>this.handleKeyDown(t,s)),this.list?.append(d),this.tabButtons.push(d)}),d?(this.indicator=document.createElement("span"),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.list.append(this.indicator),requestAnimationFrame(()=>this.updateIndicator(!1))):this.indicator=void 0,this.panel=document.createElement("div"),this.panel.className="designbase-wc-tabs__panel",this.panel.setAttribute("role","tabpanel"),this.panel.id=`panel-${n}`,this.panel.setAttribute("aria-labelledby",`tab-${n}`),this.panel.tabIndex=0;const c=document.createElement("div");c.className="designbase-wc-tabs__panel-inner",s.forEach((t,e)=>{t.forEach(t=>{t.removeAttribute("slot"),t.dataset.panelIndex=String(e),e===n?c.append(t):this.inactivePanels.append(t)})}),this.panel.append(c),this.append(this.list,this.panel),requestAnimationFrame(()=>{this.handleListScroll(),d&&this.updateIndicator(!1)}),this.isRendering=!1}select(t){const e=this.labels,s=this.tabItems;if(!e[t]||s[t]?.disabled)return;this.activeIndex=t;const i=s[t]?.id||String(t);this.setAttribute("selected-id",i),this.dispatchEvent(new CustomEvent("db-change",{detail:{index:t,label:e[t],id:i},bubbles:!0,composed:!0})),this.render()}handleKeyDown(t,e){const s=this.labels,i=this.tabItems;let a=e;if("ArrowRight"===t.key||"ArrowDown"===t.key)a=(e+1)%s.length;else if("ArrowLeft"===t.key||"ArrowUp"===t.key)a=(e-1+s.length)%s.length;else if("Home"===t.key)a=0;else{if("End"!==t.key)return"Enter"===t.key||" "===t.key?(t.preventDefault(),void this.select(e)):void 0;a=s.length-1}t.preventDefault();let n=0;for(;i[a]?.disabled&&n<s.length;)a="ArrowLeft"===t.key||"ArrowUp"===t.key?(a-1+s.length)%s.length:(a+1)%s.length,n+=1;this.tabButtons[a]?.focus()}updateIndicator(t=!1){const e=this.list?.querySelector(".designbase-wc-tabs__tab--selected");if(!e||!this.indicator)return;const s="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--no-transition",!t),this.indicator.classList.add(s?"designbase-wc-tabs__indicator--vertical":"designbase-wc-tabs__indicator--horizontal"),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),s?(this.indicator.style.width="2px",this.indicator.style.height=`${e.offsetHeight}px`,this.indicator.style.transform=`translate3d(0, ${e.offsetTop}px, 0)`):(this.indicator.style.width=`${e.offsetWidth}px`,this.indicator.style.height="2px",this.indicator.style.transform=`translate3d(${e.offsetLeft}px, 0, 0)`)}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
1
+ import{createDbIcon as t}from"./db-icons.js";import{labelFrom as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TABS_ORIENTATIONS as i,TABS_SIZES as a,TABS_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.tabButtons=[],this.inactivePanels=document.createDocumentFragment(),this.isRendering=!1,this.handleResize=()=>{this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.isRendering||(this.handleListScroll(),this.updateIndicator(!1))})},this.handleListScroll=()=>{if(!this.list)return;const t=this.list.scrollWidth>this.list.clientWidth,e=this.list.scrollLeft+this.list.clientWidth>=this.list.scrollWidth-5;this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",t&&!e&&"horizontal"===this.orientation)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width"]}get labels(){const t=this.tabItems.map(t=>t.label);return t.length?t:(this.getAttribute("labels")||"").split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?t.join(","):t)}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}set tabItems(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get activeIndex(){const t=this.getAttribute("selected-id");if(t){const e=this.tabItems.findIndex((e,s)=>(e.id||String(s))===t);if(e>=0)return e}return Number(this.getAttribute("active-index")||0)}set activeIndex(t){this.setAttribute("active-index",String(t))}get orientation(){return s(this.getAttribute("orientation"),i,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return s(this.getAttribute("size"),a,"m")}set size(t){this.setAttribute("size",t)}get variant(){return s(this.getAttribute("variant"),n,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",Boolean(t))}connectedCallback(){this.render(),this.list?.addEventListener("scroll",this.handleListScroll,{passive:!0}),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this),this.childObserver=new MutationObserver(t=>{if(this.isRendering)return;t.some(t=>Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&(t.hasAttribute("slot")||void 0!==t.dataset.panelIndex)))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.list?.removeEventListener("scroll",this.handleListScroll),window.removeEventListener("resize",this.handleResize),this.resizeObserver?.disconnect(),this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.childObserver?.disconnect()}attributeChangedCallback(){this.isConnected&&this.render()}collectPanelContent(){const t=new Map,register=(e,s)=>{if(!(e instanceof HTMLElement)||"SLOT"===e.tagName)return;t.has(s)||t.set(s,[]);const i=t.get(s);i.includes(e)||i.push(e)};return Array.from(this.children).forEach(t=>{const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/);if(e)return void register(t,Number(e[1]));const s=t.dataset.panelIndex;void 0!==s&&register(t,Number(s))}),this.panel?.querySelectorAll(":scope > .designbase-wc-tabs__panel-inner > [data-panel-index]").forEach(t=>{t instanceof HTMLElement&&register(t,Number(t.dataset.panelIndex))}),Array.from(this.inactivePanels.children).forEach(t=>{t instanceof HTMLElement&&void 0!==t.dataset.panelIndex&&register(t,Number(t.dataset.panelIndex))}),t}render(){this.isRendering=!0;const s=this.collectPanelContent(),i=[...s.values()].some(t=>t.length>0),a=this.labels,n=this.tabItems,r=Math.min(Math.max(this.activeIndex,0),Math.max(a.length-1,0)),l=this.size,o=this.orientation,d=this.variant,h="default"===d;this.className=["designbase-wc-tabs",`designbase-wc-tabs--${o}`,`designbase-wc-tabs--${l}`,`designbase-wc-tabs--${d}`,this.fullWidth&&"designbase-wc-tabs--full-width",!i&&"designbase-wc-tabs--nav-only"].filter(Boolean).join(" "),this.querySelectorAll(":scope > .designbase-wc-tabs__list, :scope > .designbase-wc-tabs__panel").forEach(t=>t.remove()),this.list=document.createElement("div"),this.list.className=["designbase-wc-tabs__list",`designbase-wc-tabs__list--${o}`,this.fullWidth&&"designbase-wc-tabs__list--full-width"].filter(Boolean).join(" "),this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",o),this.list.setAttribute("aria-label",e(this,"label-tablist","tabs.label")),this.tabButtons=[],a.forEach((e,s)=>{const a=n[s],o=Boolean(a?.disabled),d=s===r,h=document.createElement("button");if(h.type="button",h.className=["designbase-wc-tabs__tab",d&&"designbase-wc-tabs__tab--selected",o&&"designbase-wc-tabs__tab--disabled"].filter(Boolean).join(" "),h.setAttribute("role","tab"),h.setAttribute("aria-selected",String(d)),i&&h.setAttribute("aria-controls",`panel-${s}`),h.id=`tab-${s}`,h.tabIndex=d?0:-1,h.disabled=o,a?.icon){const e=document.createElement("span");e.className="designbase-wc-tabs__tab-icon";const s="s"===l?16:"l"===l?20:18;e.setAttribute("aria-hidden","true"),e.append(t(a.icon,s)),h.append(e)}const c=document.createElement("span");c.className="designbase-wc-tabs__tab-label",c.textContent=e,h.append(c),h.addEventListener("click",()=>this.select(s)),h.addEventListener("keydown",t=>this.handleKeyDown(t,s)),this.list?.append(h),this.tabButtons.push(h)}),h?(this.indicator=document.createElement("span"),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.list.append(this.indicator),requestAnimationFrame(()=>this.updateIndicator(!1))):this.indicator=void 0,this.panel=document.createElement("div"),this.panel.className="designbase-wc-tabs__panel",this.panel.setAttribute("role","tabpanel"),this.panel.id=`panel-${r}`,this.panel.setAttribute("aria-labelledby",`tab-${r}`),this.panel.tabIndex=i?0:-1,this.panel.hidden=!i;const c=document.createElement("div");c.className="designbase-wc-tabs__panel-inner",s.forEach((t,e)=>{t.forEach(t=>{t.removeAttribute("slot"),t.dataset.panelIndex=String(e),e===r?c.append(t):this.inactivePanels.append(t)})}),this.panel.append(c),this.append(this.list,this.panel),requestAnimationFrame(()=>{this.handleListScroll(),h&&this.updateIndicator(!1)}),this.isRendering=!1}select(t){const e=this.labels,s=this.tabItems;if(!e[t]||s[t]?.disabled)return;this.activeIndex=t;const i=s[t]?.id||String(t);this.setAttribute("selected-id",i),this.dispatchEvent(new CustomEvent("db-change",{detail:{index:t,label:e[t],id:i},bubbles:!0,composed:!0})),this.render()}handleKeyDown(t,e){const s=this.labels,i=this.tabItems;let a=e;if("ArrowRight"===t.key||"ArrowDown"===t.key)a=(e+1)%s.length;else if("ArrowLeft"===t.key||"ArrowUp"===t.key)a=(e-1+s.length)%s.length;else if("Home"===t.key)a=0;else{if("End"!==t.key)return"Enter"===t.key||" "===t.key?(t.preventDefault(),void this.select(e)):void 0;a=s.length-1}t.preventDefault();let n=0;for(;i[a]?.disabled&&n<s.length;)a="ArrowLeft"===t.key||"ArrowUp"===t.key?(a-1+s.length)%s.length:(a+1)%s.length,n+=1;this.tabButtons[a]?.focus()}updateIndicator(t=!1){const e=this.list?.querySelector(".designbase-wc-tabs__tab--selected");if(!e||!this.indicator)return;const s="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--no-transition",!t),this.indicator.classList.add(s?"designbase-wc-tabs__indicator--vertical":"designbase-wc-tabs__indicator--horizontal"),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),s?(this.indicator.style.width="2px",this.indicator.style.height=`${e.offsetHeight}px`,this.indicator.style.transform=`translate3d(0, ${e.offsetTop}px, 0)`):(this.indicator.style.width=`${e.offsetWidth}px`,this.indicator.style.height="2px",this.indicator.style.transform=`translate3d(${e.offsetLeft}px, 0, 0)`)}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
@@ -1 +1 @@
1
- import{dbUid as t}from"../core/uid.js";import{TEXTAREA_SIZES as e}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTextarea extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.handleInput=t=>{t.stopPropagation(),this.field&&(this.getAttribute("value")!==this.field.value&&this.setAttribute("value",this.field.value),this.updateCharacterCount(),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:this.field.value,nativeEvent:t},bubbles:!0,composed:!0})))},this.handleChange=t=>{if(t.stopPropagation(),!this.field)return;const e=this.field.value;this.getAttribute("value")!==e&&this.setAttribute("value",e),this.updateCharacterCount(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,nativeEvent:t},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["label","placeholder","value","default-value","name","size","rows","max-length","show-character-count","character-count-position","disabled","readonly","required","error","error-message","helper-text","full-width","resizable"]}get value(){return this.field?.value??this.getAttribute("value")??""}set value(t){this.setAttribute("value",t),this.field&&(this.field.value=t,this.updateCharacterCount())}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}connectedCallback(){this.built||this.build(),this.syncState()}attributeChangedCallback(t){if(this.built){if("value"===t&&this.field){const t=this.getAttribute("value")||"";return this.field.value!==t&&(this.field.value=t),void this.updateCharacterCount()}this.syncState()}}focus(){this.field?.focus()}get showCharacterCount(){return this.hasAttribute("show-character-count")}get characterCountPosition(){return this.getAttribute("character-count-position")||"bottom"}build(){const e=this.getAttribute("id")||t("db-textarea");this.hasAttribute("id")||this.setAttribute("id",e),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-textarea__label",this.labelEl.htmlFor=`${e}-field`,this.countTop=document.createElement("div"),this.countTop.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--top",this.countTop.hidden=!0;const i=document.createElement("div");i.className="designbase-wc-textarea__wrapper",this.field=document.createElement("textarea"),this.field.id=`${e}-field`,this.field.className="designbase-wc-textarea__field",this.field.addEventListener("input",this.handleInput),this.field.addEventListener("change",this.handleChange),i.appendChild(this.field),this.footerEl=document.createElement("div"),this.footerEl.className="designbase-wc-textarea__footer",this.errorEl=document.createElement("div"),this.errorEl.className="designbase-wc-textarea__error-message",this.errorEl.setAttribute("role","alert"),this.helperEl=document.createElement("div"),this.helperEl.className="designbase-wc-textarea__helper-text",this.countBottom=document.createElement("div"),this.countBottom.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--bottom",this.countBottom.hidden=!0,this.footerEl.append(this.errorEl,this.helperEl,this.countBottom),this.append(this.labelEl,this.countTop,i,this.footerEl),this.built=!0}syncState(){if(!this.field)return;const t=e.includes(this.size)?this.size:"m",i=this.getAttribute("label")||"",s=this.getAttribute("helper-text")||"",a=this.getAttribute("error-message")||"",r=this.hasAttribute("error"),h=this.getAttribute("value")??this.getAttribute("default-value")??"";if(this.className=["designbase-wc-textarea",`designbase-wc-textarea--${t}`,r&&"designbase-wc-textarea--error",this.hasAttribute("disabled")&&"designbase-wc-textarea--disabled",this.hasAttribute("readonly")&&"designbase-wc-textarea--readonly",this.hasAttribute("full-width")&&"designbase-wc-textarea--full-width",this.hasAttribute("resizable")?"":"designbase-wc-textarea--not-resizable"].filter(Boolean).join(" "),this.labelEl){const t=this.hasAttribute("required")?'<span aria-hidden="true"> *</span>':"";this.labelEl.innerHTML=i?`${this.escape(i)}${t}`:"",this.labelEl.hidden=!i}this.field.placeholder=this.getAttribute("placeholder")||"",this.field.name=this.getAttribute("name")||"",this.field.value!==h&&(this.field.value=h),this.field.rows=Number(this.getAttribute("rows")||4),this.field.disabled=this.hasAttribute("disabled"),this.field.readOnly=this.hasAttribute("readonly"),this.field.required=this.hasAttribute("required"),this.field.setAttribute("aria-invalid",String(r));const l=this.getAttribute("max-length");l?this.field.maxLength=Number(l):this.field.removeAttribute("maxLength");const n=`${this.getAttribute("id")}-helper`,d=`${this.getAttribute("id")}-error`;r&&a?(this.errorEl.id=d,this.errorEl.textContent=a,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.field.setAttribute("aria-describedby",d)):s?(this.helperEl.id=n,this.helperEl.textContent=s,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.field.setAttribute("aria-describedby",n)):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.field.removeAttribute("aria-describedby")),this.updateCharacterCount()}updateCharacterCount(){if(!this.field||!this.countTop||!this.countBottom)return;const t=this.field.value.length,e=this.getAttribute("max-length"),i=Boolean(e&&t>Number(e)),s=`${t}${e?` / ${e}`:""}`,renderCount=t=>{let e=t.querySelector(".designbase-wc-textarea__character-count-text");e||(e=document.createElement("span"),t.replaceChildren(e)),e.className="designbase-wc-textarea__character-count-text",e.classList.toggle("designbase-wc-textarea__character-count-text--error",i),e.textContent=s};this.showCharacterCount&&"top"===this.characterCountPosition?(renderCount(this.countTop),this.countTop.hidden=!1,this.countBottom.hidden=!0):this.showCharacterCount?(renderCount(this.countBottom),this.countBottom.hidden=!1,this.countTop.hidden=!0):(this.countTop.hidden=!0,this.countBottom.hidden=!0)}escape(t){return t.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t]||t))}}customElements.get("db-textarea")||customElements.define("db-textarea",DbTextarea);export{DbTextarea};
1
+ import{dbUid as t}from"../core/uid.js";import{TEXTAREA_SIZES as e}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTextarea extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.handleInput=t=>{t.stopPropagation(),this.field&&(this.getAttribute("value")!==this.field.value&&this.setAttribute("value",this.field.value),this.updateCharacterCount(),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:this.field.value,nativeEvent:t},bubbles:!0,composed:!0})))},this.handleChange=t=>{if(t.stopPropagation(),!this.field)return;const e=this.field.value;this.getAttribute("value")!==e&&this.setAttribute("value",e),this.updateCharacterCount(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,nativeEvent:t},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["label","placeholder","value","default-value","name","size","rows","max-length","show-character-count","character-count-position","disabled","readonly","required","error","error-message","helper-text","full-width","resizable"]}get value(){return this.field?.value??this.getAttribute("value")??""}set value(t){this.setAttribute("value",t),this.field&&(this.field.value=t,this.updateCharacterCount())}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}connectedCallback(){this.built||this.build(),this.syncState()}attributeChangedCallback(t){if(this.built){if("value"===t&&this.field){const t=this.getAttribute("value")||"";return this.field.value!==t&&(this.field.value=t),void this.updateCharacterCount()}this.syncState()}}focus(){this.field?.focus()}get showCharacterCount(){return this.hasAttribute("show-character-count")}get characterCountPosition(){return this.getAttribute("character-count-position")||"bottom"}build(){const e=this.getAttribute("id")||t("db-textarea");this.hasAttribute("id")||this.setAttribute("id",e),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-textarea__label",this.labelEl.htmlFor=`${e}-field`,this.countTop=document.createElement("div"),this.countTop.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--top",this.countTop.hidden=!0;const i=document.createElement("div");i.className="designbase-wc-textarea__wrapper",this.field=document.createElement("textarea"),this.field.id=`${e}-field`,this.field.className="designbase-wc-textarea__field",this.field.addEventListener("input",this.handleInput),this.field.addEventListener("change",this.handleChange),i.appendChild(this.field),this.footerEl=document.createElement("div"),this.footerEl.className="designbase-wc-textarea__footer",this.errorEl=document.createElement("div"),this.errorEl.className="designbase-wc-textarea__error-message",this.errorEl.setAttribute("role","alert"),this.helperEl=document.createElement("div"),this.helperEl.className="designbase-wc-textarea__helper-text",this.countBottom=document.createElement("div"),this.countBottom.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--bottom",this.countBottom.hidden=!0,this.footerEl.append(this.errorEl,this.helperEl,this.countBottom),this.append(this.labelEl,this.countTop,i,this.footerEl),this.built=!0}syncState(){if(!this.field)return;const t=e.includes(this.size)?this.size:"m",i=this.getAttribute("label")||"",s=this.getAttribute("helper-text")||"",a=this.getAttribute("error-message")||"",r=this.hasAttribute("error"),h=this.getAttribute("value")??this.getAttribute("default-value")??"";if(this.className=["designbase-wc-textarea",`designbase-wc-textarea--${t}`,r&&"designbase-wc-textarea--error",this.hasAttribute("disabled")&&"designbase-wc-textarea--disabled",this.hasAttribute("readonly")&&"designbase-wc-textarea--readonly",this.hasAttribute("full-width")&&"designbase-wc-textarea--full-width",this.hasAttribute("rows")&&"designbase-wc-textarea--rows",this.hasAttribute("resizable")?"":"designbase-wc-textarea--not-resizable"].filter(Boolean).join(" "),this.labelEl){const t=this.hasAttribute("required")?'<span aria-hidden="true"> *</span>':"";this.labelEl.innerHTML=i?`${this.escape(i)}${t}`:"",this.labelEl.hidden=!i}this.field.placeholder=this.getAttribute("placeholder")||"",this.field.name=this.getAttribute("name")||"",this.field.value!==h&&(this.field.value=h),this.field.rows=Number(this.getAttribute("rows")||4),this.field.disabled=this.hasAttribute("disabled"),this.field.readOnly=this.hasAttribute("readonly"),this.field.required=this.hasAttribute("required"),this.field.setAttribute("aria-invalid",String(r));const l=this.getAttribute("max-length");l?this.field.maxLength=Number(l):this.field.removeAttribute("maxLength");const n=`${this.getAttribute("id")}-helper`,d=`${this.getAttribute("id")}-error`;r&&a?(this.errorEl.id=d,this.errorEl.textContent=a,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.field.setAttribute("aria-describedby",d)):s?(this.helperEl.id=n,this.helperEl.textContent=s,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.field.setAttribute("aria-describedby",n)):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.field.removeAttribute("aria-describedby")),this.updateCharacterCount()}updateCharacterCount(){if(!this.field||!this.countTop||!this.countBottom)return;const t=this.field.value.length,e=this.getAttribute("max-length"),i=Boolean(e&&t>Number(e)),s=`${t}${e?` / ${e}`:""}`,renderCount=t=>{let e=t.querySelector(".designbase-wc-textarea__character-count-text");e||(e=document.createElement("span"),t.replaceChildren(e)),e.className="designbase-wc-textarea__character-count-text",e.classList.toggle("designbase-wc-textarea__character-count-text--error",i),e.textContent=s};this.showCharacterCount&&"top"===this.characterCountPosition?(renderCount(this.countTop),this.countTop.hidden=!1,this.countBottom.hidden=!0):this.showCharacterCount?(renderCount(this.countBottom),this.countBottom.hidden=!1,this.countTop.hidden=!0):(this.countTop.hidden=!0,this.countBottom.hidden=!0),this.footerEl&&(this.footerEl.hidden=Boolean(this.errorEl?.hidden&&this.helperEl?.hidden&&this.countBottom.hidden))}escape(t){return t.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t]||t))}}customElements.get("db-textarea")||customElements.define("db-textarea",DbTextarea);export{DbTextarea};
@@ -1 +1 @@
1
- import{dbText as t}from"../core/i18n.js";import{createDbIcon as e,getDbComponentIconSize as i}from"./db-icons.js";import"./db-button.js";import{TIME_PICKER_FORMATS as s,TIME_PICKER_SIZES as n,TIME_PICKER_DROPDOWN_POSITIONS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as r}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";const h="designbase-wc-time-picker";class DbTimePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.hours=12,this.minutes=0,this.seconds=0,this.period="PM",this.inputText="",this.tempHours=12,this.tempMinutes=0,this.tempSeconds=0,this.tempPeriod="PM",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.boundViewportChange=()=>this.handleViewportChange(),this.viewportChangeFrame=null,this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["value","default-value","type","format","minute-step","size","disabled","readonly","label","full-width","error","dropdown-position","open"]}connectedCallback(){this.built||this.build(),this.parseTimeString(this.getAttribute("value")??this.getAttribute("default-value")??"12:00"),this.syncInputText(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown),window.addEventListener("resize",this.boundViewportChange),window.addEventListener("scroll",this.boundViewportChange,{capture:!0,passive:!0})}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown),window.removeEventListener("resize",this.boundViewportChange),window.removeEventListener("scroll",this.boundViewportChange,{capture:!0}),null!==this.viewportChangeFrame&&cancelAnimationFrame(this.viewportChangeFrame),this.viewportChangeFrame=null,this.dropdownEl?.remove()}attributeChangedCallback(t){if(this.built){if("value"===t){const t=this.getAttribute("value");t&&(this.parseTimeString(t),this.syncInputText())}if("open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get format(){const t=this.getAttribute("format")||"24h";return s.includes(t)?t:"24h"}set format(t){this.setAttribute("format",t)}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get is12h(){return"12h"===this.format||"12h-with-seconds"===this.format}get showSeconds(){return"12h-with-seconds"===this.format||"24h-with-seconds"===this.format}get minuteStep(){const t=Number(this.getAttribute("minute-step")||"1");return Number.isFinite(t)&&t>0?t:1}get normalizedSize(){return r(this.getAttribute("size"),n,"m")}get dropdownPosition(){return r(this.getAttribute("dropdown-position"),o,"auto")}get itemHeight(){return"s"===this.normalizedSize?32:"l"===this.normalizedSize?40:28}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${h}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${h}__trigger`;const e=document.createElement("button");e.type="button",e.className=`${h}__icon-display`,e.setAttribute("aria-label",t("시간 선택 열기")),e.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${h}__input`,this.inputEl.setAttribute("aria-label",t("시간 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${h}__toggle`,i.setAttribute("aria-label",t("시간 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(e,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${h}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false")}pad2(t){return String(t).padStart(2,"0")}to24Hour(t,e){return"AM"===e?12===t?0:t:12===t?12:t+12}formatTimeString(t,e,i,s){const n="AM"===(s||this.period)?"오전":"오후";return this.is12h?`${n} ${this.pad2(t)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`:`${this.pad2(t)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`}toValue24(t,e,i,s){const n=this.is12h?this.to24Hour(t,s||this.period):t;return`${this.pad2(n)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`}parseTimeString(t){const e=t.trim();if(this.is12h){const t=this.showSeconds?/^(오전|오후|AM|PM)?\s*(0?[1-9]|1[0-2]):([0-5]\d):([0-5]\d)\s*(AM|PM|오전|오후)?$/i:/^(오전|오후|AM|PM)?\s*(0?[1-9]|1[0-2]):([0-5]\d)\s*(AM|PM|오전|오후)?$/i,i=e.match(t);if(i){const t=i[1],e=this.showSeconds?i[5]:i[4],s=(t||e||"AM").toUpperCase();return this.hours=parseInt(i[2],10),this.minutes=parseInt(i[3],10),this.seconds=this.showSeconds?parseInt(i[4],10):0,void(this.period="오후"===s||"PM"===s?"PM":"AM")}}else{const t=this.showSeconds?/^([01]?\d|2[0-3]):([0-5]\d):([0-5]\d)$/:/^([01]?\d|2[0-3]):([0-5]\d)$/,i=e.match(t);i&&(this.hours=parseInt(i[1],10),this.minutes=parseInt(i[2],10),this.seconds=this.showSeconds?parseInt(i[3],10):0)}}syncInputText(){this.inputText=this.formatTimeString(this.hours,this.minutes,this.seconds),this.inputEl&&(this.inputEl.value=this.inputText)}emitChange(t){this.setAttribute("value",t),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t},bubbles:!0,composed:!0}))}handleTimeChange(t,e,i=this.seconds,s){this.hours=t,this.minutes=e,this.seconds=i,s&&(this.period=s);const n=this.formatTimeString(t,e,i,s);this.inputText=n,this.inputEl&&(this.inputEl.value=n),this.emitChange(this.toValue24(t,e,i,s))}handleInputBlur(){if(!this.inputEl)return;const t=this.inputText;this.parseTimeString(this.inputEl.value);this.formatTimeString(this.hours,this.minutes,this.seconds)!==t||this.inputEl.value.trim()?this.handleTimeChange(this.hours,this.minutes,this.seconds,this.period):this.syncInputText()}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,"modal"===this.type&&(this.tempHours=this.hours,this.tempMinutes=this.minutes,this.tempSeconds=this.seconds,this.tempPeriod=this.period),this.render())}closePicker(){this.isOpen=!1,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){if(!this.isOpen)return;const e=t.target;this.contains(e)||this.dropdownEl?.contains(e)||this.closePicker()}handleViewportChange(){this.isOpen&&"dropdown"===this.type&&null===this.viewportChangeFrame&&(this.viewportChangeFrame=requestAnimationFrame(()=>{this.viewportChangeFrame=null,this.isOpen&&"dropdown"===this.type&&this.positionDropdown()}))}positionDropdown(){if(!this.isOpen||"dropdown"!==this.type||!this.triggerEl||!this.dropdownEl||this.dropdownEl.hidden)return;const t=this.dropdownEl,e=this.triggerEl.getBoundingClientRect();t.style.width="";const i=t.getBoundingClientRect(),s=Math.max(0,window.innerWidth-16),n=Math.min(i.width,s);t.style.width=`${Math.round(n)}px`;const o=this.dropdownPosition,r=e.bottom+4+i.height<=window.innerHeight-8,h=e.top-4-i.height>=8,d="auto"===o?r||!h?"bottom":"top":o.startsWith("top")?"top":"bottom",a="auto"===o?e.left+n>window.innerWidth-8?"end":"start":o.endsWith("end")?"end":"start",l="end"===a?e.right-n:e.left,u=Math.max(8,Math.min(l,window.innerWidth-n-8)),p="top"===d?e.top-i.height-4:e.bottom+4,c=Math.max(8,Math.min(p,window.innerHeight-i.height-8));t.style.left=`${Math.round(u)}px`,t.style.top=`${Math.round(c)}px`,t.dataset.placement=`${d}-${a}`}createWheel(t){const{label:e,items:i,value:s,onChange:n,formatter:o}=t,r=document.createElement("div");r.className=`${h}__wheel-container`;const d=document.createElement("div");d.className=`${h}__wheel-label`,d.textContent=e,r.appendChild(d);const a=document.createElement("div");a.className=`${h}__wheel-viewport`;const l=document.createElement("div");l.className=`${h}__wheel`,l.setAttribute("role","listbox"),l.setAttribute("aria-label",e);let u=null,p=!1,c=!1,m=0,b=0;const indexOfValue=t=>i.findIndex(e=>e===t),scrollToIndex=(t,e=!0)=>{const i=t*this.itemHeight;p=!0,l.scrollTo({top:i,behavior:e?"smooth":"auto"}),window.setTimeout(()=>{p=!1},150)},fmt=t=>o?o(t):"number"==typeof t?this.pad2(t):String(t);i.forEach(t=>{const e=document.createElement("div");e.className=[`${h}__wheel-item`,t===s&&`${h}__wheel-item--selected`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(t===s)),e.textContent=fmt(t),e.addEventListener("click",()=>{const e=indexOfValue(t);scrollToIndex(e,!0),t!==s&&n(t)}),l.appendChild(e)});const handleScroll=()=>{p||(u&&window.clearTimeout(u),u=window.setTimeout(()=>{const t=l.scrollTop,e=Math.round(t/this.itemHeight),o=Math.max(0,Math.min(i.length-1,e)),r=i[o];scrollToIndex(o,!0),r!==s&&n(r)},120))};l.addEventListener("scroll",handleScroll,{passive:!0}),l.addEventListener("pointerdown",t=>{c=!0,m=t.clientY,b=l.scrollTop,l.setPointerCapture(t.pointerId),l.style.cursor="grabbing"}),l.addEventListener("pointermove",t=>{c&&(l.scrollTop=b-(t.clientY-m))});const endDrag=t=>{c&&(c=!1,l.releasePointerCapture(t.pointerId),l.style.cursor="grab",handleScroll())};l.addEventListener("pointerup",endDrag),l.addEventListener("pointercancel",endDrag);const w=indexOfValue(s);w>=0&&requestAnimationFrame(()=>scrollToIndex(w,!1));const g=document.createElement("div");g.className=`${h}__wheel-center-indicator`,g.setAttribute("aria-hidden","true");const E=document.createElement("div");E.className=`${h}__wheel-fade wheel-fade--top`,E.setAttribute("aria-hidden","true");const v=document.createElement("div");return v.className=`${h}__wheel-fade wheel-fade--bottom`,v.setAttribute("aria-hidden","true"),a.append(l,g,E,v),r.appendChild(a),r}renderSelector(i=!1){const s=document.createElement("div");s.className=`${h}__selector`;const n=document.createElement("div");n.className=`${h}__picker-wheels`;const o=this.is12h?Array.from({length:12},(t,e)=>e+1):Array.from({length:24},(t,e)=>e),r=Array.from({length:Math.floor(60/this.minuteStep)},(t,e)=>e*this.minuteStep),d=Array.from({length:60},(t,e)=>e),a=i?this.tempHours:this.hours,l=i?this.tempMinutes:this.minutes,u=i?this.tempSeconds:this.seconds,p=i?this.tempPeriod:this.period,onChange=(t,e,s,n)=>{if(i)return this.tempHours=t,this.tempMinutes=e,this.tempSeconds=s,void(this.tempPeriod=n);this.handleTimeChange(t,e,s,n)};if(n.appendChild(this.createWheel({label:t("시간"),items:o,value:a,onChange:t=>onChange(t,l,u,p)})),n.appendChild(this.createWheel({label:t("분"),items:r,value:r.includes(l)?l:r[0],onChange:t=>onChange(a,t,u,p)})),this.showSeconds&&n.appendChild(this.createWheel({label:t("초"),items:d,value:u,onChange:t=>onChange(a,l,t,p)})),this.is12h&&n.appendChild(this.createWheel({label:t("오전/오후"),items:["AM","PM"],value:p,onChange:t=>onChange(a,l,u,t),formatter:t=>"AM"===t?"오전":"오후"})),s.appendChild(n),i)return s;const c=document.createElement("div");c.className=`${h}__dropdown-actions`;const m=document.createElement("div");m.className=`${h}__preview`,m.setAttribute("aria-live","polite"),m.appendChild(e("clock",16));const b=document.createElement("div");b.className=`${h}__preview-time`,b.textContent=this.formatTimeString(a,l,u,p),m.appendChild(b);const w=document.createElement("db-button");return w.setAttribute("variant","primary"),w.setAttribute("size","m"),w.textContent=t("선택"),w.addEventListener("click",()=>{this.handleTimeChange(a,l,u,p),this.closePicker()}),c.append(m,w),s.appendChild(c),s}render(){const s=this.normalizedSize,n=this.dropdownPosition,o=i(s);if(this.className=[h,`${h}--${s}`,this.hasAttribute("full-width")&&`${h}--full-width`,this.disabled&&`${h}--disabled`,this.readonly&&`${h}--readonly`,this.isOpen&&`${h}--open`,this.hasAttribute("error")&&`${h}--error`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.dropdownEl?.parentElement===document.body&&this.dropdownEl.remove(),this.replaceChildren(),!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const r=this.getAttribute("label")||"";this.labelEl.textContent=r,this.labelEl.hidden=!r,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.is12h?this.showSeconds?"12:00:00 PM":"12:00 PM":this.showSeconds?"12:00:00":"12:00",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${h}__icon-display`);d&&(d.innerHTML="",d.appendChild(e("clock",o)),d.disabled=this.disabled);const a=this.triggerEl.querySelector(`.${h}__toggle`);if(a&&(a.innerHTML="",a.appendChild(e("chevron-down",o)),a.disabled=this.disabled),this.dropdownEl.className=[`${h}__dropdown`,`${h}__dropdown--${s}`,`${h}__dropdown--${n}`].filter(Boolean).join(" "),this.dropdownEl.setAttribute("aria-label",t("시간 선택")),this.dropdownEl.hidden=!this.isOpen,this.isOpen&&"dropdown"===this.type&&(this.dropdownEl.replaceChildren(this.renderSelector(!1)),document.body.appendChild(this.dropdownEl),this.dropdownEl.hidden=!1,this.positionDropdown(),requestAnimationFrame(()=>this.positionDropdown())),this.append(this.labelEl,this.triggerEl),this.isOpen&&"modal"===this.type){const e=document.createElement("db-modal");e.setAttribute("open","true"),e.setAttribute("title",t("시간 선택")),e.setAttribute("size","s"),e.addEventListener("db-close",()=>this.closePicker());const i=this.renderSelector(!0),s=document.createElement("div");s.className=`${h}__modal-footer`;const n=document.createElement("db-button");n.setAttribute("variant","secondary"),n.setAttribute("size","m"),n.textContent=t("취소"),n.addEventListener("click",()=>this.closePicker());const o=document.createElement("db-button");o.setAttribute("variant","primary"),o.setAttribute("size","m"),o.textContent=t("적용"),o.addEventListener("click",()=>{this.handleTimeChange(this.tempHours,this.tempMinutes,this.tempSeconds,this.tempPeriod),this.closePicker()}),s.append(n,o),e.append(i,s),this.appendChild(e)}}}customElements.get("db-time-picker")||customElements.define("db-time-picker",DbTimePicker);export{DbTimePicker};
1
+ import{inheritThemeScope as t}from"../core/theme-scope.js";import{dbText as e}from"../core/i18n.js";import{createDbIcon as i,getDbComponentIconSize as s}from"./db-icons.js";import"./db-button.js";import{TIME_PICKER_FORMATS as n,TIME_PICKER_SIZES as o,TIME_PICKER_DROPDOWN_POSITIONS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as h}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";const d="designbase-wc-time-picker";class DbTimePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.hours=12,this.minutes=0,this.seconds=0,this.period="PM",this.inputText="",this.tempHours=12,this.tempMinutes=0,this.tempSeconds=0,this.tempPeriod="PM",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.boundViewportChange=()=>this.handleViewportChange(),this.viewportChangeFrame=null,this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["value","default-value","type","format","minute-step","size","disabled","readonly","label","full-width","error","dropdown-position","open"]}connectedCallback(){this.built||this.build(),this.parseTimeString(this.getAttribute("value")??this.getAttribute("default-value")??"12:00"),this.syncInputText(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown),window.addEventListener("resize",this.boundViewportChange),window.addEventListener("scroll",this.boundViewportChange,{capture:!0,passive:!0})}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown),window.removeEventListener("resize",this.boundViewportChange),window.removeEventListener("scroll",this.boundViewportChange,{capture:!0}),null!==this.viewportChangeFrame&&cancelAnimationFrame(this.viewportChangeFrame),this.viewportChangeFrame=null,this.dropdownEl?.remove()}attributeChangedCallback(t){if(this.built){if("value"===t){const t=this.getAttribute("value");t&&(this.parseTimeString(t),this.syncInputText())}if("open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get format(){const t=this.getAttribute("format")||"24h";return n.includes(t)?t:"24h"}set format(t){this.setAttribute("format",t)}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get is12h(){return"12h"===this.format||"12h-with-seconds"===this.format}get showSeconds(){return"12h-with-seconds"===this.format||"24h-with-seconds"===this.format}get minuteStep(){const t=Number(this.getAttribute("minute-step")||"1");return Number.isFinite(t)&&t>0?t:1}get normalizedSize(){return h(this.getAttribute("size"),o,"m")}get dropdownPosition(){return h(this.getAttribute("dropdown-position"),r,"auto")}get itemHeight(){return"s"===this.normalizedSize?32:"l"===this.normalizedSize?40:28}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${d}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${d}__trigger`;const t=document.createElement("button");t.type="button",t.className=`${d}__icon-display`,t.setAttribute("aria-label",e("시간 선택 열기")),t.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${d}__input`,this.inputEl.setAttribute("aria-label",e("시간 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${d}__toggle`,i.setAttribute("aria-label",e("시간 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(t,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${d}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false")}pad2(t){return String(t).padStart(2,"0")}to24Hour(t,e){return"AM"===e?12===t?0:t:12===t?12:t+12}formatTimeString(t,e,i,s){const n="AM"===(s||this.period)?"오전":"오후";return this.is12h?`${n} ${this.pad2(t)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`:`${this.pad2(t)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`}toValue24(t,e,i,s){const n=this.is12h?this.to24Hour(t,s||this.period):t;return`${this.pad2(n)}:${this.pad2(e)}${this.showSeconds?`:${this.pad2(i)}`:""}`}parseTimeString(t){const e=t.trim();if(this.is12h){const t=this.showSeconds?/^(오전|오후|AM|PM)?\s*(0?[1-9]|1[0-2]):([0-5]\d):([0-5]\d)\s*(AM|PM|오전|오후)?$/i:/^(오전|오후|AM|PM)?\s*(0?[1-9]|1[0-2]):([0-5]\d)\s*(AM|PM|오전|오후)?$/i,i=e.match(t);if(i){const t=i[1],e=this.showSeconds?i[5]:i[4],s=(t||e||"AM").toUpperCase();return this.hours=parseInt(i[2],10),this.minutes=parseInt(i[3],10),this.seconds=this.showSeconds?parseInt(i[4],10):0,void(this.period="오후"===s||"PM"===s?"PM":"AM")}}else{const t=this.showSeconds?/^([01]?\d|2[0-3]):([0-5]\d):([0-5]\d)$/:/^([01]?\d|2[0-3]):([0-5]\d)$/,i=e.match(t);i&&(this.hours=parseInt(i[1],10),this.minutes=parseInt(i[2],10),this.seconds=this.showSeconds?parseInt(i[3],10):0)}}syncInputText(){this.inputText=this.formatTimeString(this.hours,this.minutes,this.seconds),this.inputEl&&(this.inputEl.value=this.inputText)}emitChange(t){this.setAttribute("value",t),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t},bubbles:!0,composed:!0}))}handleTimeChange(t,e,i=this.seconds,s){this.hours=t,this.minutes=e,this.seconds=i,s&&(this.period=s);const n=this.formatTimeString(t,e,i,s);this.inputText=n,this.inputEl&&(this.inputEl.value=n),this.emitChange(this.toValue24(t,e,i,s))}handleInputBlur(){if(!this.inputEl)return;const t=this.inputText;this.parseTimeString(this.inputEl.value);this.formatTimeString(this.hours,this.minutes,this.seconds)!==t||this.inputEl.value.trim()?this.handleTimeChange(this.hours,this.minutes,this.seconds,this.period):this.syncInputText()}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,"modal"===this.type&&(this.tempHours=this.hours,this.tempMinutes=this.minutes,this.tempSeconds=this.seconds,this.tempPeriod=this.period),this.render())}closePicker(){this.isOpen=!1,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){if(!this.isOpen)return;const e=t.target;this.contains(e)||this.dropdownEl?.contains(e)||this.closePicker()}handleViewportChange(){this.isOpen&&"dropdown"===this.type&&null===this.viewportChangeFrame&&(this.viewportChangeFrame=requestAnimationFrame(()=>{this.viewportChangeFrame=null,this.isOpen&&"dropdown"===this.type&&this.positionDropdown()}))}positionDropdown(){if(!this.isOpen||"dropdown"!==this.type||!this.triggerEl||!this.dropdownEl||this.dropdownEl.hidden)return;const t=this.dropdownEl,e=this.triggerEl.getBoundingClientRect();t.style.width="";const i=t.getBoundingClientRect(),s=Math.max(0,window.innerWidth-16),n=Math.min(i.width,s);t.style.width=`${Math.round(n)}px`;const o=this.dropdownPosition,r=e.bottom+4+i.height<=window.innerHeight-8,h=e.top-4-i.height>=8,d="auto"===o?r||!h?"bottom":"top":o.startsWith("top")?"top":"bottom",a="auto"===o?e.left+n>window.innerWidth-8?"end":"start":o.endsWith("end")?"end":"start",l="end"===a?e.right-n:e.left,u=Math.max(8,Math.min(l,window.innerWidth-n-8)),p="top"===d?e.top-i.height-4:e.bottom+4,c=Math.max(8,Math.min(p,window.innerHeight-i.height-8));t.style.left=`${Math.round(u)}px`,t.style.top=`${Math.round(c)}px`,t.dataset.placement=`${d}-${a}`}createWheel(t){const{label:e,items:i,value:s,onChange:n,formatter:o}=t,r=document.createElement("div");r.className=`${d}__wheel-container`;const h=document.createElement("div");h.className=`${d}__wheel-label`,h.textContent=e,r.appendChild(h);const a=document.createElement("div");a.className=`${d}__wheel-viewport`;const l=document.createElement("div");l.className=`${d}__wheel`,l.setAttribute("role","listbox"),l.setAttribute("aria-label",e);let u=null,p=!1,c=!1,m=0,b=0;const indexOfValue=t=>i.findIndex(e=>e===t),scrollToIndex=(t,e=!0)=>{const i=t*this.itemHeight;p=!0,l.scrollTo({top:i,behavior:e?"smooth":"auto"}),window.setTimeout(()=>{p=!1},150)},fmt=t=>o?o(t):"number"==typeof t?this.pad2(t):String(t);i.forEach(t=>{const e=document.createElement("div");e.className=[`${d}__wheel-item`,t===s&&`${d}__wheel-item--selected`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(t===s)),e.textContent=fmt(t),e.addEventListener("click",()=>{const e=indexOfValue(t);scrollToIndex(e,!0),t!==s&&n(t)}),l.appendChild(e)});const handleScroll=()=>{p||(u&&window.clearTimeout(u),u=window.setTimeout(()=>{const t=l.scrollTop,e=Math.round(t/this.itemHeight),o=Math.max(0,Math.min(i.length-1,e)),r=i[o];scrollToIndex(o,!0),r!==s&&n(r)},120))};l.addEventListener("scroll",handleScroll,{passive:!0}),l.addEventListener("pointerdown",t=>{c=!0,m=t.clientY,b=l.scrollTop,l.setPointerCapture(t.pointerId),l.style.cursor="grabbing"}),l.addEventListener("pointermove",t=>{c&&(l.scrollTop=b-(t.clientY-m))});const endDrag=t=>{c&&(c=!1,l.releasePointerCapture(t.pointerId),l.style.cursor="grab",handleScroll())};l.addEventListener("pointerup",endDrag),l.addEventListener("pointercancel",endDrag);const w=indexOfValue(s);w>=0&&requestAnimationFrame(()=>scrollToIndex(w,!1));const g=document.createElement("div");g.className=`${d}__wheel-center-indicator`,g.setAttribute("aria-hidden","true");const E=document.createElement("div");E.className=`${d}__wheel-fade wheel-fade--top`,E.setAttribute("aria-hidden","true");const v=document.createElement("div");return v.className=`${d}__wheel-fade wheel-fade--bottom`,v.setAttribute("aria-hidden","true"),a.append(l,g,E,v),r.appendChild(a),r}renderSelector(t=!1){const s=document.createElement("div");s.className=`${d}__selector`;const n=document.createElement("div");n.className=`${d}__picker-wheels`;const o=this.is12h?Array.from({length:12},(t,e)=>e+1):Array.from({length:24},(t,e)=>e),r=Array.from({length:Math.floor(60/this.minuteStep)},(t,e)=>e*this.minuteStep),h=Array.from({length:60},(t,e)=>e),a=t?this.tempHours:this.hours,l=t?this.tempMinutes:this.minutes,u=t?this.tempSeconds:this.seconds,p=t?this.tempPeriod:this.period,onChange=(e,i,s,n)=>{if(t)return this.tempHours=e,this.tempMinutes=i,this.tempSeconds=s,void(this.tempPeriod=n);this.handleTimeChange(e,i,s,n)};if(n.appendChild(this.createWheel({label:e("시간"),items:o,value:a,onChange:t=>onChange(t,l,u,p)})),n.appendChild(this.createWheel({label:e("분"),items:r,value:r.includes(l)?l:r[0],onChange:t=>onChange(a,t,u,p)})),this.showSeconds&&n.appendChild(this.createWheel({label:e("초"),items:h,value:u,onChange:t=>onChange(a,l,t,p)})),this.is12h&&n.appendChild(this.createWheel({label:e("오전/오후"),items:["AM","PM"],value:p,onChange:t=>onChange(a,l,u,t),formatter:t=>"AM"===t?"오전":"오후"})),s.appendChild(n),t)return s;const c=document.createElement("div");c.className=`${d}__dropdown-actions`;const m=document.createElement("div");m.className=`${d}__preview`,m.setAttribute("aria-live","polite"),m.appendChild(i("clock",16));const b=document.createElement("div");b.className=`${d}__preview-time`,b.textContent=this.formatTimeString(a,l,u,p),m.appendChild(b);const w=document.createElement("db-button");return w.setAttribute("variant","primary"),w.setAttribute("size","m"),w.textContent=e("선택"),w.addEventListener("click",()=>{this.handleTimeChange(a,l,u,p),this.closePicker()}),c.append(m,w),s.appendChild(c),s}render(){const n=this.normalizedSize,o=this.dropdownPosition,r=s(n);if(this.className=[d,`${d}--${n}`,this.hasAttribute("full-width")&&`${d}--full-width`,this.disabled&&`${d}--disabled`,this.readonly&&`${d}--readonly`,this.isOpen&&`${d}--open`,this.hasAttribute("error")&&`${d}--error`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.dropdownEl?.parentElement===document.body&&this.dropdownEl.remove(),this.replaceChildren(),!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const h=this.getAttribute("label")||"";this.labelEl.textContent=h,this.labelEl.hidden=!h,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.is12h?this.showSeconds?"12:00:00 PM":"12:00 PM":this.showSeconds?"12:00:00":"12:00",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const a=this.triggerEl.querySelector(`.${d}__icon-display`);a&&(a.innerHTML="",a.appendChild(i("clock",r)),a.disabled=this.disabled);const l=this.triggerEl.querySelector(`.${d}__toggle`);if(l&&(l.innerHTML="",l.appendChild(i("chevron-down",r)),l.disabled=this.disabled),this.dropdownEl.className=[`${d}__dropdown`,`${d}__dropdown--${n}`,`${d}__dropdown--${o}`].filter(Boolean).join(" "),this.dropdownEl.setAttribute("aria-label",e("시간 선택")),this.dropdownEl.hidden=!this.isOpen,this.isOpen&&"dropdown"===this.type&&(this.dropdownEl.replaceChildren(this.renderSelector(!1)),t(this,this.dropdownEl),document.body.appendChild(this.dropdownEl),this.dropdownEl.hidden=!1,this.positionDropdown(),requestAnimationFrame(()=>this.positionDropdown())),this.append(this.labelEl,this.triggerEl),this.isOpen&&"modal"===this.type){const t=document.createElement("db-modal");t.setAttribute("open","true"),t.setAttribute("title",e("시간 선택")),t.setAttribute("size","s"),t.addEventListener("db-close",()=>this.closePicker());const i=this.renderSelector(!0),s=document.createElement("div");s.className=`${d}__modal-footer`;const n=document.createElement("db-button");n.setAttribute("variant","secondary"),n.setAttribute("size","m"),n.textContent=e("취소"),n.addEventListener("click",()=>this.closePicker());const o=document.createElement("db-button");o.setAttribute("variant","primary"),o.setAttribute("size","m"),o.textContent=e("적용"),o.addEventListener("click",()=>{this.handleTimeChange(this.tempHours,this.tempMinutes,this.tempSeconds,this.tempPeriod),this.closePicker()}),s.append(n,o),t.append(i,s),this.appendChild(t)}}}customElements.get("db-time-picker")||customElements.define("db-time-picker",DbTimePicker);export{DbTimePicker};