@designbasekorea/ui-wc 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE-WORLD-MAP.md +10 -0
  3. package/README.md +83 -0
  4. package/dist/esm/components/db-achievement-list.d.ts +2 -0
  5. package/dist/esm/components/db-achievement-list.js +1 -1
  6. package/dist/esm/components/db-activity-heatmap.d.ts +1 -0
  7. package/dist/esm/components/db-activity-heatmap.js +1 -1
  8. package/dist/esm/components/db-ad-banner.d.ts +2 -0
  9. package/dist/esm/components/db-ad-banner.js +1 -1
  10. package/dist/esm/components/db-ai-chat-list.d.ts +5 -1
  11. package/dist/esm/components/db-ai-chat-list.js +1 -1
  12. package/dist/esm/components/db-ai-chat.d.ts +2 -0
  13. package/dist/esm/components/db-ai-chat.js +1 -1
  14. package/dist/esm/components/db-ai-file-tree.js +1 -1
  15. package/dist/esm/components/db-alert.d.ts +1 -0
  16. package/dist/esm/components/db-alert.js +1 -1
  17. package/dist/esm/components/db-audio-player.d.ts +2 -0
  18. package/dist/esm/components/db-audio-player.js +1 -1
  19. package/dist/esm/components/db-avatar.d.ts +1 -0
  20. package/dist/esm/components/db-avatar.js +1 -1
  21. package/dist/esm/components/db-banner.d.ts +2 -0
  22. package/dist/esm/components/db-banner.js +1 -1
  23. package/dist/esm/components/db-button.d.ts +7 -1
  24. package/dist/esm/components/db-button.js +1 -1
  25. package/dist/esm/components/db-calendar.d.ts +5 -0
  26. package/dist/esm/components/db-calendar.js +1 -1
  27. package/dist/esm/components/db-card.d.ts +1 -0
  28. package/dist/esm/components/db-card.js +1 -1
  29. package/dist/esm/components/db-chat-composer.d.ts +3 -0
  30. package/dist/esm/components/db-chat-composer.js +1 -1
  31. package/dist/esm/components/db-chat-message.d.ts +2 -0
  32. package/dist/esm/components/db-chat-message.js +1 -1
  33. package/dist/esm/components/db-chat-room.d.ts +1 -0
  34. package/dist/esm/components/db-chat-room.js +1 -1
  35. package/dist/esm/components/db-chat-typing.d.ts +2 -0
  36. package/dist/esm/components/db-chat-typing.js +1 -1
  37. package/dist/esm/components/db-chat-widget.d.ts +9 -0
  38. package/dist/esm/components/db-chat-widget.js +1 -1
  39. package/dist/esm/components/db-chip.d.ts +2 -0
  40. package/dist/esm/components/db-chip.js +1 -1
  41. package/dist/esm/components/db-code-block.d.ts +1 -0
  42. package/dist/esm/components/db-code-block.js +1 -1
  43. package/dist/esm/components/db-color-picker.d.ts +4 -0
  44. package/dist/esm/components/db-color-picker.js +1 -1
  45. package/dist/esm/components/db-color-swatch.d.ts +3 -0
  46. package/dist/esm/components/db-color-swatch.js +1 -1
  47. package/dist/esm/components/db-cookie-banner.d.ts +3 -0
  48. package/dist/esm/components/db-cookie-banner.js +1 -1
  49. package/dist/esm/components/db-countdown.d.ts +2 -1
  50. package/dist/esm/components/db-countdown.js +1 -1
  51. package/dist/esm/components/db-date-picker.d.ts +3 -0
  52. package/dist/esm/components/db-date-picker.js +1 -1
  53. package/dist/esm/components/db-dropdown.d.ts +1 -0
  54. package/dist/esm/components/db-dropdown.js +1 -1
  55. package/dist/esm/components/db-dropzone.d.ts +2 -0
  56. package/dist/esm/components/db-dropzone.js +1 -1
  57. package/dist/esm/components/db-email-verify.d.ts +1 -0
  58. package/dist/esm/components/db-email-verify.js +1 -1
  59. package/dist/esm/components/db-file-uploader.d.ts +2 -0
  60. package/dist/esm/components/db-file-uploader.js +1 -1
  61. package/dist/esm/components/db-form.d.ts +2 -0
  62. package/dist/esm/components/db-form.js +1 -1
  63. package/dist/esm/components/db-gantt.d.ts +2 -0
  64. package/dist/esm/components/db-gantt.js +1 -1
  65. package/dist/esm/components/db-image-list.d.ts +3 -0
  66. package/dist/esm/components/db-image-list.js +1 -1
  67. package/dist/esm/components/db-image.d.ts +1 -0
  68. package/dist/esm/components/db-image.js +1 -1
  69. package/dist/esm/components/db-input-group.d.ts +30 -0
  70. package/dist/esm/components/db-input-group.js +1 -0
  71. package/dist/esm/components/db-input.d.ts +1 -0
  72. package/dist/esm/components/db-input.js +1 -1
  73. package/dist/esm/components/db-kanban.d.ts +3 -0
  74. package/dist/esm/components/db-kanban.js +1 -1
  75. package/dist/esm/components/db-lightbox.d.ts +2 -0
  76. package/dist/esm/components/db-lightbox.js +1 -1
  77. package/dist/esm/components/db-list.d.ts +2 -0
  78. package/dist/esm/components/db-list.js +1 -1
  79. package/dist/esm/components/db-markdown-editor.d.ts +2 -0
  80. package/dist/esm/components/db-markdown-editor.js +1 -1
  81. package/dist/esm/components/db-menu-item.js +1 -1
  82. package/dist/esm/components/db-navbar.d.ts +3 -0
  83. package/dist/esm/components/db-navbar.js +1 -1
  84. package/dist/esm/components/db-node.d.ts +1 -0
  85. package/dist/esm/components/db-node.js +1 -1
  86. package/dist/esm/components/db-onboarding-modal.d.ts +2 -0
  87. package/dist/esm/components/db-onboarding-modal.js +1 -1
  88. package/dist/esm/components/db-otp-input.d.ts +4 -1
  89. package/dist/esm/components/db-otp-input.js +1 -1
  90. package/dist/esm/components/db-page-header.js +1 -1
  91. package/dist/esm/components/db-popover.d.ts +1 -0
  92. package/dist/esm/components/db-popover.js +1 -1
  93. package/dist/esm/components/db-progress-step.d.ts +2 -0
  94. package/dist/esm/components/db-progress-step.js +1 -1
  95. package/dist/esm/components/db-range-slider.d.ts +1 -0
  96. package/dist/esm/components/db-range-slider.js +1 -1
  97. package/dist/esm/components/db-rating.d.ts +1 -0
  98. package/dist/esm/components/db-rating.js +1 -1
  99. package/dist/esm/components/db-search-bar.d.ts +2 -0
  100. package/dist/esm/components/db-search-bar.js +1 -1
  101. package/dist/esm/components/db-section-logo-cloud.js +1 -1
  102. package/dist/esm/components/db-selection-bar.d.ts +42 -0
  103. package/dist/esm/components/db-selection-bar.js +1 -0
  104. package/dist/esm/components/db-share.d.ts +5 -0
  105. package/dist/esm/components/db-share.js +1 -1
  106. package/dist/esm/components/db-sidebar.d.ts +3 -0
  107. package/dist/esm/components/db-sidebar.js +1 -1
  108. package/dist/esm/components/db-signature.d.ts +2 -0
  109. package/dist/esm/components/db-signature.js +1 -1
  110. package/dist/esm/components/db-spinner.d.ts +2 -0
  111. package/dist/esm/components/db-spinner.js +1 -1
  112. package/dist/esm/components/db-stepper.d.ts +2 -0
  113. package/dist/esm/components/db-stepper.js +1 -1
  114. package/dist/esm/components/db-table.d.ts +2 -0
  115. package/dist/esm/components/db-table.js +1 -1
  116. package/dist/esm/components/db-tabs.d.ts +1 -0
  117. package/dist/esm/components/db-tabs.js +1 -1
  118. package/dist/esm/components/db-ticket.js +1 -1
  119. package/dist/esm/components/db-time-picker.d.ts +2 -0
  120. package/dist/esm/components/db-time-picker.js +1 -1
  121. package/dist/esm/components/db-timeline.d.ts +4 -0
  122. package/dist/esm/components/db-timeline.js +1 -1
  123. package/dist/esm/components/db-toast.d.ts +2 -0
  124. package/dist/esm/components/db-toast.js +1 -1
  125. package/dist/esm/components/db-tool-layout.d.ts +92 -0
  126. package/dist/esm/components/db-tool-layout.js +1 -0
  127. package/dist/esm/components/db-tool-panel.d.ts +50 -0
  128. package/dist/esm/components/db-tool-panel.js +1 -0
  129. package/dist/esm/components/db-top-banner.d.ts +2 -0
  130. package/dist/esm/components/db-top-banner.js +1 -1
  131. package/dist/esm/components/db-video-player.d.ts +3 -0
  132. package/dist/esm/components/db-video-player.js +1 -1
  133. package/dist/esm/components/db-world-map.d.ts +60 -0
  134. package/dist/esm/components/db-world-map.js +1 -0
  135. package/dist/esm/components/db-youtube-player.d.ts +2 -0
  136. package/dist/esm/components/db-youtube-player.js +1 -1
  137. package/dist/esm/components/db-zoom-control.d.ts +52 -0
  138. package/dist/esm/components/db-zoom-control.js +1 -0
  139. package/dist/esm/components/input-validation.js +1 -1
  140. package/dist/esm/components/paper-card.d.ts +2 -0
  141. package/dist/esm/components/paper-card.js +1 -1
  142. package/dist/esm/core/i18n-copy.js +1 -1
  143. package/dist/esm/core/i18n-en.js +1 -1
  144. package/dist/esm/core/i18n.d.ts +34 -1
  145. package/dist/esm/core/i18n.js +1 -1
  146. package/dist/esm/helpers/world-countries.js +1 -0
  147. package/dist/esm/helpers/world-land.js +1 -0
  148. package/dist/esm/index.d.ts +7 -1
  149. package/dist/esm/index.js +1 -1
  150. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  151. package/dist/index.cjs +1 -1
  152. package/dist/index.css +1 -1
  153. package/dist/index.d.ts +484 -6
  154. package/dist/index.esm.js +1 -1
  155. package/dist/react/index.cjs +1 -1
  156. package/dist/react/index.d.ts +871 -71
  157. package/dist/react/index.esm.js +1 -1
  158. package/package.json +4 -3
@@ -1 +1 @@
1
- import{rafThrottle as t}from"../core/dom.js";import{setHostClasses as e}from"../core/host-class.js";import{dbUid as i}from"../core/uid.js";import{sliderBounds as s,sliderPercent as r,sliderValueAt as a,sliderValue as n}from"../core/range-values.js";import{coerceToContract as l}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RANGE_SLIDER_SIZES as h,RANGE_SLIDER_VARIANTS as u,RANGE_SLIDER_VALUE_POSITIONS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c="designbase-wc-range-slider";class DbRangeSlider extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.headerEl=null,this.labelEl=null,this.valuesEl=null,this.containerEl=null,this.trackEl=null,this.fillEl=null,this.thumbEls=[],this.initialized=!1,this.reflecting=!1,this.pointerId=null,this.pointerThumb=null,this.currentValue=50,this.currentRange=[25,75],this.isDragging=!1,this.activeThumb=null,this.boundTrackClick=t=>this.handleTrackClick(t),this.boundPointerMove=t=>{t.pointerId===this.pointerId&&this.handlePointerMove(t)},this.boundPointerUp=t=>this.handlePointerUp(t),this.boundPointerCancel=t=>{t.pointerId===this.pointerId&&this.cancelDrag()},this.eventsBound=!1,this.handlePointerMove=t(t=>{this.isDragging&&this.isInteractive()&&t.pointerId===this.pointerId&&this.applyDragValue(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY)))})}static get observedAttributes(){return["value","range","min","max","step","size","variant","show-value","show-label","label","value-position","value-fixed","show-thumb-tooltip","show-marks","marks","mark-labels","snap-marks","disabled","readonly","full-width","vertical","aria-label","aria-labelledby","aria-describedby","label-minimum","label-maximum"]}connectedCallback(){for(const t of["value","range","min","max","step","size","variant","disabled","readOnly","vertical"]){if(!Object.prototype.hasOwnProperty.call(this,t))continue;const e=this,i=e[t];delete e[t],e[t]=i}this.built||(this.build(),this.built=!0),this.readAttributeValues(),this.syncClasses(),this.syncDomOrder(),this.syncStructure(),this.syncVisuals(),this.syncA11y(),this.bindEvents(),this.tooltipResize??(this.tooltipResize=new ResizeObserver(()=>{this.isConnected&&(this.syncThumbTooltips(),this.syncMarkLabelBounds())})),this.tooltipResize.observe(this)}disconnectedCallback(){this.cancelDrag(),this.unbindEvents(),this.tooltipResize?.disconnect()}attributeChangedCallback(t,e,i){if(!this.built||this.reflecting)return;const s="range"===t&&null===e!=(null===i);this.isInteractive()&&!s&&"vertical"!==t||this.cancelDrag();const r=this.thumbEls.findIndex(t=>t===this.ownerDocument.activeElement),a=this.thumbEls[r];this.readAttributeValues(t),this.syncClasses(),(s||this.isStructuralAttribute(t))&&(this.syncDomOrder(),this.syncStructure()),this.syncVisuals(),this.syncA11y();const n=a?.isConnected?a:r>=0?this.thumbEls[Math.min(r,this.thumbEls.length-1)]:void 0;n&&!this.disabled&&this.ownerDocument.activeElement!==n&&n.focus({preventScroll:!0})}isStructuralAttribute(t){return["min","max","step","show-value","show-label","label","value-position","show-marks","marks","mark-labels","vertical","aria-label","aria-labelledby","aria-describedby","label-minimum","label-maximum"].includes(t)}get value(){return this.built?this.currentValue:this.clamp(this.getNumberAttr("value",50))}set value(t){this.currentValue=this.clamp(Number.isFinite(t)?t:50),this.setAttribute("value",String(this.currentValue)),this.syncVisuals(),this.syncA11y()}get range(){if(!this.hasAttribute("range"))return;const t=this.built?this.currentRange:this.parseRangeAttr(this.getAttribute("range"))??this.currentRange;return this.normalizeValues(t)}set range(t){if(null==t)return this.removeAttribute("range"),void(this.built&&(this.syncStructure(),this.syncVisuals()));const e=this.normalizeRangeInput(t);if(!e)return;this.currentRange=this.normalizeValues(e);const i=`${this.currentRange[0]},${this.currentRange[1]}`;this.getAttribute("range")!==i&&this.setAttribute("range",i),this.built&&(this.syncVisuals(),this.syncA11y())}get min(){return this.getNumberAttr("min",0)}set min(t){this.setAttribute("min",String(t))}get max(){return Math.max(this.min,this.getNumberAttr("max",100))}set max(t){this.setAttribute("max",String(t))}get step(){const t=this.getNumberAttr("step",1);return t>0?t:1}set step(t){this.setAttribute("step",String(t))}get size(){return l(this.getAttribute("size"),h,"m")}set size(t){this.setAttribute("size",t)}get variant(){return l(this.getAttribute("variant"),u,"default")}set variant(t){this.setAttribute("variant",t)}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))}get vertical(){return this.hasAttribute("vertical")}set vertical(t){this.toggleAttribute("vertical",Boolean(t))}focus(t){this.thumbEls[0]?.focus(t)}get bounds(){return s(this.min,this.max,this.step)}normalizeValues(t){const e=this.clamp(t[0]),i=this.clamp(t[1]);return[Math.min(e,i),Math.max(e,i)]}build(){this.classList.add(c),this.headerEl=document.createElement("div"),this.headerEl.className=`${c}__header`,this.labelEl=document.createElement("span"),this.labelEl.className=`${c}__label`,this.valuesEl=document.createElement("div"),this.valuesEl.className=`${c}__values`,this.containerEl=document.createElement("div"),this.containerEl.className=`${c}__container`,this.trackEl=document.createElement("div"),this.trackEl.className=`${c}__track`,this.fillEl=document.createElement("div"),this.fillEl.className=`${c}__fill`,this.trackEl.appendChild(this.fillEl),this.containerEl.appendChild(this.trackEl)}getValuePosition(){const t=this.getAttribute("value-position");return t?l(t,o,this.shouldShowLabel()?"top":"right"):this.shouldShowLabel()?"top":"right"}shouldShowLabel(){return this.hasAttribute("show-label")&&Boolean(this.getAttribute("label")?.trim())}formatValue(t){const e=this.getAttribute("value-fixed");if(null!==e&&""!==e){const i=Number(e);if(Number.isFinite(i))return t.toFixed(Math.min(100,Math.max(0,Math.trunc(i))))}return String(t)}syncDomOrder(){if(!(this.headerEl&&this.valuesEl&&this.containerEl&&this.labelEl))return;const t=this.getValuePosition(),e=this.shouldShowLabel(),i=this.hasAttribute("show-value"),s=this.hasAttribute("range")||"top"===t;this.labelEl.textContent=this.getAttribute("label")?.trim()||"";const r=[...e?[this.labelEl]:[],...i&&s?[this.valuesEl]:[]];this.headerEl.replaceChildren(...r),this.containerEl.parentNode!==this&&this.append(this.containerEl),i&&!s?"bottom"===t?this.lastElementChild!==this.valuesEl&&this.append(this.valuesEl):this.valuesEl.nextElementSibling!==this.containerEl&&this.insertBefore(this.valuesEl,this.containerEl):s&&i||this.valuesEl.remove();const a=i&&!s&&"bottom"!==t?this.valuesEl:this.containerEl;r.length?this.headerEl.nextElementSibling!==a&&this.insertBefore(this.headerEl,a):this.headerEl.remove();const n=new Set([this.containerEl,...r.length?[this.headerEl]:[],...i&&!s?[this.valuesEl]:[]]);for(const t of Array.from(this.children))n.has(t)||t.remove()}bindEvents(){this.eventsBound||(this.containerEl?.addEventListener("click",this.boundTrackClick),this.eventsBound=!0)}unbindEvents(){this.eventsBound&&(this.containerEl?.removeEventListener("click",this.boundTrackClick),document.removeEventListener("pointermove",this.boundPointerMove),document.removeEventListener("pointerup",this.boundPointerUp),document.removeEventListener("pointercancel",this.boundPointerCancel),this.handlePointerMove.cancel(),this.eventsBound=!1)}readAttributeValues(t){const e=!this.initialized;if((e||"value"===t)&&(this.currentValue=this.clamp(this.getNumberAttr("value",50))),e||"range"===t){const t=this.parseRangeAttr(this.getAttribute("range"))??(this.hasAttribute("range")&&!this.getAttribute("range")?this.parseRangeAttr(this.getAttribute("value")):null);this.currentRange=t?this.normalizeValues(t):this.normalizeValues(this.currentRange)}this.currentValue=this.clamp(this.currentValue),this.currentRange=this.normalizeValues(this.currentRange),this.initialized=!0}syncClasses(){const t=this.size,i=this.variant,s=this.hasAttribute("range"),r=this.getValuePosition(),a=s?"top":r,n=this.hasAttribute("show-marks")&&this.parseMarks().length>0&&Object.keys(this.parseMarkLabels()).length>0,l=[c,`${c}--${t}`,`${c}--${i}`,`${c}--value-${a}`,this.shouldShowLabel()?`${c}--has-label`:"",this.hasAttribute("disabled")?`${c}--disabled`:"",this.hasAttribute("readonly")?`${c}--readonly`:"",this.hasAttribute("full-width")?`${c}--full-width`:"",this.hasAttribute("vertical")?`${c}--vertical`:"",this.hasAttribute("show-thumb-tooltip")?`${c}--show-tooltip`:"",s?`${c}--range`:"",n?`${c}--has-mark-labels`:""].filter(Boolean);if(e(this,l),this.trackEl){const t=[`${c}__track`];this.hasAttribute("disabled")&&t.push(`${c}__track--disabled`),this.hasAttribute("readonly")&&t.push(`${c}__track--readonly`),this.trackEl.className=t.join(" ")}}syncStructure(){if(!this.valuesEl||!this.trackEl||!this.fillEl)return;const t=this.hasAttribute("show-value"),e=this.hasAttribute("range"),i=this.hasAttribute("show-marks");if(this.valuesEl.innerHTML="",this.valuesEl.hidden=!t,t)if(e){const t=document.createElement("span");t.className=`${c}__value ${c}__value--min`;const e=document.createElement("span");e.className=`${c}__value-separator`,e.textContent="~",e.setAttribute("aria-hidden","true");const i=document.createElement("span");i.className=`${c}__value ${c}__value--max`,this.valuesEl.append(t,e,i)}else{const t=document.createElement("span");t.className=`${c}__value ${c}__value--single`,this.valuesEl.appendChild(t)}if(this.trackEl.querySelectorAll(`.${c}__mark`).forEach(t=>t.remove()),i){const t=this.parseMarks();if(t.length>0){const e=this.parseMarkLabels();t.forEach(t=>{const i=document.createElement("div");if(i.className=`${c}__mark`,i.setAttribute("aria-hidden","true"),i.dataset.value=String(t),this.isMarkActive(t)&&i.classList.add(`${c}__mark--active`),this.hasAttribute("vertical")?i.style.bottom=`${this.valueToPercent(t)}%`:i.style.left=`${this.valueToPercent(t)}%`,void 0!==e[t]){const s=document.createElement("span");s.className=`${c}__mark-label`,s.textContent=e[t],i.appendChild(s)}this.trackEl.insertBefore(i,this.fillEl)})}}const s=e?2:1;for(;this.thumbEls.length>s;)this.thumbEls.pop()?.remove();for(;this.thumbEls.length<s;){const t=document.createElement("div");t.className=`${c}__thumb`,t.setAttribute("role","slider"),t.setAttribute("draggable","false");const kind=()=>t.dataset.thumb||"single";t.addEventListener("pointerdown",t=>this.handleThumbPointerDown(t,kind())),t.addEventListener("keydown",t=>this.handleKeyDown(t,kind())),t.addEventListener("lostpointercapture",t=>{t.pointerId===this.pointerId&&this.cancelDrag()});const e=document.createElement("span");e.className=`${c}__thumb-tooltip`,e.setAttribute("aria-hidden","true"),e.hidden=!0,t.append(e),this.trackEl.append(t),this.thumbEls.push(t)}this.thumbEls.forEach((t,i)=>t.dataset.thumb=e?0===i?"min":"max":"single")}isMarkActive(t){if(this.hasAttribute("range")){const[e,i]=this.currentRange;return t>=e&&t<=i}return t<=this.currentValue}syncVisuals(){if(!this.fillEl)return;const t=this.hasAttribute("range"),e=this.min,i=this.max;if(t){const[t,s]=this.currentRange,r=this.valueToPercent(t),a=this.valueToPercent(s);this.hasAttribute("vertical")?(this.fillEl.style.left="",this.fillEl.style.width="",this.fillEl.style.bottom=`${r}%`,this.fillEl.style.height=a-r+"%"):(this.fillEl.style.bottom="",this.fillEl.style.height="",this.fillEl.style.left=`${r}%`,this.fillEl.style.width=a-r+"%"),this.thumbEls[0]&&(this.setThumbPosition(this.thumbEls[0],r),this.thumbEls[0].setAttribute("aria-valuemin",String(e)),this.thumbEls[0].setAttribute("aria-valuemax",String(s)),this.thumbEls[0].setAttribute("aria-valuenow",String(t))),this.thumbEls[1]&&(this.setThumbPosition(this.thumbEls[1],a),this.thumbEls[1].setAttribute("aria-valuemin",String(t)),this.thumbEls[1].setAttribute("aria-valuemax",String(i)),this.thumbEls[1].setAttribute("aria-valuenow",String(s)));const n=this.valuesEl?.querySelector(`.${c}__value--min`),l=this.valuesEl?.querySelector(`.${c}__value--max`);n&&(n.textContent=this.formatValue(t)),l&&(l.textContent=this.formatValue(s))}else{const t=this.valueToPercent(this.currentValue);this.hasAttribute("vertical")?(this.fillEl.style.left="",this.fillEl.style.width="",this.fillEl.style.bottom="0",this.fillEl.style.height=`${t}%`):(this.fillEl.style.bottom="",this.fillEl.style.height="",this.fillEl.style.left="0",this.fillEl.style.width=`${t}%`),this.thumbEls[0]&&(this.setThumbPosition(this.thumbEls[0],t),this.thumbEls[0].setAttribute("aria-valuemin",String(e)),this.thumbEls[0].setAttribute("aria-valuemax",String(i)),this.thumbEls[0].setAttribute("aria-valuenow",String(this.currentValue)));const s=this.valuesEl?.querySelector(`.${c}__value--single`);s&&(s.textContent=this.formatValue(this.currentValue))}this.syncThumbTooltips(),this.syncMarkLabelBounds(),this.trackEl?.querySelectorAll(`.${c}__mark`).forEach(t=>{const e=Number(t.dataset.value);t.classList.toggle(`${c}__mark--active`,this.isMarkActive(e))})}syncThumbTooltips(){const t=this.hasAttribute("range"),e=this.hasAttribute("show-thumb-tooltip");this.thumbEls.forEach((i,s)=>{const r=i.querySelector(`.${c}__thumb-tooltip`);if(!r)return;if(!e)return void(r.hidden=!0);r.hidden=!1;const a=t?0===s?this.currentRange[0]:this.currentRange[1]:this.currentValue;r.textContent=this.formatValue(a),this.fitFloatingText(r)})}fitFloatingText(t){const e=this.getBoundingClientRect();if(!e.width)return;t.style.maxWidth=`${e.width}px`,t.style.marginLeft="0px";const i=t.getBoundingClientRect(),s=i.left<e.left?e.left-i.left:i.right>e.right?e.right-i.right:0;s&&(t.style.marginLeft=`${s}px`)}syncMarkLabelBounds(){this.trackEl?.querySelectorAll(`.${c}__mark-label`).forEach(t=>this.fitFloatingText(t))}syncA11y(){if(!this.containerEl)return;const t=this.min,e=this.max,s=this.hasAttribute("range"),r=this.hasAttribute("disabled"),a=this.hasAttribute("readonly");this.containerEl.removeAttribute("role"),this.containerEl.removeAttribute("tabindex"),["aria-valuemin","aria-valuemax","aria-valuenow","aria-valuetext","aria-disabled","aria-readonly"].forEach(t=>this.containerEl?.removeAttribute(t));const n=this.getAttribute("aria-label")?.trim()||this.getAttribute("label")?.trim()||"Value";this.thumbEls.forEach((l,h)=>{const u=s?0===h?this.currentRange[0]:this.currentRange[1]:this.currentValue,o=s?`${n} ${0===h?this.getAttribute("label-minimum")||"minimum":this.getAttribute("label-maximum")||"maximum"}`:n;l.setAttribute("aria-label",o);const c=this.getAttribute("aria-labelledby");if(c)if(s){const t=l.querySelector("[data-range-endpoint]")??document.createElement("span");t.dataset.rangeEndpoint="",t.hidden=!0,t.id||(t.id=i("slider-endpoint")),t.textContent=0===h?this.getAttribute("label-minimum")||"minimum":this.getAttribute("label-maximum")||"maximum",t.parentNode||l.append(t),l.setAttribute("aria-labelledby",c+" "+t.id)}else l.setAttribute("aria-labelledby",c);else l.removeAttribute("aria-labelledby");const b=this.getAttribute("aria-describedby");b?l.setAttribute("aria-describedby",b):l.removeAttribute("aria-describedby"),l.setAttribute("aria-orientation",this.vertical?"vertical":"horizontal"),l.setAttribute("aria-valuemin",String(s&&1===h?this.currentRange[0]:t)),l.setAttribute("aria-valuemax",String(s&&0===h?this.currentRange[1]:e)),l.setAttribute("aria-valuenow",String(u)),l.setAttribute("aria-valuetext",this.formatValue(u)),l.setAttribute("aria-disabled",String(r)),l.setAttribute("aria-readonly",String(a)),l.setAttribute("tabindex",r?"-1":"0")})}setThumbPosition(t,e){this.hasAttribute("vertical")?(t.style.left="",t.style.bottom=`${e}%`):(t.style.bottom="",t.style.left=`${e}%`)}valueToPercent(t){return r(t,this.bounds)}percentToValue(t){return a(t,this.bounds)}clamp(t,e=this.min,i=this.max,r=this.step){const a=this.snapStops();return a.length>0&&Number.isFinite(t)?a.reduce((e,i)=>Math.abs(i-t)<Math.abs(e-t)?i:e,a[0]):n(t,s(e,i,r))}snapStops(){return this.hasAttribute("snap-marks")?this.parseMarks():[]}adjacentStop(t,e){const i=this.snapStops();return(e>0?i.find(e=>e>t):[...i].reverse().find(e=>e<t))??t}getNumberAttr(t,e){const i=this.getAttribute(t);if(null===i||""===i)return e;const s=Number(i);return Number.isFinite(s)?s:e}normalizeRangeInput(t){if("string"==typeof t)return this.parseRangeAttr(t);if(!Array.isArray(t)||t.length<2)return null;const e=Number(t[0]),i=Number(t[1]);return Number.isFinite(e)&&Number.isFinite(i)?[e,i]:null}parseRangeAttr(t){if(!t)return null;if(t.startsWith("[")){try{const e=JSON.parse(t);if(Array.isArray(e)&&2===e.length){const t=Number(e[0]),i=Number(e[1]);if(Number.isFinite(t)&&Number.isFinite(i))return[t,i]}}catch{return null}return null}const e=t.split(",").map(t=>Number(t.trim()));return 2!==e.length||e.some(t=>!Number.isFinite(t))?null:[e[0],e[1]]}parseMarks(){return[...new Set(this.readMarks())].filter(t=>t>=this.min&&t<=this.max).sort((t,e)=>t-e)}readMarks(){const t=this.getAttribute("marks");if(!t)return[];if(t.startsWith("[")){try{const e=JSON.parse(t);if(Array.isArray(e))return e.map(t=>Number(t)).filter(t=>Number.isFinite(t))}catch{return[]}return[]}return t.split(",").map(t=>Number(t.trim())).filter(t=>Number.isFinite(t))}parseMarkLabels(){const t=this.getAttribute("mark-labels");if(!t)return{};try{const e=JSON.parse(t);if(!e||"object"!=typeof e||Array.isArray(e))return{};const i={};return Object.entries(e).forEach(([t,e])=>{!Number.isFinite(Number(t))||"string"!=typeof e&&"number"!=typeof e||(i[Number(t)]=String(e))}),i}catch{return{}}}isInteractive(){return!this.hasAttribute("disabled")&&!this.hasAttribute("readonly")}getTrackPercent(t,e){if(!this.trackEl)return 0;const i=this.trackEl.getBoundingClientRect();if(!i.width||!i.height)return 0;if(this.hasAttribute("vertical")){const t=Math.max(i.top,Math.min(i.bottom,e));return(i.bottom-t)/i.height*100}return(Math.max(i.left,Math.min(i.right,t))-i.left)/i.width*100}handleThumbPointerDown(t,e){if(this.isInteractive()&&0===t.button&&!1!==t.isPrimary&&!this.isDragging){t.preventDefault(),this.isDragging=!0,this.pointerId=t.pointerId,this.activeThumb=e,this.pointerThumb=t.currentTarget,this.pointerThumb.focus({preventScroll:!0}),this.setThumbActive(e,!0);try{this.pointerThumb.setPointerCapture(t.pointerId)}catch{}document.addEventListener("pointermove",this.boundPointerMove),document.addEventListener("pointerup",this.boundPointerUp),document.addEventListener("pointercancel",this.boundPointerCancel)}}handleTrackClick(t){this.isInteractive()&&this.trackEl&&!t.target.closest(`.${c}__thumb`)&&this.commitValueAtPosition(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY)))}handlePointerUp(t){this.isDragging&&t.pointerId===this.pointerId&&(this.handlePointerMove.cancel(),this.isInteractive()&&this.applyDragValue(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY))),this.cancelDrag())}cancelDrag(){this.handlePointerMove.cancel(),this.activeThumb&&this.setThumbActive(this.activeThumb,!1);const t=this.pointerThumb,e=this.pointerId;this.isDragging=!1,this.activeThumb=null,this.pointerId=null,this.pointerThumb=null,document.removeEventListener("pointermove",this.boundPointerMove),document.removeEventListener("pointerup",this.boundPointerUp),document.removeEventListener("pointercancel",this.boundPointerCancel);try{t&&null!==e&&t.hasPointerCapture(e)&&t.releasePointerCapture(e)}catch{}}setThumbActive(t,e){if(this.hasAttribute("range")){const i=this.thumbEls["min"===t?0:1];return void i?.classList.toggle(`${c}__thumb--active`,e)}this.thumbEls[0]?.classList.toggle(`${c}__thumb--active`,e)}reflectCurrent(){this.reflecting=!0;try{const t=this.hasAttribute("range")?"range":"value",e="range"===t?this.currentRange.join(","):String(this.currentValue);this.getAttribute(t)!==e&&this.setAttribute(t,e)}finally{this.reflecting=!1}}applyDragValue(t){this.applyValue(t,this.activeThumb??"single")}applyValue(t,e){const i=this.clamp(t);if(this.hasAttribute("range")){const[t,s]=this.currentRange,r="min"===e?[Math.min(i,s),s]:[t,Math.max(i,t)];if(r[0]===t&&r[1]===s)return;this.currentRange=r}else{if(i===this.currentValue)return;this.currentValue=i}this.reflectCurrent(),this.syncVisuals(),this.syncA11y(),this.hasAttribute("range")?this.dispatchRangeChange():this.dispatchValueChange()}commitValueAtPosition(t){const e=this.hasAttribute("range")?Math.abs(t-this.currentRange[0])<=Math.abs(t-this.currentRange[1])?"min":"max":"single";this.thumbEls["max"===e?1:0]?.focus({preventScroll:!0}),this.applyValue(t,e)}handleKeyDown(t,e="single"){if(!this.isInteractive())return;const i=this.hasAttribute("range")?this.currentRange["max"===e?1:0]:this.currentValue;let s;if(this.snapStops().length>0){switch(t.key){case"ArrowLeft":case"ArrowDown":case"PageDown":s=this.adjacentStop(i,-1);break;case"ArrowRight":case"ArrowUp":case"PageUp":s=this.adjacentStop(i,1);break;case"Home":s=this.min;break;case"End":s=this.max;break;default:return}return t.preventDefault(),void this.applyValue(s,e)}switch(t.key){case"ArrowLeft":case"ArrowDown":s=i-this.step;break;case"ArrowRight":case"ArrowUp":s=i+this.step;break;case"PageDown":s=i-10*this.step;break;case"PageUp":s=i+10*this.step;break;case"Home":s=this.min;break;case"End":s=this.max;break;default:return}t.preventDefault(),this.applyValue(s,e)}dispatchValueChange(){this.dispatchEvent(new CustomEvent("db-change",{bubbles:!0,composed:!0,detail:{value:this.currentValue}}))}dispatchRangeChange(){const t=[...this.currentRange];for(const e of["db-change","db-range-change"])this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:{range:[...t]}}))}}customElements.get("db-range-slider")||customElements.define("db-range-slider",DbRangeSlider);export{DbRangeSlider};
1
+ import{rafThrottle as t}from"../core/dom.js";import{setHostClasses as e}from"../core/host-class.js";import{dbUid as i}from"../core/uid.js";import{subscribeDbLocale as s,dbText as r}from"../core/i18n.js";import{sliderBounds as a,sliderPercent as n,sliderValueAt as l,sliderValue as h}from"../core/range-values.js";import{coerceToContract as u}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RANGE_SLIDER_SIZES as o,RANGE_SLIDER_VARIANTS as c,RANGE_SLIDER_VALUE_POSITIONS as b}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const m="designbase-wc-range-slider";class DbRangeSlider extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.headerEl=null,this.labelEl=null,this.valuesEl=null,this.containerEl=null,this.trackEl=null,this.fillEl=null,this.thumbEls=[],this.initialized=!1,this.reflecting=!1,this.pointerId=null,this.pointerThumb=null,this.currentValue=50,this.currentRange=[25,75],this.isDragging=!1,this.activeThumb=null,this.boundTrackClick=t=>this.handleTrackClick(t),this.boundPointerMove=t=>{t.pointerId===this.pointerId&&this.handlePointerMove(t)},this.boundPointerUp=t=>this.handlePointerUp(t),this.boundPointerCancel=t=>{t.pointerId===this.pointerId&&this.cancelDrag()},this.eventsBound=!1,this.handlePointerMove=t(t=>{this.isDragging&&this.isInteractive()&&t.pointerId===this.pointerId&&this.applyDragValue(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY)))})}static get observedAttributes(){return["value","range","min","max","step","size","variant","show-value","show-label","label","value-position","value-fixed","show-thumb-tooltip","show-marks","marks","mark-labels","snap-marks","disabled","readonly","full-width","vertical","aria-label","aria-labelledby","aria-describedby","label-minimum","label-maximum"]}connectedCallback(){for(const t of["value","range","min","max","step","size","variant","disabled","readOnly","vertical"]){if(!Object.prototype.hasOwnProperty.call(this,t))continue;const e=this,i=e[t];delete e[t],e[t]=i}this.built||(this.build(),this.built=!0),this.readAttributeValues(),this.syncClasses(),this.syncDomOrder(),this.syncStructure(),this.syncVisuals(),this.syncA11y(),this.unsubscribeLocale?.(),this.unsubscribeLocale=s(()=>this.syncA11y()),this.bindEvents(),this.tooltipResize??(this.tooltipResize=new ResizeObserver(()=>{this.isConnected&&(this.syncThumbTooltips(),this.syncMarkLabelBounds())})),this.tooltipResize.observe(this)}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.cancelDrag(),this.unbindEvents(),this.tooltipResize?.disconnect()}attributeChangedCallback(t,e,i){if(!this.built||this.reflecting)return;const s="range"===t&&null===e!=(null===i);this.isInteractive()&&!s&&"vertical"!==t||this.cancelDrag();const r=this.thumbEls.findIndex(t=>t===this.ownerDocument.activeElement),a=this.thumbEls[r];this.readAttributeValues(t),this.syncClasses(),(s||this.isStructuralAttribute(t))&&(this.syncDomOrder(),this.syncStructure()),this.syncVisuals(),this.syncA11y();const n=a?.isConnected?a:r>=0?this.thumbEls[Math.min(r,this.thumbEls.length-1)]:void 0;n&&!this.disabled&&this.ownerDocument.activeElement!==n&&n.focus({preventScroll:!0})}isStructuralAttribute(t){return["min","max","step","show-value","show-label","label","value-position","show-marks","marks","mark-labels","vertical","aria-label","aria-labelledby","aria-describedby","label-minimum","label-maximum"].includes(t)}get value(){return this.built?this.currentValue:this.clamp(this.getNumberAttr("value",50))}set value(t){this.currentValue=this.clamp(Number.isFinite(t)?t:50),this.setAttribute("value",String(this.currentValue)),this.syncVisuals(),this.syncA11y()}get range(){if(!this.hasAttribute("range"))return;const t=this.built?this.currentRange:this.parseRangeAttr(this.getAttribute("range"))??this.currentRange;return this.normalizeValues(t)}set range(t){if(null==t)return this.removeAttribute("range"),void(this.built&&(this.syncStructure(),this.syncVisuals()));const e=this.normalizeRangeInput(t);if(!e)return;this.currentRange=this.normalizeValues(e);const i=`${this.currentRange[0]},${this.currentRange[1]}`;this.getAttribute("range")!==i&&this.setAttribute("range",i),this.built&&(this.syncVisuals(),this.syncA11y())}get min(){return this.getNumberAttr("min",0)}set min(t){this.setAttribute("min",String(t))}get max(){return Math.max(this.min,this.getNumberAttr("max",100))}set max(t){this.setAttribute("max",String(t))}get step(){const t=this.getNumberAttr("step",1);return t>0?t:1}set step(t){this.setAttribute("step",String(t))}get size(){return u(this.getAttribute("size"),o,"m")}set size(t){this.setAttribute("size",t)}get variant(){return u(this.getAttribute("variant"),c,"default")}set variant(t){this.setAttribute("variant",t)}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))}get vertical(){return this.hasAttribute("vertical")}set vertical(t){this.toggleAttribute("vertical",Boolean(t))}focus(t){this.thumbEls[0]?.focus(t)}get bounds(){return a(this.min,this.max,this.step)}normalizeValues(t){const e=this.clamp(t[0]),i=this.clamp(t[1]);return[Math.min(e,i),Math.max(e,i)]}build(){this.classList.add(m),this.headerEl=document.createElement("div"),this.headerEl.className=`${m}__header`,this.labelEl=document.createElement("span"),this.labelEl.className=`${m}__label`,this.valuesEl=document.createElement("div"),this.valuesEl.className=`${m}__values`,this.containerEl=document.createElement("div"),this.containerEl.className=`${m}__container`,this.trackEl=document.createElement("div"),this.trackEl.className=`${m}__track`,this.fillEl=document.createElement("div"),this.fillEl.className=`${m}__fill`,this.trackEl.appendChild(this.fillEl),this.containerEl.appendChild(this.trackEl)}getValuePosition(){const t=this.getAttribute("value-position");return t?u(t,b,this.shouldShowLabel()?"top":"right"):this.shouldShowLabel()?"top":"right"}shouldShowLabel(){return this.hasAttribute("show-label")&&Boolean(this.getAttribute("label")?.trim())}formatValue(t){const e=this.getAttribute("value-fixed");if(null!==e&&""!==e){const i=Number(e);if(Number.isFinite(i))return t.toFixed(Math.min(100,Math.max(0,Math.trunc(i))))}return String(t)}syncDomOrder(){if(!(this.headerEl&&this.valuesEl&&this.containerEl&&this.labelEl))return;const t=this.getValuePosition(),e=this.shouldShowLabel(),i=this.hasAttribute("show-value"),s=this.hasAttribute("range")||"top"===t;this.labelEl.textContent=this.getAttribute("label")?.trim()||"";const r=[...e?[this.labelEl]:[],...i&&s?[this.valuesEl]:[]];this.headerEl.replaceChildren(...r),this.containerEl.parentNode!==this&&this.append(this.containerEl),i&&!s?"bottom"===t?this.lastElementChild!==this.valuesEl&&this.append(this.valuesEl):this.valuesEl.nextElementSibling!==this.containerEl&&this.insertBefore(this.valuesEl,this.containerEl):s&&i||this.valuesEl.remove();const a=i&&!s&&"bottom"!==t?this.valuesEl:this.containerEl;r.length?this.headerEl.nextElementSibling!==a&&this.insertBefore(this.headerEl,a):this.headerEl.remove();const n=new Set([this.containerEl,...r.length?[this.headerEl]:[],...i&&!s?[this.valuesEl]:[]]);for(const t of Array.from(this.children))n.has(t)||t.remove()}bindEvents(){this.eventsBound||(this.containerEl?.addEventListener("click",this.boundTrackClick),this.eventsBound=!0)}unbindEvents(){this.eventsBound&&(this.containerEl?.removeEventListener("click",this.boundTrackClick),document.removeEventListener("pointermove",this.boundPointerMove),document.removeEventListener("pointerup",this.boundPointerUp),document.removeEventListener("pointercancel",this.boundPointerCancel),this.handlePointerMove.cancel(),this.eventsBound=!1)}readAttributeValues(t){const e=!this.initialized;if((e||"value"===t)&&(this.currentValue=this.clamp(this.getNumberAttr("value",50))),e||"range"===t){const t=this.parseRangeAttr(this.getAttribute("range"))??(this.hasAttribute("range")&&!this.getAttribute("range")?this.parseRangeAttr(this.getAttribute("value")):null);this.currentRange=t?this.normalizeValues(t):this.normalizeValues(this.currentRange)}this.currentValue=this.clamp(this.currentValue),this.currentRange=this.normalizeValues(this.currentRange),this.initialized=!0}syncClasses(){const t=this.size,i=this.variant,s=this.hasAttribute("range"),r=this.getValuePosition(),a=s?"top":r,n=this.hasAttribute("show-marks")&&this.parseMarks().length>0&&Object.keys(this.parseMarkLabels()).length>0,l=[m,`${m}--${t}`,`${m}--${i}`,`${m}--value-${a}`,this.shouldShowLabel()?`${m}--has-label`:"",this.hasAttribute("disabled")?`${m}--disabled`:"",this.hasAttribute("readonly")?`${m}--readonly`:"",this.hasAttribute("full-width")?`${m}--full-width`:"",this.hasAttribute("vertical")?`${m}--vertical`:"",this.hasAttribute("show-thumb-tooltip")?`${m}--show-tooltip`:"",s?`${m}--range`:"",n?`${m}--has-mark-labels`:""].filter(Boolean);if(e(this,l),this.trackEl){const t=[`${m}__track`];this.hasAttribute("disabled")&&t.push(`${m}__track--disabled`),this.hasAttribute("readonly")&&t.push(`${m}__track--readonly`),this.trackEl.className=t.join(" ")}}syncStructure(){if(!this.valuesEl||!this.trackEl||!this.fillEl)return;const t=this.hasAttribute("show-value"),e=this.hasAttribute("range"),i=this.hasAttribute("show-marks");if(this.valuesEl.innerHTML="",this.valuesEl.hidden=!t,t)if(e){const t=document.createElement("span");t.className=`${m}__value ${m}__value--min`;const e=document.createElement("span");e.className=`${m}__value-separator`,e.textContent="~",e.setAttribute("aria-hidden","true");const i=document.createElement("span");i.className=`${m}__value ${m}__value--max`,this.valuesEl.append(t,e,i)}else{const t=document.createElement("span");t.className=`${m}__value ${m}__value--single`,this.valuesEl.appendChild(t)}if(this.trackEl.querySelectorAll(`.${m}__mark`).forEach(t=>t.remove()),i){const t=this.parseMarks();if(t.length>0){const e=this.parseMarkLabels();t.forEach(t=>{const i=document.createElement("div");if(i.className=`${m}__mark`,i.setAttribute("aria-hidden","true"),i.dataset.value=String(t),this.isMarkActive(t)&&i.classList.add(`${m}__mark--active`),this.hasAttribute("vertical")?i.style.bottom=`${this.valueToPercent(t)}%`:i.style.left=`${this.valueToPercent(t)}%`,void 0!==e[t]){const s=document.createElement("span");s.className=`${m}__mark-label`,s.textContent=e[t],i.appendChild(s)}this.trackEl.insertBefore(i,this.fillEl)})}}const s=e?2:1;for(;this.thumbEls.length>s;)this.thumbEls.pop()?.remove();for(;this.thumbEls.length<s;){const t=document.createElement("div");t.className=`${m}__thumb`,t.setAttribute("role","slider"),t.setAttribute("draggable","false");const kind=()=>t.dataset.thumb||"single";t.addEventListener("pointerdown",t=>this.handleThumbPointerDown(t,kind())),t.addEventListener("keydown",t=>this.handleKeyDown(t,kind())),t.addEventListener("lostpointercapture",t=>{t.pointerId===this.pointerId&&this.cancelDrag()});const e=document.createElement("span");e.className=`${m}__thumb-tooltip`,e.setAttribute("aria-hidden","true"),e.hidden=!0,t.append(e),this.trackEl.append(t),this.thumbEls.push(t)}this.thumbEls.forEach((t,i)=>t.dataset.thumb=e?0===i?"min":"max":"single")}isMarkActive(t){if(this.hasAttribute("range")){const[e,i]=this.currentRange;return t>=e&&t<=i}return t<=this.currentValue}syncVisuals(){if(!this.fillEl)return;const t=this.hasAttribute("range"),e=this.min,i=this.max;if(t){const[t,s]=this.currentRange,r=this.valueToPercent(t),a=this.valueToPercent(s);this.hasAttribute("vertical")?(this.fillEl.style.left="",this.fillEl.style.width="",this.fillEl.style.bottom=`${r}%`,this.fillEl.style.height=a-r+"%"):(this.fillEl.style.bottom="",this.fillEl.style.height="",this.fillEl.style.left=`${r}%`,this.fillEl.style.width=a-r+"%"),this.thumbEls[0]&&(this.setThumbPosition(this.thumbEls[0],r),this.thumbEls[0].setAttribute("aria-valuemin",String(e)),this.thumbEls[0].setAttribute("aria-valuemax",String(s)),this.thumbEls[0].setAttribute("aria-valuenow",String(t))),this.thumbEls[1]&&(this.setThumbPosition(this.thumbEls[1],a),this.thumbEls[1].setAttribute("aria-valuemin",String(t)),this.thumbEls[1].setAttribute("aria-valuemax",String(i)),this.thumbEls[1].setAttribute("aria-valuenow",String(s)));const n=this.valuesEl?.querySelector(`.${m}__value--min`),l=this.valuesEl?.querySelector(`.${m}__value--max`);n&&(n.textContent=this.formatValue(t)),l&&(l.textContent=this.formatValue(s))}else{const t=this.valueToPercent(this.currentValue);this.hasAttribute("vertical")?(this.fillEl.style.left="",this.fillEl.style.width="",this.fillEl.style.bottom="0",this.fillEl.style.height=`${t}%`):(this.fillEl.style.bottom="",this.fillEl.style.height="",this.fillEl.style.left="0",this.fillEl.style.width=`${t}%`),this.thumbEls[0]&&(this.setThumbPosition(this.thumbEls[0],t),this.thumbEls[0].setAttribute("aria-valuemin",String(e)),this.thumbEls[0].setAttribute("aria-valuemax",String(i)),this.thumbEls[0].setAttribute("aria-valuenow",String(this.currentValue)));const s=this.valuesEl?.querySelector(`.${m}__value--single`);s&&(s.textContent=this.formatValue(this.currentValue))}this.syncThumbTooltips(),this.syncMarkLabelBounds(),this.trackEl?.querySelectorAll(`.${m}__mark`).forEach(t=>{const e=Number(t.dataset.value);t.classList.toggle(`${m}__mark--active`,this.isMarkActive(e))})}syncThumbTooltips(){const t=this.hasAttribute("range"),e=this.hasAttribute("show-thumb-tooltip");this.thumbEls.forEach((i,s)=>{const r=i.querySelector(`.${m}__thumb-tooltip`);if(!r)return;if(!e)return void(r.hidden=!0);r.hidden=!1;const a=t?0===s?this.currentRange[0]:this.currentRange[1]:this.currentValue;r.textContent=this.formatValue(a),this.fitFloatingText(r)})}fitFloatingText(t){const e=this.getBoundingClientRect();if(!e.width)return;t.style.maxWidth=`${e.width}px`,t.style.marginLeft="0px";const i=t.getBoundingClientRect(),s=i.left<e.left?e.left-i.left:i.right>e.right?e.right-i.right:0;s&&(t.style.marginLeft=`${s}px`)}syncMarkLabelBounds(){this.trackEl?.querySelectorAll(`.${m}__mark-label`).forEach(t=>this.fitFloatingText(t))}syncA11y(){if(!this.containerEl)return;const t=this.min,e=this.max,s=this.hasAttribute("range"),a=this.hasAttribute("disabled"),n=this.hasAttribute("readonly");this.containerEl.removeAttribute("role"),this.containerEl.removeAttribute("tabindex"),["aria-valuemin","aria-valuemax","aria-valuenow","aria-valuetext","aria-disabled","aria-readonly"].forEach(t=>this.containerEl?.removeAttribute(t));const l=this.getAttribute("aria-label")?.trim()||this.getAttribute("label")?.trim()||r("슬라이더 값");this.thumbEls.forEach((h,u)=>{const o=s?0===u?this.currentRange[0]:this.currentRange[1]:this.currentValue,c=0===u?this.getAttribute("label-minimum")||r("범위 최솟값"):this.getAttribute("label-maximum")||r("범위 최댓값"),b=s?`${l} ${c}`:l;h.setAttribute("aria-label",b);const m=this.getAttribute("aria-labelledby");if(m)if(s){const t=h.querySelector("[data-range-endpoint]")??document.createElement("span");t.dataset.rangeEndpoint="",t.hidden=!0,t.id||(t.id=i("slider-endpoint")),t.textContent=c,t.parentNode||h.append(t),h.setAttribute("aria-labelledby",m+" "+t.id)}else h.setAttribute("aria-labelledby",m);else h.removeAttribute("aria-labelledby");const d=this.getAttribute("aria-describedby");d?h.setAttribute("aria-describedby",d):h.removeAttribute("aria-describedby"),h.setAttribute("aria-orientation",this.vertical?"vertical":"horizontal"),h.setAttribute("aria-valuemin",String(s&&1===u?this.currentRange[0]:t)),h.setAttribute("aria-valuemax",String(s&&0===u?this.currentRange[1]:e)),h.setAttribute("aria-valuenow",String(o)),h.setAttribute("aria-valuetext",this.formatValue(o)),h.setAttribute("aria-disabled",String(a)),h.setAttribute("aria-readonly",String(n)),h.setAttribute("tabindex",a?"-1":"0")})}setThumbPosition(t,e){this.hasAttribute("vertical")?(t.style.left="",t.style.bottom=`${e}%`):(t.style.bottom="",t.style.left=`${e}%`)}valueToPercent(t){return n(t,this.bounds)}percentToValue(t){return l(t,this.bounds)}clamp(t,e=this.min,i=this.max,s=this.step){const r=this.snapStops();return r.length>0&&Number.isFinite(t)?r.reduce((e,i)=>Math.abs(i-t)<Math.abs(e-t)?i:e,r[0]):h(t,a(e,i,s))}snapStops(){return this.hasAttribute("snap-marks")?this.parseMarks():[]}adjacentStop(t,e){const i=this.snapStops();return(e>0?i.find(e=>e>t):[...i].reverse().find(e=>e<t))??t}getNumberAttr(t,e){const i=this.getAttribute(t);if(null===i||""===i)return e;const s=Number(i);return Number.isFinite(s)?s:e}normalizeRangeInput(t){if("string"==typeof t)return this.parseRangeAttr(t);if(!Array.isArray(t)||t.length<2)return null;const e=Number(t[0]),i=Number(t[1]);return Number.isFinite(e)&&Number.isFinite(i)?[e,i]:null}parseRangeAttr(t){if(!t)return null;if(t.startsWith("[")){try{const e=JSON.parse(t);if(Array.isArray(e)&&2===e.length){const t=Number(e[0]),i=Number(e[1]);if(Number.isFinite(t)&&Number.isFinite(i))return[t,i]}}catch{return null}return null}const e=t.split(",").map(t=>Number(t.trim()));return 2!==e.length||e.some(t=>!Number.isFinite(t))?null:[e[0],e[1]]}parseMarks(){return[...new Set(this.readMarks())].filter(t=>t>=this.min&&t<=this.max).sort((t,e)=>t-e)}readMarks(){const t=this.getAttribute("marks");if(!t)return[];if(t.startsWith("[")){try{const e=JSON.parse(t);if(Array.isArray(e))return e.map(t=>Number(t)).filter(t=>Number.isFinite(t))}catch{return[]}return[]}return t.split(",").map(t=>Number(t.trim())).filter(t=>Number.isFinite(t))}parseMarkLabels(){const t=this.getAttribute("mark-labels");if(!t)return{};try{const e=JSON.parse(t);if(!e||"object"!=typeof e||Array.isArray(e))return{};const i={};return Object.entries(e).forEach(([t,e])=>{!Number.isFinite(Number(t))||"string"!=typeof e&&"number"!=typeof e||(i[Number(t)]=String(e))}),i}catch{return{}}}isInteractive(){return!this.hasAttribute("disabled")&&!this.hasAttribute("readonly")}getTrackPercent(t,e){if(!this.trackEl)return 0;const i=this.trackEl.getBoundingClientRect();if(!i.width||!i.height)return 0;if(this.hasAttribute("vertical")){const t=Math.max(i.top,Math.min(i.bottom,e));return(i.bottom-t)/i.height*100}return(Math.max(i.left,Math.min(i.right,t))-i.left)/i.width*100}handleThumbPointerDown(t,e){if(this.isInteractive()&&0===t.button&&!1!==t.isPrimary&&!this.isDragging){t.preventDefault(),this.isDragging=!0,this.pointerId=t.pointerId,this.activeThumb=e,this.pointerThumb=t.currentTarget,this.pointerThumb.focus({preventScroll:!0}),this.setThumbActive(e,!0);try{this.pointerThumb.setPointerCapture(t.pointerId)}catch{}document.addEventListener("pointermove",this.boundPointerMove),document.addEventListener("pointerup",this.boundPointerUp),document.addEventListener("pointercancel",this.boundPointerCancel)}}handleTrackClick(t){this.isInteractive()&&this.trackEl&&!t.target.closest(`.${m}__thumb`)&&this.commitValueAtPosition(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY)))}handlePointerUp(t){this.isDragging&&t.pointerId===this.pointerId&&(this.handlePointerMove.cancel(),this.isInteractive()&&this.applyDragValue(this.percentToValue(this.getTrackPercent(t.clientX,t.clientY))),this.cancelDrag())}cancelDrag(){this.handlePointerMove.cancel(),this.activeThumb&&this.setThumbActive(this.activeThumb,!1);const t=this.pointerThumb,e=this.pointerId;this.isDragging=!1,this.activeThumb=null,this.pointerId=null,this.pointerThumb=null,document.removeEventListener("pointermove",this.boundPointerMove),document.removeEventListener("pointerup",this.boundPointerUp),document.removeEventListener("pointercancel",this.boundPointerCancel);try{t&&null!==e&&t.hasPointerCapture(e)&&t.releasePointerCapture(e)}catch{}}setThumbActive(t,e){if(this.hasAttribute("range")){const i=this.thumbEls["min"===t?0:1];return void i?.classList.toggle(`${m}__thumb--active`,e)}this.thumbEls[0]?.classList.toggle(`${m}__thumb--active`,e)}reflectCurrent(){this.reflecting=!0;try{const t=this.hasAttribute("range")?"range":"value",e="range"===t?this.currentRange.join(","):String(this.currentValue);this.getAttribute(t)!==e&&this.setAttribute(t,e)}finally{this.reflecting=!1}}applyDragValue(t){this.applyValue(t,this.activeThumb??"single")}applyValue(t,e){const i=this.clamp(t);if(this.hasAttribute("range")){const[t,s]=this.currentRange,r="min"===e?[Math.min(i,s),s]:[t,Math.max(i,t)];if(r[0]===t&&r[1]===s)return;this.currentRange=r}else{if(i===this.currentValue)return;this.currentValue=i}this.reflectCurrent(),this.syncVisuals(),this.syncA11y(),this.hasAttribute("range")?this.dispatchRangeChange():this.dispatchValueChange()}commitValueAtPosition(t){const e=this.hasAttribute("range")?Math.abs(t-this.currentRange[0])<=Math.abs(t-this.currentRange[1])?"min":"max":"single";this.thumbEls["max"===e?1:0]?.focus({preventScroll:!0}),this.applyValue(t,e)}handleKeyDown(t,e="single"){if(!this.isInteractive())return;const i=this.hasAttribute("range")?this.currentRange["max"===e?1:0]:this.currentValue;let s;if(this.snapStops().length>0){switch(t.key){case"ArrowLeft":case"ArrowDown":case"PageDown":s=this.adjacentStop(i,-1);break;case"ArrowRight":case"ArrowUp":case"PageUp":s=this.adjacentStop(i,1);break;case"Home":s=this.min;break;case"End":s=this.max;break;default:return}return t.preventDefault(),void this.applyValue(s,e)}switch(t.key){case"ArrowLeft":case"ArrowDown":s=i-this.step;break;case"ArrowRight":case"ArrowUp":s=i+this.step;break;case"PageDown":s=i-10*this.step;break;case"PageUp":s=i+10*this.step;break;case"Home":s=this.min;break;case"End":s=this.max;break;default:return}t.preventDefault(),this.applyValue(s,e)}dispatchValueChange(){this.dispatchEvent(new CustomEvent("db-change",{bubbles:!0,composed:!0,detail:{value:this.currentValue}}))}dispatchRangeChange(){const t=[...this.currentRange];for(const e of["db-change","db-range-change"])this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:{range:[...t]}}))}}customElements.get("db-range-slider")||customElements.define("db-range-slider",DbRangeSlider);export{DbRangeSlider};
@@ -1,4 +1,5 @@
1
1
  declare class DbRating extends HTMLElement {
2
+ private unsubscribeLocale?;
2
3
  private hoverValue;
3
4
  private starsEl;
4
5
  static get observedAttributes(): string[];
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";import{rafThrottle as t}from"../core/dom.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RATING_SIZES as i,RATING_VARIANTS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const a=i,n=r,o=["stars","number","both","reviews","detailed"],l=["star","number","percentage","text"],c=["primary","secondary","success","warning","error","custom"];class DbRating extends HTMLElement{constructor(){super(...arguments),this.hoverValue=null,this.starsEl=null,this.handlePointerMove=t(e=>{if(!this.isInteractive()||!this.getBooleanAttr("hover-effect",!0))return;const t=e.target?.closest(".designbase-wc-rating__star");if(!t||!this.contains(t))return;const s=Number(t.dataset.index);if(!Number.isFinite(s))return;const i=this.getNumberAttr("max-value",5),r=this.getPointerValue(s,e.clientX,t,i);this.hoverValue!==r&&(this.hoverValue=r,this.classList.toggle("designbase-wc-rating--hovering",!0),this.refreshStars(),this.dispatchEvent(new CustomEvent("db-hover",{detail:{value:r},bubbles:!0,composed:!0})))}),this.handlePointerLeave=()=>{null!==this.hoverValue&&(this.hoverValue=null,this.classList.remove("designbase-wc-rating--hovering"),this.refreshStars())},this.handleClick=e=>{if(!this.isInteractive())return;const t=e.target?.closest(".designbase-wc-rating__star");if(!t||!this.contains(t))return;e.preventDefault();const s=Number(t.dataset.index);if(!Number.isFinite(s))return;const i=this.getNumberAttr("max-value",5),r=this.getPointerValue(s,e.clientX,t,i);this.hoverValue=null,this.classList.remove("designbase-wc-rating--hovering"),this.setAttribute("value",String(r)),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:r},bubbles:!0,composed:!0})),this.render()}}static get observedAttributes(){return["value","max-value","size","variant","type","display","review-count","rating-text","review-text","allow-half","readonly","disabled","clickable","color","custom-color","animated","hover-effect"]}connectedCallback(){this.addEventListener("mousemove",this.handlePointerMove),this.addEventListener("mouseleave",this.handlePointerLeave),this.addEventListener("click",this.handleClick),this.render()}disconnectedCallback(){this.removeEventListener("mousemove",this.handlePointerMove),this.removeEventListener("mouseleave",this.handlePointerLeave),this.removeEventListener("click",this.handleClick)}attributeChangedCallback(){this.isConnected&&this.render()}getNumberAttr(e,t){const s=this.getAttribute(e);if(null===s||""===s)return t;const i=Number(s);return Number.isFinite(i)?i:t}getBooleanAttr(e,t=!1){if(!this.hasAttribute(e))return t;const s=this.getAttribute(e);return""===s||"true"===s}getOption(e,t,s){const i=this.getAttribute(e);return i&&t.includes(i)?i:s}normalizeSize(e){return"xs"===e||"s"===e?"s":"xl"===e||"l"===e?"l":"m"===e?"m":s(e,a,"m")}getStarIconSize(){const e=this.normalizeSize(this.getAttribute("size"));return"s"===e?16:"l"===e?24:20}supportsHalfSteps(){return this.getBooleanAttr("allow-half")||this.getBooleanAttr("clickable")}isInteractive(){return this.getBooleanAttr("clickable")&&!this.getBooleanAttr("readonly")&&!this.getBooleanAttr("disabled")}getStarFill(e,t,s){const i=e+1;return t>=i?1:s&&t>=i-.5?.5:0}getPointerValue(e,t,s,i){const r=s.getBoundingClientRect();let a;return a=this.supportsHalfSteps()&&t-r.left<r.width/2?e+.5:e+1,a/5*i}formatRating(e,t,s,i){const r=e/t*5;return"percentage"===s?`${Math.round(e/t*100)}%`:"number"===s?i?r.toFixed(1):String(Math.round(r)):"text"===s?r>=4.5?"매우 좋음":r>=3?"보통":"낮음":`${r.toFixed(1)}/5`}updateStarElement(t,s,i,r,a){t.className=["designbase-wc-rating__star",0===s&&"designbase-wc-rating__star--empty",s>0&&a&&"designbase-wc-rating__star--hover-preview",r&&"designbase-wc-rating__star--clickable",this.getBooleanAttr("animated")&&"designbase-wc-rating__star--animated"].filter(Boolean).join(" "),t.dataset.index=String(i);const n=1===s?"star-filled":.5===s?"star-half":"star",o=this.getStarIconSize(),l=t.querySelector("svg");l?.getAttribute("data-designbase-icon")===n&&l.getAttribute("width")===String(o)||t.replaceChildren(e(n,o))}refreshStars(){if(!this.starsEl)return;const e=this.getNumberAttr("value",0),t=this.getNumberAttr("max-value",5),s=this.getBooleanAttr("allow-half",!1),i=this.getBooleanAttr("hover-effect",!0),r=null!==this.hoverValue&&i,a=(r?this.hoverValue:e)/t*5,n=this.isInteractive(),o=s||r,l=Array.from(this.starsEl.querySelectorAll(":scope > .designbase-wc-rating__star"));for(let e=0;e<5;e+=1){const t=this.getStarFill(e,a,o),s=r&&t>0,i=l[e]??document.createElement("span");i.setAttribute("aria-hidden","true"),this.updateStarElement(i,t,e,n,s),l[e]||this.starsEl.append(i)}for(let e=l.length-1;e>=5;e-=1)l[e]?.remove()}render(){const e=this.getNumberAttr("value",0),t=this.getNumberAttr("max-value",5),s=this.normalizeSize(this.getAttribute("size")),i=this.getOption("variant",n,"default"),r=this.getOption("type",l,"star"),a=this.getOption("display",o,"stars"),h=this.getOption("color",c,"primary"),g=this.getNumberAttr("review-count",0),d=this.getBooleanAttr("allow-half",!1),u=this.getBooleanAttr("readonly",!1),m=this.getBooleanAttr("disabled",!1),b=this.getBooleanAttr("clickable",!1),v=this.getBooleanAttr("hover-effect",!0),p=null!==this.hoverValue&&v;this.className=["designbase-wc-rating",`designbase-wc-rating--size-${s}`,`designbase-wc-rating--variant-${i}`,`designbase-wc-rating--type-${r}`,`designbase-wc-rating--display-${a}`,`designbase-wc-rating--color-${h}`,u&&"designbase-wc-rating--readonly",m&&"designbase-wc-rating--disabled",b&&"designbase-wc-rating--clickable",this.getBooleanAttr("animated")&&"designbase-wc-rating--animated",p&&"designbase-wc-rating--hovering"].filter(Boolean).join(" ");const f=this.getAttribute("custom-color");"custom"===h&&f?this.style.setProperty("--rating-color",f):this.style.removeProperty("--rating-color");let w=this.querySelector(':scope > [role="img"]');w||(w=document.createElement("div"),this.replaceChildren(w)),w.setAttribute("role","img"),w.setAttribute("aria-label",`rating ${this.formatRating(e,t,r,d)}`);if("stars"===a||"both"===a||"detailed"===a){const e=w.querySelectorAll(":scope > .designbase-wc-rating__stars");e.forEach((e,t)=>{t>0&&e.remove()});const t=e[0];t?this.starsEl=t:(this.starsEl=document.createElement("div"),this.starsEl.className="designbase-wc-rating__stars",w.prepend(this.starsEl)),this.refreshStars()}else this.starsEl&&(this.starsEl.remove(),this.starsEl=null);const A=this.getAttribute("rating-text")||this.formatRating(e,t,r,d);let _=w.querySelector(".designbase-wc-rating__number-container");if("number"===a||"both"===a){if(!_){_=document.createElement("div"),_.className="designbase-wc-rating__number-container";const e=document.createElement("span");e.className="designbase-wc-rating__number",_.append(e),w.append(_)}const e=_.querySelector(".designbase-wc-rating__number");e&&(e.textContent=A)}else _?.remove();let E=w.querySelector(".designbase-wc-rating__review-count");if("reviews"===a||"detailed"===a){const e=this.getAttribute("review-text")||(g>0?`${g.toLocaleString()} 리뷰`:"");e?(E||(E=document.createElement("span"),E.className="designbase-wc-rating__review-count",w.append(E)),E.textContent=e):E?.remove()}else E?.remove()}}customElements.get("db-rating")||customElements.define("db-rating",DbRating);export{DbRating};
1
+ import{subscribeDbLocale as e,t,getDbLocale as s}from"../core/i18n.js";import{createDbIcon as i}from"./db-icons.js";import{rafThrottle as r}from"../core/dom.js";import{coerceToContract as a}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RATING_SIZES as n,RATING_VARIANTS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const l=n,c=o,h=["stars","number","both","reviews","detailed"],g=["star","number","percentage","text"],u=["primary","secondary","success","warning","error","custom"];class DbRating extends HTMLElement{constructor(){super(...arguments),this.hoverValue=null,this.starsEl=null,this.handlePointerMove=r(e=>{if(!this.isInteractive()||!this.getBooleanAttr("hover-effect",!0))return;const t=e.target?.closest(".designbase-wc-rating__star");if(!t||!this.contains(t))return;const s=Number(t.dataset.index);if(!Number.isFinite(s))return;const i=this.getNumberAttr("max-value",5),r=this.getPointerValue(s,e.clientX,t,i);this.hoverValue!==r&&(this.hoverValue=r,this.classList.toggle("designbase-wc-rating--hovering",!0),this.refreshStars(),this.dispatchEvent(new CustomEvent("db-hover",{detail:{value:r},bubbles:!0,composed:!0})))}),this.handlePointerLeave=()=>{null!==this.hoverValue&&(this.hoverValue=null,this.classList.remove("designbase-wc-rating--hovering"),this.refreshStars())},this.handleClick=e=>{if(!this.isInteractive())return;const t=e.target?.closest(".designbase-wc-rating__star");if(!t||!this.contains(t))return;e.preventDefault();const s=Number(t.dataset.index);if(!Number.isFinite(s))return;const i=this.getNumberAttr("max-value",5),r=this.getPointerValue(s,e.clientX,t,i);this.hoverValue=null,this.classList.remove("designbase-wc-rating--hovering"),this.setAttribute("value",String(r)),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:r},bubbles:!0,composed:!0})),this.render()}}static get observedAttributes(){return["value","max-value","size","variant","type","display","review-count","rating-text","review-text","allow-half","readonly","disabled","clickable","color","custom-color","animated","hover-effect"]}connectedCallback(){this.addEventListener("mousemove",this.handlePointerMove),this.addEventListener("mouseleave",this.handlePointerLeave),this.addEventListener("click",this.handleClick),this.render(),this.unsubscribeLocale?.(),this.unsubscribeLocale=e(()=>this.render())}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.removeEventListener("mousemove",this.handlePointerMove),this.removeEventListener("mouseleave",this.handlePointerLeave),this.removeEventListener("click",this.handleClick)}attributeChangedCallback(){this.isConnected&&this.render()}getNumberAttr(e,t){const s=this.getAttribute(e);if(null===s||""===s)return t;const i=Number(s);return Number.isFinite(i)?i:t}getBooleanAttr(e,t=!1){if(!this.hasAttribute(e))return t;const s=this.getAttribute(e);return""===s||"true"===s}getOption(e,t,s){const i=this.getAttribute(e);return i&&t.includes(i)?i:s}normalizeSize(e){return"xs"===e||"s"===e?"s":"xl"===e||"l"===e?"l":"m"===e?"m":a(e,l,"m")}getStarIconSize(){const e=this.normalizeSize(this.getAttribute("size"));return"s"===e?16:"l"===e?24:20}supportsHalfSteps(){return this.getBooleanAttr("allow-half")||this.getBooleanAttr("clickable")}isInteractive(){return this.getBooleanAttr("clickable")&&!this.getBooleanAttr("readonly")&&!this.getBooleanAttr("disabled")}getStarFill(e,t,s){const i=e+1;return t>=i?1:s&&t>=i-.5?.5:0}getPointerValue(e,t,s,i){const r=s.getBoundingClientRect();let a;return a=this.supportsHalfSteps()&&t-r.left<r.width/2?e+.5:e+1,a/5*i}formatRating(e,s,i,r){const a=e/s*5;return"percentage"===i?`${Math.round(e/s*100)}%`:"number"===i?r?a.toFixed(1):String(Math.round(a)):"text"===i?t(a>=4.5?"rating.high":a>=3?"rating.medium":"rating.low"):`${a.toFixed(1)}/5`}updateStarElement(e,t,s,r,a){e.className=["designbase-wc-rating__star",0===t&&"designbase-wc-rating__star--empty",t>0&&a&&"designbase-wc-rating__star--hover-preview",r&&"designbase-wc-rating__star--clickable",this.getBooleanAttr("animated")&&"designbase-wc-rating__star--animated"].filter(Boolean).join(" "),e.dataset.index=String(s);const n=1===t?"star-filled":.5===t?"star-half":"star",o=this.getStarIconSize(),l=e.querySelector("svg");l?.getAttribute("data-designbase-icon")===n&&l.getAttribute("width")===String(o)||e.replaceChildren(i(n,o))}refreshStars(){if(!this.starsEl)return;const e=this.getNumberAttr("value",0),t=this.getNumberAttr("max-value",5),s=this.getBooleanAttr("allow-half",!1),i=this.getBooleanAttr("hover-effect",!0),r=null!==this.hoverValue&&i,a=(r?this.hoverValue:e)/t*5,n=this.isInteractive(),o=s||r,l=Array.from(this.starsEl.querySelectorAll(":scope > .designbase-wc-rating__star"));for(let e=0;e<5;e+=1){const t=this.getStarFill(e,a,o),s=r&&t>0,i=l[e]??document.createElement("span");i.setAttribute("aria-hidden","true"),this.updateStarElement(i,t,e,n,s),l[e]||this.starsEl.append(i)}for(let e=l.length-1;e>=5;e-=1)l[e]?.remove()}render(){const e=this.getNumberAttr("value",0),i=this.getNumberAttr("max-value",5),r=this.normalizeSize(this.getAttribute("size")),a=this.getOption("variant",c,"default"),n=this.getOption("type",g,"star"),o=this.getOption("display",h,"stars"),l=this.getOption("color",u,"primary"),d=this.getNumberAttr("review-count",0),m=this.getBooleanAttr("allow-half",!1),b=this.getBooleanAttr("readonly",!1),v=this.getBooleanAttr("disabled",!1),p=this.getBooleanAttr("clickable",!1),f=this.getBooleanAttr("hover-effect",!0),w=null!==this.hoverValue&&f;this.className=["designbase-wc-rating",`designbase-wc-rating--size-${r}`,`designbase-wc-rating--variant-${a}`,`designbase-wc-rating--type-${n}`,`designbase-wc-rating--display-${o}`,`designbase-wc-rating--color-${l}`,b&&"designbase-wc-rating--readonly",v&&"designbase-wc-rating--disabled",p&&"designbase-wc-rating--clickable",this.getBooleanAttr("animated")&&"designbase-wc-rating--animated",w&&"designbase-wc-rating--hovering"].filter(Boolean).join(" ");const A=this.getAttribute("custom-color");"custom"===l&&A?this.style.setProperty("--rating-color",A):this.style.removeProperty("--rating-color");let _=this.querySelector(':scope > [role="img"]');_||(_=document.createElement("div"),this.replaceChildren(_)),_.setAttribute("role","img"),_.setAttribute("aria-label",t("rating.label").replace("{value}",this.formatRating(e,i,n,m)));if("stars"===o||"both"===o||"detailed"===o){const e=_.querySelectorAll(":scope > .designbase-wc-rating__stars");e.forEach((e,t)=>{t>0&&e.remove()});const t=e[0];t?this.starsEl=t:(this.starsEl=document.createElement("div"),this.starsEl.className="designbase-wc-rating__stars",_.prepend(this.starsEl)),this.refreshStars()}else this.starsEl&&(this.starsEl.remove(),this.starsEl=null);const E=this.getAttribute("rating-text")||this.formatRating(e,i,n,m);let S=_.querySelector(".designbase-wc-rating__number-container");if("number"===o||"both"===o){if(!S){S=document.createElement("div"),S.className="designbase-wc-rating__number-container";const e=document.createElement("span");e.className="designbase-wc-rating__number",S.append(e),_.append(S)}const e=S.querySelector(".designbase-wc-rating__number");e&&(e.textContent=E)}else S?.remove();let y=_.querySelector(".designbase-wc-rating__review-count");if("reviews"===o||"detailed"===o){const e=this.getAttribute("review-text")||(d>0?t(1===d?"rating.review":"rating.reviews").replace("{count}",d.toLocaleString("ko"===s()?"ko-KR":"en-US")):"");e?(y||(y=document.createElement("span"),y.className="designbase-wc-rating__review-count",_.append(y)),y.textContent=e):y?.remove()}else y?.remove()}}customElements.get("db-rating")||customElements.define("db-rating",DbRating);export{DbRating};
@@ -1,4 +1,5 @@
1
1
  declare class DbSearchBar extends HTMLElement {
2
+ private unsubscribeLocale?;
2
3
  static get observedAttributes(): string[];
3
4
  private input?;
4
5
  private clearButton?;
@@ -29,6 +30,7 @@ declare class DbSearchBar extends HTMLElement {
29
30
  private clearSuggestionInterval;
30
31
  private syncSuggestionRolling;
31
32
  private syncPlaceholder;
33
+ private syncLocale;
32
34
  private syncValueState;
33
35
  private syncAttributes;
34
36
  private bindGlobalShortcut;
@@ -1 +1 @@
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
+ import{inheritThemeScope as e}from"../core/theme-scope.js";import{subscribeDbLocale as t,dbText as s,dbFormat as a}from"../core/i18n.js";import{getDbComponentIconSize as r,createDbIcon as n}from"./db-icons.js";import{SEARCH_BAR_SIZES as i,SEARCH_BAR_RECENT_LAYOUTS as o}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 i.includes(e)?e:"m"}getIconPx(){return r(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.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.syncLocale()),this.loadRecentSearches(),this.render(),this.bindGlobalShortcut()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,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(),a=this.getAttribute("placeholder")||s("검색...");e.length>0&&!t?this.input.placeholder=e[this.currentSuggestion]||a:this.input.placeholder=a}syncLocale(){this.syncPlaceholder(),this.input?.setAttribute("aria-label",s("검색어 입력")),this.clearButton?.setAttribute("aria-label",s("검색어 지우기"));const setText=(e,t)=>{const a=this.dropdown?.querySelector(e);a&&(a.textContent=s(t))};setText(".designbase-wc-search-bar__results-empty","검색 결과가 없습니다."),setText(".designbase-wc-search-bar__recent-title","최근 검색어"),setText(".designbase-wc-search-bar__suggestions-title","추천 검색어");const e=this.dropdown?.querySelector(".designbase-wc-search-bar__clear-all-button");e&&(e.textContent=s("전체 삭제"),e.setAttribute("aria-label",s("모든 최근 검색어 삭제"))),this.dropdown?.querySelectorAll(".designbase-wc-search-bar__recent-item").forEach(e=>{const t=e.querySelector(".designbase-wc-search-bar__recent-search-button")?.textContent;t&&e.querySelector(".designbase-wc-search-bar__recent-remove-button")?.setAttribute("aria-label",a("{0} 삭제",[t]))})}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--${i.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"),r=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(r)&&!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 t=this.hasInputValue(),i=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=o.includes(this.getAttribute("recent-searches-layout")||"vertical")&&this.getAttribute("recent-searches-layout")||"vertical";if(i.length>0){const e=document.createElement("div");e.className="designbase-wc-search-bar__categories",i.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(t&&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 t=document.createElement("div");t.className="designbase-wc-search-bar__results-empty",t.textContent=s("검색 결과가 없습니다."),e.append(t)}return this.dropdown.append(e),void this.attachDropdownPortal()}if(this.hasAttribute("enable-recent-searches")&&!t&&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 t=document.createElement("div");t.className="designbase-wc-search-bar__recent-header";const i=document.createElement("span");i.className="designbase-wc-search-bar__recent-title",i.textContent=s("최근 검색어");const o=document.createElement("button");o.type="button",o.className="designbase-wc-search-bar__clear-all-button",o.setAttribute("aria-label",s("모든 최근 검색어 삭제")),o.textContent=s("전체 삭제"),o.addEventListener("mousedown",e=>{e.preventDefault(),this.recentSearches=[];try{localStorage.removeItem(this.getRecentSearchesKey())}catch{}this.updateDropdown()}),t.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 s=document.createElement("button");s.type="button",s.className="designbase-wc-search-bar__recent-search-button",s.textContent=e,s.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",a("{0} 삭제",[e])),i.append(n("close",r("s"))),i.addEventListener("mousedown",t=>{t.preventDefault(),this.recentSearches=this.recentSearches.filter(t=>t!==e),this.saveRecentSearches(),this.updateDropdown()}),t.append(s,i),c.append(t)}),e.append(t,c),this.dropdown.append(e)}if(c.length>0&&!t){const e=document.createElement("div");e.className="designbase-wc-search-bar__suggestions";const t=document.createElement("div");t.className="designbase-wc-search-bar__suggestions-header";const a=document.createElement("span");a.className="designbase-wc-search-bar__suggestions-title",a.textContent=s("추천 검색어"),t.append(a);const r=document.createElement("div");r.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()}),r.append(s)}),e.append(t,r),this.dropdown.append(e)}if(l&&!t&&(!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",t=this.hasAttribute("disabled"),a=this.hasAttribute("readonly"),r=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--${i.includes(e)?e:"m"}`,"pill"===this.getAttribute("appearance")&&"designbase-wc-search-bar--appearance-pill",t&&"designbase-wc-search-bar--disabled",a&&"designbase-wc-search-bar--readonly",r&&"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=t,b.readOnly=a,b.setAttribute("aria-label",s("검색어 입력")),this.input=b,o){const s=document.createElement("db-badge");s.className="designbase-wc-search-bar__shortcut-badge",s.setAttribute("size","l"===e?"m":"s"),s.setAttribute("variant","secondary"),s.setAttribute("type","text"),s.setAttribute("aria-hidden","true"),s.textContent=this.getAttribute("shortcut-label")||"⌘K",s.hidden=h||t||a,this.shortcutBadge=s,l.append(u,b,s)}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",s("검색어 지우기")),p.hidden=!h||t||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{applySectionBlockHeader as e}from"./section-block-header-utils.js";import{syncMarketingBlockHost as t}from"./marketing-block-host-utils.js";import{sanitizeHref as s}from"../core/safe-url.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SECTION_LOGO_CLOUD_VARIANTS as n,SECTION_ALIGNS as a,SECTION_LOGO_CLOUD_SIZES as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const l="designbase-wc-section-logo-cloud";class DbSectionLogoCloud extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["headline","subtitle","description","badge","logos","variant","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}parseLogos(){try{const e=JSON.parse(this.getAttribute("logos")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${l}__inner`,this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header",this.headerEl.innerHTML='\n <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>\n <h2 class="designbase-wc-section-block-header__headline"></h2>\n <p class="designbase-wc-section-block-header__subtitle"></p>\n <p class="designbase-wc-section-block-header__description"></p>\n ',this.contentEl=document.createElement("div"),this.innerEl.append(this.headerEl,this.contentEl),this.append(this.innerEl)}updateUI(){const r=this.getAttribute("headline")||"함께하는 파트너",c=this.getAttribute("subtitle")||"",d=this.getAttribute("description")||"",h=i(this.getAttribute("variant"),n,"grid"),u=this.getAttribute("content-padding")||"m",b=i(this.getAttribute("align"),a,"center"),m=i(this.getAttribute("size"),o,"m"),g=this.parseBadge(),p=this.parseLogos();if(this.className=[l,`${l}--${h}`,`${l}--size-${m}`,`${l}--padding-${u}`].join(" "),t(this,l),this.headerEl&&e(this.headerEl,{headline:r,subtitle:c,description:d,badge:g,align:b}),this.contentEl){if(this.contentEl.replaceChildren(),"marquee"===h){this.contentEl.className=`${l}__marquee`;const e=document.createElement("db-marquee");return e.setAttribute("items",JSON.stringify(p.map(e=>e.label??e.alt))),void this.contentEl.append(e)}this.contentEl.className=`${l}__grid`,p.forEach(e=>{const t=s(e.href,""),i=document.createElement(t?"a":"div");if(i.className=`${l}__item`,t&&i instanceof HTMLAnchorElement&&(i.href=t,i.target="_blank",i.rel="noopener noreferrer"),e.src){const t=document.createElement("img");t.src=e.src,t.alt=e.alt,t.className=`${l}__image`,i.append(t)}else{const t=document.createElement("span");t.className=`${l}__label`,t.textContent=e.label??e.alt,i.append(t)}this.contentEl.append(i)})}}}customElements.get("db-section-logo-cloud")||customElements.define("db-section-logo-cloud",DbSectionLogoCloud);export{DbSectionLogoCloud};
1
+ import{applySectionBlockHeader as e}from"./section-block-header-utils.js";import{syncMarketingBlockHost as t}from"./marketing-block-host-utils.js";import{sanitizeHref as s}from"../core/safe-url.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SECTION_LOGO_CLOUD_VARIANTS as n,SECTION_ALIGNS as a,SECTION_LOGO_CLOUD_SIZES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const l="designbase-wc-section-logo-cloud";class DbSectionLogoCloud extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["headline","subtitle","description","badge","logos","variant","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}parseLogos(){try{const e=JSON.parse(this.getAttribute("logos")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${l}__inner`,this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header",this.headerEl.innerHTML='\n <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>\n <h2 class="designbase-wc-section-block-header__headline"></h2>\n <p class="designbase-wc-section-block-header__subtitle"></p>\n <p class="designbase-wc-section-block-header__description"></p>\n ',this.contentEl=document.createElement("div"),this.innerEl.append(this.headerEl,this.contentEl),this.append(this.innerEl)}updateUI(){const o=this.getAttribute("headline")||"함께하는 파트너",c=this.getAttribute("subtitle")||"",d=this.getAttribute("description")||"",h=i(this.getAttribute("variant"),n,"grid"),u=this.getAttribute("content-padding")||"m",b=i(this.getAttribute("align"),a,"center"),g=i(this.getAttribute("size"),r,"m"),m=this.parseBadge(),p=this.parseLogos();if(this.className=[l,`${l}--${h}`,`${l}--size-${g}`,`${l}--padding-${u}`].join(" "),t(this,l),this.headerEl&&e(this.headerEl,{headline:o,subtitle:c,description:d,badge:m,align:b}),this.contentEl){if(this.contentEl.replaceChildren(),"marquee"===h){this.contentEl.className=`${l}__marquee`;const e=document.createElement("db-marquee");return e.setAttribute("items",JSON.stringify(p.map(e=>e.src?{src:e.src,alt:e.alt,href:e.href,height:48}:e.label??e.alt))),void this.contentEl.append(e)}this.contentEl.className=`${l}__grid`,p.forEach(e=>{const t=s(e.href,""),i=document.createElement(t?"a":"div");if(i.className=`${l}__item`,t&&i instanceof HTMLAnchorElement&&(i.href=t,i.target="_blank",i.rel="noopener noreferrer"),e.src){const t=document.createElement("img");t.src=e.src,t.alt=e.alt,t.className=`${l}__image`,i.append(t)}else{const t=document.createElement("span");t.className=`${l}__label`,t.textContent=e.label??e.alt,i.append(t)}this.contentEl.append(i)})}}}customElements.get("db-section-logo-cloud")||customElements.define("db-section-logo-cloud",DbSectionLogoCloud);export{DbSectionLogoCloud};
@@ -0,0 +1,42 @@
1
+ import './db-button.js';
2
+
3
+ /** Controlled bulk-selection surface. Consumer-owned action DOM is never moved or cloned. */
4
+ declare class DbSelectionBar extends HTMLElement {
5
+ static get observedAttributes(): string[];
6
+ private summary?;
7
+ private status?;
8
+ private clear?;
9
+ private clearText?;
10
+ private observer?;
11
+ private unsubscribe?;
12
+ private visible;
13
+ private origin?;
14
+ private originalSizes;
15
+ private disabledControls;
16
+ get count(): number;
17
+ set count(value: number);
18
+ get placement(): 'inline' | 'floating';
19
+ set placement(value: 'inline' | 'floating');
20
+ private widthLimit;
21
+ get minWidth(): number;
22
+ set minWidth(value: number);
23
+ get maxWidth(): number;
24
+ set maxWidth(value: number);
25
+ get disabled(): boolean;
26
+ set disabled(value: boolean);
27
+ connectedCallback(): void;
28
+ disconnectedCallback(): void;
29
+ attributeChangedCallback(): void;
30
+ private keydown;
31
+ private requestClear;
32
+ private set;
33
+ private restoreControls;
34
+ private sync;
35
+ }
36
+ declare global {
37
+ interface HTMLElementTagNameMap {
38
+ 'db-selection-bar': DbSelectionBar;
39
+ }
40
+ }
41
+
42
+ export { DbSelectionBar };
@@ -0,0 +1 @@
1
+ import"./db-button.js";import{subscribeDbLocale as t,t as e}from"../core/i18n.js";import{dbUid as s}from"../core/uid.js";class DbSelectionBar extends HTMLElement{constructor(){super(...arguments),this.visible=!1,this.originalSizes=new Map,this.disabledControls=new Map,this.keydown=t=>{"Escape"!==t.key||t.defaultPrevented||t.isComposing||t.composedPath().some(t=>t instanceof HTMLElement&&(t.matches('input,textarea,select,[role="textbox"],[role="dialog"],[role^="menu"]')||t.isContentEditable))||this.count&&!this.disabled&&(t.preventDefault(),this.requestClear("escape"))}}static get observedAttributes(){return["count","placement","floating-scope","size","disabled","selection-label","clear-label","min-width","max-width","aria-label"]}get count(){const t=Number(this.getAttribute("count")??0);return Number.isFinite(t)?Math.max(0,Math.floor(t)):0}set count(t){this.setAttribute("count",String(t))}get placement(){return"floating"===this.getAttribute("placement")?"floating":"inline"}set placement(t){this.setAttribute("placement",t)}widthLimit(t,e){const s=this.getAttribute(t);if(!s?.trim())return e;const i=Number(s);return Number.isFinite(i)&&("max-width"===t?i>0:i>=0)?i:e}get minWidth(){return this.widthLimit("min-width",0)}set minWidth(t){this.setAttribute("min-width",String(t))}get maxWidth(){return this.widthLimit("max-width",960)}set maxWidth(t){this.setAttribute("max-width",String(t))}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}connectedCallback(){this.classList.add("designbase-wc-selection-bar"),this.summary||(this.summary=document.createElement("div"),this.summary.className="designbase-wc-selection-bar__summary",this.summary.dataset.selectionBarChrome="",this.summary.id=s("selection-bar"),this.status=document.createElement("span"),this.status.className="designbase-wc-selection-bar__status",this.status.setAttribute("role","status"),this.status.setAttribute("aria-live","polite"),this.status.setAttribute("aria-atomic","true"),this.clear=document.createElement("db-button"),this.clear.setAttribute("variant","tertiary"),this.clearText=document.createElement("span"),this.clear.append(this.clearText),this.clear.addEventListener("db-click",()=>this.requestClear("button")),this.summary.append(this.status,this.clear),this.prepend(this.summary)),this.setAttribute("role","region"),this.addEventListener("keydown",this.keydown),this.sync(),this.observer=new MutationObserver(()=>this.sync()),this.observer.observe(this,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["disabled"]}),this.unsubscribe=t(()=>this.sync())}disconnectedCallback(){this.observer?.disconnect(),this.unsubscribe?.(),this.removeEventListener("keydown",this.keydown),this.restoreControls();for(const[t,e]of this.originalSizes)this.set(t,"size",e);this.originalSizes.clear()}attributeChangedCallback(){this.isConnected&&this.sync()}requestClear(t){!this.disabled&&this.count&&this.dispatchEvent(new CustomEvent("db-clear",{detail:{count:this.count,source:t},bubbles:!0,composed:!0}))}set(t,e,s){null===s?t.hasAttribute(e)&&t.removeAttribute(e):t.getAttribute(e)!==s&&t.setAttribute(e,s)}restoreControls(){for(const[t,e]of this.disabledControls)this.set(t,"disabled",e);this.disabledControls.clear()}sync(){if(!this.summary||!this.status||!this.clear)return;const t=this.count>0;if(t&&!this.visible){const t=this.ownerDocument.activeElement;this.origin=t instanceof HTMLElement&&!this.contains(t)?t:void 0}!t&&this.visible&&this.contains(this.ownerDocument.activeElement)&&this.origin?.isConnected&&this.origin.focus({preventScroll:!0}),this.visible=t,this.set(this,"data-visible",t?"":null),this.set(this,"aria-hidden",t?null:"true"),this.dataset.placement=this.placement,this.style.setProperty("--_db-selection-bar-min-width",this.minWidth+"px"),this.style.setProperty("--_db-selection-bar-max-width",this.maxWidth+"px"),this.dataset.scope="container"===this.getAttribute("floating-scope")?"container":"viewport",this.dataset.size="m"===this.getAttribute("size")?"m":"s";const s=(this.getAttribute("selection-label")||e("selectionBar.count")).split("{count}").join(String(this.count));this.status.textContent!==s&&(this.status.textContent=s);const i=this.getAttribute("clear-label")||e("selectionBar.clear");this.clearText&&this.clearText.textContent!==i&&(this.clearText.textContent=i),this.set(this.clear,"size",this.dataset.size),this.set(this.clear,"disabled",this.disabled?"":null),this.set(this,"aria-description",this.getAttribute("aria-label")?null:e("selectionBar.label")),this.hasAttribute("aria-labelledby")&&this.getAttribute("aria-labelledby")!==this.summary.id||this.set(this,"aria-labelledby",this.hasAttribute("aria-label")?null:this.summary.id),this.set(this.summary,"aria-label",e("selectionBar.label"));const a=[...this.querySelectorAll(':scope > [slot="actions"] db-button, :scope > [slot="actions"] db-select, :scope > [slot="actions"] button')].filter(t=>"button"!==t.localName||!t.closest("db-button,db-select")),r=a.filter(t=>t.matches("db-button,db-select"));for(const[t,e]of this.originalSizes)r.includes(t)||(this.set(t,"size",e),this.originalSizes.delete(t));for(const t of r)this.originalSizes.has(t)||this.originalSizes.set(t,t.getAttribute("size")),this.set(t,"size",this.dataset.size);for(const[t,e]of this.disabledControls)a.includes(t)||(this.set(t,"disabled",e),this.disabledControls.delete(t));if(this.disabled)for(const t of a)this.disabledControls.has(t)||this.disabledControls.set(t,t.getAttribute("disabled")),this.set(t,"disabled","");else this.restoreControls()}}customElements.get("db-selection-bar")||customElements.define("db-selection-bar",DbSelectionBar);export{DbSelectionBar};
@@ -8,8 +8,13 @@ declare class DbShare extends HTMLElement {
8
8
  private modalEl;
9
9
  private contentSlot;
10
10
  private dropdownEl;
11
+ private unsubscribeLocale?;
11
12
  connectedCallback(): void;
12
13
  disconnectedCallback(): void;
14
+ private platformName;
15
+ private platformAriaLabel;
16
+ private copySuccessLabel;
17
+ private syncLocale;
13
18
  private getVariant;
14
19
  private getSize;
15
20
  private getPosition;
@@ -1 +1 @@
1
- import{dbFormat as e,dbText as t}from"../core/i18n.js";import{createShareIcon as s,createSharePlatformIcon as r}from"./db-share-icons.js";import{sanitizeHref as n}from"../core/safe-url.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SHARE_VARIANTS as a,SHARE_SIZES as o,SHARE_POSITIONS as l}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c=["facebook","x","linkedin","whatsapp","email","link"],h={facebook:{name:"Facebook",color:"#1877f2",shareUrl:"https://www.facebook.com/sharer/sharer.php?u={url}"},x:{name:"X",color:"#000000",shareUrl:"https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}"},instagram:{name:"Instagram",color:"#e4405f",shareUrl:"https://www.instagram.com/",customShare:()=>{window.alert("Instagram에 직접 공유하려면 링크를 복사하여 사용하세요.")}},linkedin:{name:"LinkedIn",color:"#0077b5",shareUrl:"https://www.linkedin.com/sharing/share-offsite/?url={url}"},pinterest:{name:"Pinterest",color:"#bd081c",shareUrl:"https://pinterest.com/pin/create/button/?url={url}&description={title}&media={imageUrl}"},whatsapp:{name:"WhatsApp",color:"#25d366",shareUrl:"https://wa.me/?text={title}%20{url}"},telegram:{name:"Telegram",color:"#0088cc",shareUrl:"https://t.me/share/url?url={url}&text={title}"},email:{name:"이메일",color:"#ea4335",shareUrl:"mailto:?subject={title}&body={description}%20{url}"},link:{name:"링크 복사",color:"#6c757d",shareUrl:""},qr:{name:"QR 코드",color:"#6c757d",shareUrl:""}};class DbShare extends HTMLElement{constructor(){super(...arguments),this.isCopied=!1,this.qrCodeData="",this.copyResetTimer=null,this.modalEl=null,this.contentSlot=null,this.dropdownEl=null}static get observedAttributes(){return["url","title","description","image-url","hashtags","variant","size","position","platforms","button-text","modal-title","show-qr-code","qr-code-size","copy-success-message","open"]}connectedCallback(){this.render()}disconnectedCallback(){this.copyResetTimer&&clearTimeout(this.copyResetTimer)}getVariant(){return i(this.getAttribute("variant"),a,"button")}getSize(){return i(this.getAttribute("size"),o,"m")}getPosition(){return i(this.getAttribute("position"),l,"bottom")}attributeChangedCallback(e){"open"===e&&"modal"===this.getVariant()&&this.modalEl?this.syncModalOpen():"url"===e&&this.contentSlot?this.refreshLinkInputValue():this.render()}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(e){e?this.setAttribute("open","true"):this.removeAttribute("open")}parseListAttribute(e){const t=this.getAttribute(e);if(!t)return[];try{const e=JSON.parse(t);if(Array.isArray(e))return e.map(e=>String(e).trim()).filter(Boolean)}catch{}return t.split(",").map(e=>e.trim()).filter(Boolean)}getResolvedUrl(){const e=this.getAttribute("url");return e?n(e,""):"undefined"!=typeof window&&window.location?.href?n(window.location.href,""):""}getContext(){return{url:this.getResolvedUrl(),title:this.getAttribute("share-title")||this.getAttribute("title")||"",description:this.getAttribute("description")||"",imageUrl:this.getAttribute("image-url")||"",hashtags:this.parseListAttribute("hashtags"),host:this}}getActivePlatforms(){const e=this.parseListAttribute("platforms");return(e.length>0?e:c).filter(e=>e in h)}replaceUrlVariables(e,t){return e.replace("{url}",encodeURIComponent(t.url)).replace("{title}",encodeURIComponent(t.title)).replace("{description}",encodeURIComponent(t.description)).replace("{imageUrl}",encodeURIComponent(t.imageUrl)).replace("{hashtags}",t.hashtags.join(","))}async handleCopyLink(e){try{await navigator.clipboard.writeText(e.url),this.isCopied=!0,this.dispatchEvent(new CustomEvent("db-copy-success",{bubbles:!0,composed:!0,detail:{url:e.url}})),this.refreshContent(),this.copyResetTimer&&clearTimeout(this.copyResetTimer),this.copyResetTimer=setTimeout(()=>{this.isCopied=!1,this.refreshContent()},3e3)}catch(e){this.dispatchEvent(new CustomEvent("db-copy-error",{bubbles:!0,composed:!0,detail:{error:e}}))}}handleShowQrCode(e){if(this.qrCodeData=e.url,"modal"===this.getVariant())return this.open=!0,void this.refreshContent();this.refreshContent()}handlePlatformShare(e){const t=this.getContext(),s=h[e];if(s)try{if("link"===e)this.handleCopyLink(t);else if("qr"===e)this.handleShowQrCode(t);else if(s.customShare)s.customShare(t);else if(s.shareUrl){const e=this.replaceUrlVariables(s.shareUrl,t),r=n(e,"");if(!r)throw new Error("Invalid share URL");window.open(r,"_blank","noopener,noreferrer,width=600,height=400")}this.dispatchEvent(new CustomEvent("db-share",{bubbles:!0,composed:!0,detail:{platform:e,url:t.url}}))}catch(t){this.dispatchEvent(new CustomEvent("db-share-error",{bubbles:!0,composed:!0,detail:{platform:e,error:t}}))}}getPlacement(){const e=this.getPosition();return"top"===e||"left"===e?"top-left":"right"===e?"bottom-right":"bottom-left"}mapButtonSize(){const e=this.getSize();return"s"===e?"s":"l"===e?"l":"m"}createTriggerButton(e){const t=document.createElement("db-button");return t.className=e||"designbase-wc-share__trigger",t.setAttribute("variant","secondary"),t.setAttribute("size",this.mapButtonSize()),t.textContent=this.getAttribute("button-text")||"공유",t.prepend(s("share-alt",16)),t.addEventListener("db-click",()=>{"modal"!==this.getVariant()?this.open=!this.open:this.open=!0}),t}createPlatformIcon(e){const t=document.createElement("span");return t.className="designbase-wc-share__platform-icon",t.append(r(e,24)),t}createPlatformButton(r){const n=h[r],i=document.createElement("button");i.type="button",i.className=["designbase-wc-share__platform-button",`designbase-wc-share__platform-button--${r}`,"link"===r&&this.isCopied?"designbase-wc-share__platform-button--copied":""].filter(Boolean).join(" "),i.style.setProperty("--platform-color",n.color),i.title=n.name,i.setAttribute("aria-label",e("{0}에 공유하기",[n.name])),i.append(this.createPlatformIcon(r));const a=document.createElement("span");if(a.className="designbase-wc-share__platform-name",a.textContent=n.name,i.append(a),"link"===r&&this.isCopied){const e=document.createElement("span");e.className="designbase-wc-share__copy-success",e.append(s("copy",12));const r=document.createElement("span");r.textContent=t("복사됨!"),e.append(r),i.append(e)}return i.addEventListener("click",()=>this.handlePlatformShare(r)),i}createLinkInput(e){const t=document.createElement("db-input");return t.className="designbase-wc-share__link-input",t.setAttribute("type","text"),t.setAttribute("readonly",""),t.setAttribute("size","s"),t.setAttribute("full-width",""),t.setAttribute("value",e),customElements.whenDefined("db-input").then(()=>{t.setAttribute("value",e),t.value=e}),t}refreshLinkInputValue(){const e=this.getResolvedUrl(),t=this.contentSlot?.querySelector("db-input.designbase-wc-share__link-input");t&&(t.setAttribute("value",e),t.value=e)}createCopyButton(e){const t=document.createElement("db-button");t.className="designbase-wc-share__copy-button",t.setAttribute("size","s"),t.setAttribute("variant","primary");const r=document.createElement("span");return r.className="designbase-wc-button__start-icon",r.setAttribute("aria-hidden","true"),r.append(s(this.isCopied?"copy":"link",16)),t.append(r),t.append(document.createTextNode(this.isCopied?"복사됨!":"복사")),t.addEventListener("db-click",()=>{this.handleCopyLink(e)}),t}generateQrCodeUrl(){const e=Number(this.getAttribute("qr-code-size")||200);return`https://api.qrserver.com/v1/create-qr-code/?size=${e}x${e}&data=${encodeURIComponent(this.qrCodeData)}`}createShareContent(){const e=document.createElement("div");return e.className="designbase-wc-share__content",this.populateShareContent(e),e}populateShareContent(e){const s=document.createElement("div");s.className="designbase-wc-share__platforms",this.getActivePlatforms().forEach(e=>{s.append(this.createPlatformButton(e))}),e.append(s);if("false"!==this.getAttribute("show-qr-code")&&this.qrCodeData){const s=document.createElement("div");s.className="designbase-wc-share__qr-section";const r=document.createElement("h4");r.className="designbase-wc-share__qr-title",r.textContent=t("QR 코드"),s.append(r);const n=document.createElement("div");n.className="designbase-wc-share__qr-code";const i=document.createElement("img"),a=Number(this.getAttribute("qr-code-size")||200);i.src=this.generateQrCodeUrl(),i.alt="QR Code",i.width=a,i.height=a,n.append(i),s.append(n);const o=document.createElement("p");o.className="designbase-wc-share__qr-description",o.textContent=t("QR 코드를 스캔하여 링크에 접속하세요"),s.append(o),e.append(s)}const r=this.getContext(),n=document.createElement("div");n.className="designbase-wc-share__link-preview";const i=document.createElement("h4");i.className="designbase-wc-share__link-title",i.textContent=t("공유 링크"),n.append(i);const a=document.createElement("div");a.className="designbase-wc-share__link-container",a.append(this.createLinkInput(r.url)),a.append(this.createCopyButton(r)),n.append(a),e.append(n)}refreshContent(){const e=this.getVariant();if("inline"===e){const e=this.querySelector(":scope > .designbase-wc-share__content");return void e?.replaceWith(this.createShareContent())}"modal"===e&&this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}syncModalOpen(){this.modalEl&&(this.open?(this.refreshLinkInputValue(),this.modalEl.setAttribute("open","true")):this.modalEl.removeAttribute("open"))}renderDropdown(){const e=document.createElement("db-dropdown");e.className="designbase-wc-share__dropdown",e.setAttribute("placement",this.getPlacement()),e.setAttribute("label",this.getAttribute("button-text")||"공유"),e.setAttribute("trigger-variant","secondary"),e.setAttribute("trigger-icon","share-alt"),e.setAttribute("size",this.mapButtonSize()),e.setAttribute("items",JSON.stringify(this.getActivePlatforms().map(e=>({id:e,label:h[e].name})))),e.addEventListener("db-change",e=>{const t=e.detail,s=t?.id;s&&this.handlePlatformShare(s)}),this.dropdownEl=e,this.append(e)}renderModal(){const e=this.createTriggerButton();this.append(e);const t=document.createElement("db-modal");t.className="designbase-wc-share__modal",t.setAttribute("title",this.getAttribute("modal-title")||"공유하기"),t.setAttribute("size","m"),this.contentSlot=document.createElement("div"),this.contentSlot.className="designbase-wc-share designbase-wc-share__content",this.contentSlot.setAttribute("data-modal-part","body"),this.populateShareContent(this.contentSlot),t.append(this.contentSlot),t.addEventListener("db-close",()=>{this.open=!1,this.qrCodeData="",this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}),this.modalEl=t,this.append(t),this.syncModalOpen()}render(){const e=this.getVariant();this.className=`designbase-wc-share designbase-wc-share--${e}`,this.replaceChildren(),this.modalEl=null,this.contentSlot=null,this.dropdownEl=null,"inline"!==e?"dropdown"!==e?"modal"!==e?this.append(this.createTriggerButton()):this.renderModal():this.renderDropdown():this.append(this.createShareContent())}}customElements.get("db-share")||customElements.define("db-share",DbShare);export{DbShare};
1
+ import{subscribeDbLocale as t,dbText as e,dbFormat as s}from"../core/i18n.js";import{createShareIcon as r,createSharePlatformIcon as n}from"./db-share-icons.js";import{sanitizeHref as i}from"../core/safe-url.js";import{coerceToContract as a}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SHARE_VARIANTS as o,SHARE_SIZES as l,SHARE_POSITIONS as c}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const h=["facebook","x","linkedin","whatsapp","email","link"],d={facebook:{name:"Facebook",color:"#1877f2",shareUrl:"https://www.facebook.com/sharer/sharer.php?u={url}"},x:{name:"X",color:"#000000",shareUrl:"https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}"},instagram:{name:"Instagram",color:"#e4405f",shareUrl:"https://www.instagram.com/",customShare:()=>{window.alert(e("Instagram에 직접 공유하려면 링크를 복사하여 사용하세요."))}},linkedin:{name:"LinkedIn",color:"#0077b5",shareUrl:"https://www.linkedin.com/sharing/share-offsite/?url={url}"},pinterest:{name:"Pinterest",color:"#bd081c",shareUrl:"https://pinterest.com/pin/create/button/?url={url}&description={title}&media={imageUrl}"},whatsapp:{name:"WhatsApp",color:"#25d366",shareUrl:"https://wa.me/?text={title}%20{url}"},telegram:{name:"Telegram",color:"#0088cc",shareUrl:"https://t.me/share/url?url={url}&text={title}"},email:{name:"이메일",color:"#ea4335",shareUrl:"mailto:?subject={title}&body={description}%20{url}"},link:{name:"링크 복사",color:"#6c757d",shareUrl:""},qr:{name:"QR 코드",color:"#6c757d",shareUrl:""}};class DbShare extends HTMLElement{constructor(){super(...arguments),this.isCopied=!1,this.qrCodeData="",this.copyResetTimer=null,this.modalEl=null,this.contentSlot=null,this.dropdownEl=null}static get observedAttributes(){return["url","title","share-title","description","image-url","hashtags","variant","size","position","platforms","button-text","modal-title","show-qr-code","qr-code-size","copy-success-message","open"]}connectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.syncLocale()),this.render()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.copyResetTimer&&clearTimeout(this.copyResetTimer)}platformName(t){return["email","link","qr"].includes(t)?e(d[t].name):d[t].name}platformAriaLabel(t){return"email"===t?e("이메일로 공유"):"link"===t?e("링크 복사"):"qr"===t?e("QR 코드 보기"):s("{0}에 공유하기",[this.platformName(t)])}copySuccessLabel(){return this.getAttribute("copy-success-message")||e("복사됨!")}syncLocale(){const t=this.contentSlot||this,s=this.querySelector(".designbase-wc-share__trigger"),r=s&&Array.from(s.childNodes).find(t=>t.nodeType===Node.TEXT_NODE);r&&(r.textContent=this.getAttribute("button-text")||e("공유")),this.modalEl&&this.modalEl.setAttribute("title",this.getAttribute("modal-title")||e("공유하기")),t.querySelectorAll("[data-share-platform]").forEach(t=>{const e=t.dataset.sharePlatform,s=this.platformName(e);t.title=s,t.setAttribute("aria-label",this.platformAriaLabel(e));const r=t.querySelector(".designbase-wc-share__platform-name");r&&(r.textContent=s);const n=t.querySelector(".designbase-wc-share__copy-success span");n&&(n.textContent=this.copySuccessLabel())});const n=t.querySelector(".designbase-wc-share__copy-button"),i=n&&Array.from(n.childNodes).find(t=>t.nodeType===Node.TEXT_NODE);i&&(i.textContent=this.isCopied?this.copySuccessLabel():e("복사"));const a=[[".designbase-wc-share__qr-title","QR 코드"],[".designbase-wc-share__qr-description","QR 코드를 스캔하여 링크에 접속하세요"],[".designbase-wc-share__link-title","공유 링크"]];for(const[s,r]of a){const n=t.querySelector(s);n&&(n.textContent=e(r))}if(this.dropdownEl){const t=document.activeElement,s=Array.from(this.dropdownEl.querySelectorAll(".designbase-wc-dropdown__item")).findIndex(e=>e===t||e.contains(t));this.dropdownEl.setAttribute("label",this.getAttribute("button-text")||e("공유")),this.dropdownEl.setAttribute("items",JSON.stringify(this.getActivePlatforms().map(t=>({id:t,label:this.platformName(t)})))),s>=0&&this.dropdownEl.querySelectorAll(".designbase-wc-dropdown__item")[s]?.focus({preventScroll:!0})}}getVariant(){return a(this.getAttribute("variant"),o,"button")}getSize(){return a(this.getAttribute("size"),l,"m")}getPosition(){return a(this.getAttribute("position"),c,"bottom")}attributeChangedCallback(t){"open"===t&&"modal"===this.getVariant()&&this.modalEl?this.syncModalOpen():"url"===t&&this.contentSlot?this.refreshLinkInputValue():this.render()}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open","true"):this.removeAttribute("open")}parseListAttribute(t){const e=this.getAttribute(t);if(!e)return[];try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(t=>String(t).trim()).filter(Boolean)}catch{}return e.split(",").map(t=>t.trim()).filter(Boolean)}getResolvedUrl(){const t=this.getAttribute("url");return t?i(t,""):"undefined"!=typeof window&&window.location?.href?i(window.location.href,""):""}getContext(){return{url:this.getResolvedUrl(),title:this.getAttribute("share-title")||this.getAttribute("title")||"",description:this.getAttribute("description")||"",imageUrl:this.getAttribute("image-url")||"",hashtags:this.parseListAttribute("hashtags"),host:this}}getActivePlatforms(){const t=this.parseListAttribute("platforms");return(t.length>0?t:h).filter(t=>t in d)}replaceUrlVariables(t,e){return t.replace("{url}",encodeURIComponent(e.url)).replace("{title}",encodeURIComponent(e.title)).replace("{description}",encodeURIComponent(e.description)).replace("{imageUrl}",encodeURIComponent(e.imageUrl)).replace("{hashtags}",e.hashtags.join(","))}async handleCopyLink(t){try{await navigator.clipboard.writeText(t.url),this.isCopied=!0,this.dispatchEvent(new CustomEvent("db-copy-success",{bubbles:!0,composed:!0,detail:{url:t.url}})),this.refreshContent(),this.copyResetTimer&&clearTimeout(this.copyResetTimer),this.copyResetTimer=setTimeout(()=>{this.isCopied=!1,this.refreshContent()},3e3)}catch(t){this.dispatchEvent(new CustomEvent("db-copy-error",{bubbles:!0,composed:!0,detail:{error:t}}))}}handleShowQrCode(t){if(this.qrCodeData=t.url,"modal"===this.getVariant())return this.open=!0,void this.refreshContent();this.refreshContent()}handlePlatformShare(t){const e=this.getContext(),s=d[t];if(s)try{if("link"===t)this.handleCopyLink(e);else if("qr"===t)this.handleShowQrCode(e);else if(s.customShare)s.customShare(e);else if(s.shareUrl){const t=this.replaceUrlVariables(s.shareUrl,e),r=i(t,"");if(!r)throw new Error("Invalid share URL");window.open(r,"_blank","noopener,noreferrer,width=600,height=400")}this.dispatchEvent(new CustomEvent("db-share",{bubbles:!0,composed:!0,detail:{platform:t,url:e.url}}))}catch(e){this.dispatchEvent(new CustomEvent("db-share-error",{bubbles:!0,composed:!0,detail:{platform:t,error:e}}))}}getPlacement(){const t=this.getPosition();return"top"===t||"left"===t?"top-left":"right"===t?"bottom-right":"bottom-left"}mapButtonSize(){const t=this.getSize();return"s"===t?"s":"l"===t?"l":"m"}createTriggerButton(t){const s=document.createElement("db-button");return s.className=t||"designbase-wc-share__trigger",s.setAttribute("variant","secondary"),s.setAttribute("size",this.mapButtonSize()),s.textContent=this.getAttribute("button-text")||e("공유"),s.prepend(r("share-alt",16)),s.addEventListener("db-click",()=>{"modal"!==this.getVariant()?this.open=!this.open:this.open=!0}),s}createPlatformIcon(t){const e=document.createElement("span");return e.className="designbase-wc-share__platform-icon",e.append(n(t,24)),e}createPlatformButton(t){const e=d[t],s=document.createElement("button");s.type="button",s.className=["designbase-wc-share__platform-button",`designbase-wc-share__platform-button--${t}`,"link"===t&&this.isCopied?"designbase-wc-share__platform-button--copied":""].filter(Boolean).join(" "),s.style.setProperty("--platform-color",e.color),s.dataset.sharePlatform=t;const n=this.platformName(t);s.title=n,s.setAttribute("aria-label",this.platformAriaLabel(t)),s.append(this.createPlatformIcon(t));const i=document.createElement("span");if(i.className="designbase-wc-share__platform-name",i.textContent=n,s.append(i),"link"===t&&this.isCopied){const t=document.createElement("span");t.className="designbase-wc-share__copy-success",t.append(r("copy",12));const e=document.createElement("span");e.textContent=this.copySuccessLabel(),t.append(e),s.append(t)}return s.addEventListener("click",()=>this.handlePlatformShare(t)),s}createLinkInput(t){const e=document.createElement("db-input");return e.className="designbase-wc-share__link-input",e.setAttribute("type","text"),e.setAttribute("readonly",""),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.setAttribute("value",t),customElements.whenDefined("db-input").then(()=>{e.setAttribute("value",t),e.value=t}),e}refreshLinkInputValue(){const t=this.getResolvedUrl(),e=this.contentSlot?.querySelector("db-input.designbase-wc-share__link-input");e&&(e.setAttribute("value",t),e.value=t)}createCopyButton(t){const s=document.createElement("db-button");s.className="designbase-wc-share__copy-button",s.setAttribute("size","s"),s.setAttribute("variant","primary");const n=document.createElement("span");return n.className="designbase-wc-button__start-icon",n.setAttribute("aria-hidden","true"),n.append(r(this.isCopied?"copy":"link",16)),s.append(n),s.append(document.createTextNode(this.isCopied?this.copySuccessLabel():e("복사"))),s.addEventListener("db-click",()=>{this.handleCopyLink(t)}),s}generateQrCodeUrl(){const t=Number(this.getAttribute("qr-code-size")||200);return`https://api.qrserver.com/v1/create-qr-code/?size=${t}x${t}&data=${encodeURIComponent(this.qrCodeData)}`}createShareContent(){const t=document.createElement("div");return t.className="designbase-wc-share__content",this.populateShareContent(t),t}populateShareContent(t){const s=document.createElement("div");s.className="designbase-wc-share__platforms",this.getActivePlatforms().forEach(t=>{s.append(this.createPlatformButton(t))}),t.append(s);if("false"!==this.getAttribute("show-qr-code")&&this.qrCodeData){const s=document.createElement("div");s.className="designbase-wc-share__qr-section";const r=document.createElement("h4");r.className="designbase-wc-share__qr-title",r.textContent=e("QR 코드"),s.append(r);const n=document.createElement("div");n.className="designbase-wc-share__qr-code";const i=document.createElement("img"),a=Number(this.getAttribute("qr-code-size")||200);i.src=this.generateQrCodeUrl(),i.alt="QR Code",i.width=a,i.height=a,n.append(i),s.append(n);const o=document.createElement("p");o.className="designbase-wc-share__qr-description",o.textContent=e("QR 코드를 스캔하여 링크에 접속하세요"),s.append(o),t.append(s)}const r=this.getContext(),n=document.createElement("div");n.className="designbase-wc-share__link-preview";const i=document.createElement("h4");i.className="designbase-wc-share__link-title",i.textContent=e("공유 링크"),n.append(i);const a=document.createElement("div");a.className="designbase-wc-share__link-container",a.append(this.createLinkInput(r.url)),a.append(this.createCopyButton(r)),n.append(a),t.append(n)}refreshContent(){const t=this.getVariant();if("inline"===t){const t=this.querySelector(":scope > .designbase-wc-share__content");return void t?.replaceWith(this.createShareContent())}"modal"===t&&this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}syncModalOpen(){this.modalEl&&(this.open?(this.refreshLinkInputValue(),this.modalEl.setAttribute("open","true")):this.modalEl.removeAttribute("open"))}renderDropdown(){const t=document.createElement("db-dropdown");t.className="designbase-wc-share__dropdown",t.setAttribute("placement",this.getPlacement()),t.setAttribute("label",this.getAttribute("button-text")||e("공유")),t.setAttribute("trigger-variant","secondary"),t.setAttribute("trigger-icon","share-alt"),t.setAttribute("size",this.mapButtonSize()),t.setAttribute("items",JSON.stringify(this.getActivePlatforms().map(t=>({id:t,label:this.platformName(t)})))),t.addEventListener("db-change",t=>{const e=t.detail,s=e?.id;s&&this.handlePlatformShare(s)}),this.dropdownEl=t,this.append(t)}renderModal(){const t=this.createTriggerButton();this.append(t);const s=document.createElement("db-modal");s.className="designbase-wc-share__modal",s.setAttribute("title",this.getAttribute("modal-title")||e("공유하기")),s.setAttribute("size","m"),this.contentSlot=document.createElement("div"),this.contentSlot.className="designbase-wc-share designbase-wc-share__content",this.contentSlot.setAttribute("data-modal-part","body"),this.populateShareContent(this.contentSlot),s.append(this.contentSlot),s.addEventListener("db-close",()=>{this.open=!1,this.qrCodeData="",this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}),this.modalEl=s,this.append(s),this.syncModalOpen()}render(){const t=this.getVariant();this.className=`designbase-wc-share designbase-wc-share--${t}`,this.replaceChildren(),this.modalEl=null,this.contentSlot=null,this.dropdownEl=null,"inline"!==t?"dropdown"!==t?"modal"!==t?this.append(this.createTriggerButton()):this.renderModal():this.renderDropdown():this.append(this.createShareContent())}}customElements.get("db-share")||customElements.define("db-share",DbShare);export{DbShare};
@@ -73,6 +73,7 @@ interface DbSidebarUpdateBanner {
73
73
  variant?: 'primary' | 'secondary' | 'tertiary' | 'outline';
74
74
  }
75
75
  declare class DbSidebar extends HTMLElement {
76
+ private autoAriaLabel?;
76
77
  private expandedItems;
77
78
  private userMenuOpen;
78
79
  private projectMenuOpen;
@@ -92,7 +93,9 @@ declare class DbSidebar extends HTMLElement {
92
93
  private createCustomNavSlot;
93
94
  private projectCustomNavSlots;
94
95
  static get observedAttributes(): string[];
96
+ private unsubscribeLocale?;
95
97
  connectedCallback(): void;
98
+ private syncAccessibleName;
96
99
  disconnectedCallback(): void;
97
100
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
98
101
  private bindPanelMediaQuery;