@designbasekorea/ui-wc 0.9.4 → 0.11.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 (182) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE-WORLD-MAP.md +10 -0
  3. package/README.md +60 -0
  4. package/dist/esm/components/db-accordion.d.ts +22 -10
  5. package/dist/esm/components/db-accordion.js +1 -1
  6. package/dist/esm/components/db-achievement-list.d.ts +2 -0
  7. package/dist/esm/components/db-achievement-list.js +1 -1
  8. package/dist/esm/components/db-activity-heatmap.d.ts +1 -0
  9. package/dist/esm/components/db-activity-heatmap.js +1 -1
  10. package/dist/esm/components/db-ad-banner.d.ts +2 -0
  11. package/dist/esm/components/db-ad-banner.js +1 -1
  12. package/dist/esm/components/db-ai-chat-list.d.ts +5 -1
  13. package/dist/esm/components/db-ai-chat-list.js +1 -1
  14. package/dist/esm/components/db-ai-chat.d.ts +2 -0
  15. package/dist/esm/components/db-ai-chat.js +1 -1
  16. package/dist/esm/components/db-ai-file-tree.js +1 -1
  17. package/dist/esm/components/db-alert.d.ts +1 -0
  18. package/dist/esm/components/db-alert.js +1 -1
  19. package/dist/esm/components/db-audio-player.d.ts +2 -0
  20. package/dist/esm/components/db-audio-player.js +1 -1
  21. package/dist/esm/components/db-avatar.d.ts +1 -0
  22. package/dist/esm/components/db-avatar.js +1 -1
  23. package/dist/esm/components/db-banner.d.ts +2 -0
  24. package/dist/esm/components/db-banner.js +1 -1
  25. package/dist/esm/components/db-button.d.ts +40 -2
  26. package/dist/esm/components/db-button.js +1 -1
  27. package/dist/esm/components/db-calendar.d.ts +5 -0
  28. package/dist/esm/components/db-calendar.js +1 -1
  29. package/dist/esm/components/db-card.d.ts +1 -0
  30. package/dist/esm/components/db-card.js +1 -1
  31. package/dist/esm/components/db-chat-composer.d.ts +3 -0
  32. package/dist/esm/components/db-chat-composer.js +1 -1
  33. package/dist/esm/components/db-chat-message.d.ts +2 -0
  34. package/dist/esm/components/db-chat-message.js +1 -1
  35. package/dist/esm/components/db-chat-orb.d.ts +13 -0
  36. package/dist/esm/components/db-chat-orb.js +1 -1
  37. package/dist/esm/components/db-chat-room.d.ts +1 -0
  38. package/dist/esm/components/db-chat-room.js +1 -1
  39. package/dist/esm/components/db-chat-typing.d.ts +2 -0
  40. package/dist/esm/components/db-chat-typing.js +1 -1
  41. package/dist/esm/components/db-chat-widget.d.ts +9 -0
  42. package/dist/esm/components/db-chat-widget.js +1 -1
  43. package/dist/esm/components/db-checkbox.d.ts +3 -0
  44. package/dist/esm/components/db-checkbox.js +1 -1
  45. package/dist/esm/components/db-chip.d.ts +2 -0
  46. package/dist/esm/components/db-chip.js +1 -1
  47. package/dist/esm/components/db-code-block.d.ts +1 -0
  48. package/dist/esm/components/db-code-block.js +1 -1
  49. package/dist/esm/components/db-color-picker.d.ts +4 -0
  50. package/dist/esm/components/db-color-picker.js +1 -1
  51. package/dist/esm/components/db-color-swatch.d.ts +3 -0
  52. package/dist/esm/components/db-color-swatch.js +1 -1
  53. package/dist/esm/components/db-confetti.d.ts +11 -5
  54. package/dist/esm/components/db-confetti.js +1 -1
  55. package/dist/esm/components/db-cookie-banner.d.ts +3 -0
  56. package/dist/esm/components/db-cookie-banner.js +1 -1
  57. package/dist/esm/components/db-countdown.d.ts +2 -1
  58. package/dist/esm/components/db-countdown.js +1 -1
  59. package/dist/esm/components/db-date-picker.d.ts +3 -0
  60. package/dist/esm/components/db-date-picker.js +1 -1
  61. package/dist/esm/components/db-dropdown.d.ts +1 -0
  62. package/dist/esm/components/db-dropdown.js +1 -1
  63. package/dist/esm/components/db-dropzone.d.ts +2 -0
  64. package/dist/esm/components/db-dropzone.js +1 -1
  65. package/dist/esm/components/db-email-verify.d.ts +37 -7
  66. package/dist/esm/components/db-email-verify.js +1 -1
  67. package/dist/esm/components/db-file-uploader.d.ts +2 -0
  68. package/dist/esm/components/db-file-uploader.js +1 -1
  69. package/dist/esm/components/db-floating-action-button.d.ts +1 -1
  70. package/dist/esm/components/db-floating-action-button.js +1 -1
  71. package/dist/esm/components/db-form.d.ts +2 -0
  72. package/dist/esm/components/db-form.js +1 -1
  73. package/dist/esm/components/db-gantt.d.ts +2 -0
  74. package/dist/esm/components/db-gantt.js +1 -1
  75. package/dist/esm/components/db-image-list.d.ts +3 -0
  76. package/dist/esm/components/db-image-list.js +1 -1
  77. package/dist/esm/components/db-image.d.ts +1 -0
  78. package/dist/esm/components/db-image.js +1 -1
  79. package/dist/esm/components/db-input-group.d.ts +30 -0
  80. package/dist/esm/components/db-input-group.js +1 -0
  81. package/dist/esm/components/db-input.d.ts +9 -1
  82. package/dist/esm/components/db-input.js +1 -1
  83. package/dist/esm/components/db-kanban.d.ts +3 -0
  84. package/dist/esm/components/db-kanban.js +1 -1
  85. package/dist/esm/components/db-lightbox.d.ts +2 -0
  86. package/dist/esm/components/db-lightbox.js +1 -1
  87. package/dist/esm/components/db-list.d.ts +2 -0
  88. package/dist/esm/components/db-list.js +1 -1
  89. package/dist/esm/components/db-markdown-editor.d.ts +2 -0
  90. package/dist/esm/components/db-markdown-editor.js +1 -1
  91. package/dist/esm/components/db-menu-item.js +1 -1
  92. package/dist/esm/components/db-navbar.d.ts +6 -0
  93. package/dist/esm/components/db-navbar.js +1 -1
  94. package/dist/esm/components/db-node.d.ts +1 -0
  95. package/dist/esm/components/db-node.js +1 -1
  96. package/dist/esm/components/db-onboarding-modal.d.ts +2 -0
  97. package/dist/esm/components/db-onboarding-modal.js +1 -1
  98. package/dist/esm/components/db-otp-input.d.ts +4 -1
  99. package/dist/esm/components/db-otp-input.js +1 -1
  100. package/dist/esm/components/db-page-header.d.ts +11 -0
  101. package/dist/esm/components/db-page-header.js +1 -1
  102. package/dist/esm/components/db-phone-verify.d.ts +33 -11
  103. package/dist/esm/components/db-phone-verify.js +1 -1
  104. package/dist/esm/components/db-popover.d.ts +1 -0
  105. package/dist/esm/components/db-popover.js +1 -1
  106. package/dist/esm/components/db-progress-step.d.ts +2 -0
  107. package/dist/esm/components/db-progress-step.js +1 -1
  108. package/dist/esm/components/db-radio.d.ts +3 -0
  109. package/dist/esm/components/db-radio.js +1 -1
  110. package/dist/esm/components/db-range-slider.d.ts +36 -7
  111. package/dist/esm/components/db-range-slider.js +1 -1
  112. package/dist/esm/components/db-rating.d.ts +1 -0
  113. package/dist/esm/components/db-rating.js +1 -1
  114. package/dist/esm/components/db-search-bar.d.ts +2 -0
  115. package/dist/esm/components/db-search-bar.js +1 -1
  116. package/dist/esm/components/db-section-logo-cloud.js +1 -1
  117. package/dist/esm/components/db-select.d.ts +35 -6
  118. package/dist/esm/components/db-select.js +1 -1
  119. package/dist/esm/components/db-share.d.ts +5 -0
  120. package/dist/esm/components/db-share.js +1 -1
  121. package/dist/esm/components/db-sidebar.d.ts +3 -0
  122. package/dist/esm/components/db-sidebar.js +1 -1
  123. package/dist/esm/components/db-signature.d.ts +2 -0
  124. package/dist/esm/components/db-signature.js +1 -1
  125. package/dist/esm/components/db-spinner.d.ts +2 -0
  126. package/dist/esm/components/db-spinner.js +1 -1
  127. package/dist/esm/components/db-stepper.d.ts +2 -0
  128. package/dist/esm/components/db-stepper.js +1 -1
  129. package/dist/esm/components/db-table.d.ts +2 -0
  130. package/dist/esm/components/db-table.js +1 -1
  131. package/dist/esm/components/db-tabs.d.ts +37 -13
  132. package/dist/esm/components/db-tabs.js +1 -1
  133. package/dist/esm/components/db-textarea.d.ts +13 -1
  134. package/dist/esm/components/db-textarea.js +1 -1
  135. package/dist/esm/components/db-ticket.js +1 -1
  136. package/dist/esm/components/db-time-picker.d.ts +2 -0
  137. package/dist/esm/components/db-time-picker.js +1 -1
  138. package/dist/esm/components/db-timeline.d.ts +4 -0
  139. package/dist/esm/components/db-timeline.js +1 -1
  140. package/dist/esm/components/db-toast.d.ts +2 -0
  141. package/dist/esm/components/db-toast.js +1 -1
  142. package/dist/esm/components/db-toggle.d.ts +33 -4
  143. package/dist/esm/components/db-toggle.js +1 -1
  144. package/dist/esm/components/db-tool-layout.d.ts +92 -0
  145. package/dist/esm/components/db-tool-layout.js +1 -0
  146. package/dist/esm/components/db-tool-panel.d.ts +50 -0
  147. package/dist/esm/components/db-tool-panel.js +1 -0
  148. package/dist/esm/components/db-top-banner.d.ts +2 -0
  149. package/dist/esm/components/db-top-banner.js +1 -1
  150. package/dist/esm/components/db-two-factor.d.ts +35 -12
  151. package/dist/esm/components/db-two-factor.js +1 -1
  152. package/dist/esm/components/db-video-player.d.ts +3 -0
  153. package/dist/esm/components/db-video-player.js +1 -1
  154. package/dist/esm/components/db-world-map.d.ts +60 -0
  155. package/dist/esm/components/db-world-map.js +1 -0
  156. package/dist/esm/components/db-youtube-player.d.ts +2 -0
  157. package/dist/esm/components/db-youtube-player.js +1 -1
  158. package/dist/esm/components/db-zoom-control.d.ts +52 -0
  159. package/dist/esm/components/db-zoom-control.js +1 -0
  160. package/dist/esm/components/input-validation.js +1 -1
  161. package/dist/esm/components/paper-card.d.ts +2 -0
  162. package/dist/esm/components/paper-card.js +1 -1
  163. package/dist/esm/core/control-label.js +1 -0
  164. package/dist/esm/core/i18n-copy.js +1 -1
  165. package/dist/esm/core/i18n-en.js +1 -1
  166. package/dist/esm/core/i18n.d.ts +31 -1
  167. package/dist/esm/core/i18n.js +1 -1
  168. package/dist/esm/core/range-values.js +1 -0
  169. package/dist/esm/core/text-field-state.js +1 -0
  170. package/dist/esm/helpers/world-countries.js +1 -0
  171. package/dist/esm/helpers/world-land.js +1 -0
  172. package/dist/esm/index.d.ts +6 -1
  173. package/dist/esm/index.js +1 -1
  174. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  175. package/dist/index.cjs +1 -1
  176. package/dist/index.css +1 -1
  177. package/dist/index.d.ts +804 -83
  178. package/dist/index.esm.js +1 -1
  179. package/dist/react/index.cjs +1 -1
  180. package/dist/react/index.d.ts +6211 -648
  181. package/dist/react/index.esm.js +1 -1
  182. package/package.json +9 -4
@@ -4,6 +4,7 @@ declare class DbCodeBlock extends HTMLElement {
4
4
  private renderToken;
5
5
  private internalActiveId;
6
6
  private copied;
7
+ private unsubscribeLocale?;
7
8
  private copyTimeout?;
8
9
  private editedCodes;
9
10
  connectedCallback(): void;
@@ -1 +1 @@
1
- import{setHostClasses as e}from"../core/host-class.js";import{dbFormat as t}from"../core/i18n.js";import{ensureHighlightReady as i,highlightCodeSync as s,formatLanguageLabel as o}from"./highlight-code.js";const n="designbase-wc-code-block";class DbCodeBlock extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.renderToken=0,this.internalActiveId="",this.copied=!1,this.editedCodes={},this.handleSegmentChange=e=>{const t=e,i=t.detail?.value;i&&(this.hasAttribute("active-id")||(this.internalActiveId=i),this.dispatchEvent(new CustomEvent("db-active-id-change",{detail:{activeId:i},bubbles:!0,composed:!0})),this.render())}}static get observedAttributes(){return["items","code","language","default-active-id","active-id","show-language","highlight","theme","show-copy","copied-label","copy-label","min-height","max-height","overflow","editable"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.internalActiveId=this.getAttribute("default-active-id")||this.getResolvedItems()[0]?.id||""),this.render(),i().then(()=>{this.isConnected&&this.built&&this.render()}),this.addEventListener("db-change",this.handleSegmentChange)}disconnectedCallback(){this.removeEventListener("db-change",this.handleSegmentChange),this.copyTimeout&&window.clearTimeout(this.copyTimeout)}attributeChangedCallback(e){if(this.built)if("active-id"!==e){if("items"===e||"code"===e||"language"===e){const e=this.getResolvedItems();e.find(e=>e.id===this.getActiveId())||(this.internalActiveId=e[0]?.id||"")}this.render()}else this.render()}getBool(e,t=!0){if(!this.hasAttribute(e))return t;const i=this.getAttribute(e);return""===i||"true"===i}getResolvedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length>0)return t}catch{}const t=this.getAttribute("code");if(t){const e=this.getAttribute("language")||"tsx";return[{id:"default",label:e,code:t,language:e}]}return[]}getActiveId(){return this.getAttribute("active-id")||this.internalActiveId}getActiveItem(){const e=this.getResolvedItems();return e.find(e=>e.id===this.getActiveId())||e[0]}toCssSize(e){if(e)return/^\d+$/.test(e)?`${e}px`:e}async handleCopy(){const e=this.getActiveItem(),t=this.getBool("editable",!1),i=(t?this.editedCodes[e?.id??""]??e?.code:e?.code)?.trim();if(i){try{await navigator.clipboard.writeText(i)}catch{const e=document.createElement("textarea");e.value=i,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}this.copied=!0,this.render(),this.copyTimeout&&window.clearTimeout(this.copyTimeout),this.copyTimeout=window.setTimeout(()=>{this.copied=!1,this.render()},1600)}}render(){const e=++this.renderToken;this.renderNow(e)}renderNow(i){const d=this.getActiveItem();if(!d)return void this.replaceChildren();const c=this.getResolvedItems(),a=c.length>1,r=this.getAttribute("language")||"tsx",l=d.language??r,h=this.getBool("show-language",!0),u=this.getBool("highlight",!0),m=this.getAttribute("theme")||"auto",b=this.getBool("show-copy",!0),g=this.getAttribute("copied-label")||"복사됨",p=this.getAttribute("copy-label")||"복사",v=this.getAttribute("overflow")||"scroll-x",A=this.getBool("editable",!1),y=A?this.editedCodes[d.id]??d.code:d.code,f=y.trim();let C=null;if(u&&y)try{C=s(y,l)}catch{C=null}if(i!==this.renderToken)return;const E=this.toCssSize(this.getAttribute("min-height")),_=this.toCssSize(this.getAttribute("max-height"));E?this.style.setProperty("--db-code-block-min-height",E):this.style.removeProperty("--db-code-block-min-height"),_?this.style.setProperty("--db-code-block-max-height",_):this.style.removeProperty("--db-code-block-max-height"),e(this,[n,`${n}--overflow-${v}`,"auto"!==m&&`${n}--theme-${m}`,A&&`${n}--editable`]);const x=document.createElement("div");x.className=`${n}__toolbar`;const $=document.createElement("div");if($.className=`${n}__toolbar-left`,a){const e=document.createElement("db-segment-control");e.setAttribute("size","s"),e.setAttribute("options",JSON.stringify(c.map(e=>({value:e.id,label:e.label})))),e.setAttribute("value",this.getActiveId()),$.append(e)}if(h){const e=document.createElement("span");e.className=`${n}__language`,e.textContent=o(l),$.append(e)}if(x.append($),b){const e=document.createElement("db-button");e.setAttribute("type","button"),e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("start-icon",this.copied?"done":"copy"),e.textContent=this.copied?g:p,e.addEventListener("db-click",()=>this.handleCopy()),x.append(e)}const w=document.createElement("div");if(w.className=`${n}__body`,a&&d.description){const e=document.createElement("p");e.className=`${n}__caption`,e.textContent=d.description,w.append(e)}if(A){void 0===this.editedCodes[d.id]&&(this.editedCodes[d.id]=d.code);const e=document.createElement("div");e.className=`${n}__editor`;const i=document.createElement("pre");i.className=`${n}__pre ${n}__pre--mirror`,i.setAttribute("aria-hidden","true");const c=document.createElement("code");c.className=`${n}__code language-${l}`,C?c.innerHTML=C:c.textContent=y,i.append(c);const a=document.createElement("textarea");a.className=`${n}__textarea`,a.value=y,a.spellcheck=!1,a.setAttribute("autocapitalize","off"),a.setAttribute("autocorrect","off"),a.setAttribute("aria-label",t("{0} 코드 편집",[o(l)])),a.addEventListener("input",()=>{this.editedCodes[d.id]=a.value;const e=u&&a.value?s(a.value,l):null;e?c.innerHTML=e:c.textContent=a.value,this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:a.value,itemId:d.id},bubbles:!0,composed:!0}))}),e.append(i,a),w.append(e)}else{const e=document.createElement("pre");e.className=`${n}__pre`;const t=document.createElement("code");t.className=`${n}__code language-${l}`,C?t.innerHTML=C:t.textContent=f,e.append(t),w.append(e)}this.replaceChildren(x,w)}}customElements.get("db-code-block")||customElements.define("db-code-block",DbCodeBlock);export{DbCodeBlock};
1
+ import{setHostClasses as e}from"../core/host-class.js";import{subscribeDbLocale as t,dbText as i,dbFormat as s}from"../core/i18n.js";import{formatLanguageLabel as o,ensureHighlightReady as n,highlightCodeSync as c}from"./highlight-code.js";const a="designbase-wc-code-block";class DbCodeBlock extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.renderToken=0,this.internalActiveId="",this.copied=!1,this.editedCodes={},this.handleSegmentChange=e=>{const t=e,i=t.detail?.value;i&&(this.hasAttribute("active-id")||(this.internalActiveId=i),this.dispatchEvent(new CustomEvent("db-active-id-change",{detail:{activeId:i},bubbles:!0,composed:!0})),this.render())}}static get observedAttributes(){return["items","code","language","default-active-id","active-id","show-language","highlight","theme","show-copy","copied-label","copy-label","min-height","max-height","overflow","editable"]}connectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>{const e=this.querySelector(`.${a}__copy-button`);e&&(e.textContent=this.copied?this.getAttribute("copied-label")||i("복사됨"):this.getAttribute("copy-label")||i("복사"));const t=this.querySelector(`.${a}__textarea`),n=this.getActiveItem();t&&n&&t.setAttribute("aria-label",s("{0} 코드 편집",[o(n.language??this.getAttribute("language")??"tsx")]))}),this.style.display="block",this.built||(this.built=!0,this.internalActiveId=this.getAttribute("default-active-id")||this.getResolvedItems()[0]?.id||""),this.render(),n().then(()=>{this.isConnected&&this.built&&this.render()}),this.addEventListener("db-change",this.handleSegmentChange)}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.removeEventListener("db-change",this.handleSegmentChange),this.copyTimeout&&window.clearTimeout(this.copyTimeout)}attributeChangedCallback(e){if(this.built)if("active-id"!==e){if("items"===e||"code"===e||"language"===e){const e=this.getResolvedItems();e.find(e=>e.id===this.getActiveId())||(this.internalActiveId=e[0]?.id||"")}this.render()}else this.render()}getBool(e,t=!0){if(!this.hasAttribute(e))return t;const i=this.getAttribute(e);return""===i||"true"===i}getResolvedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length>0)return t}catch{}const t=this.getAttribute("code");if(t){const e=this.getAttribute("language")||"tsx";return[{id:"default",label:e,code:t,language:e}]}return[]}getActiveId(){return this.getAttribute("active-id")||this.internalActiveId}getActiveItem(){const e=this.getResolvedItems();return e.find(e=>e.id===this.getActiveId())||e[0]}toCssSize(e){if(e)return/^\d+$/.test(e)?`${e}px`:e}async handleCopy(){const e=this.getActiveItem(),t=this.getBool("editable",!1),i=(t?this.editedCodes[e?.id??""]??e?.code:e?.code)?.trim();if(i){try{await navigator.clipboard.writeText(i)}catch{const e=document.createElement("textarea");e.value=i,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}this.copied=!0,this.render(),this.copyTimeout&&window.clearTimeout(this.copyTimeout),this.copyTimeout=window.setTimeout(()=>{this.copied=!1,this.render()},1600)}}render(){const e=++this.renderToken;this.renderNow(e)}renderNow(t){const n=this.getActiveItem();if(!n)return void this.replaceChildren();const d=this.getResolvedItems(),r=d.length>1,l=this.getAttribute("language")||"tsx",h=n.language??l,u=this.getBool("show-language",!0),b=this.getBool("highlight",!0),m=this.getAttribute("theme")||"auto",g=this.getBool("show-copy",!0),p=this.getAttribute("copied-label")||i("복사됨"),v=this.getAttribute("copy-label")||i("복사"),A=this.getAttribute("overflow")||"scroll-x",y=this.getBool("editable",!1),f=y?this.editedCodes[n.id]??n.code:n.code,C=f.trim();let _=null;if(b&&f)try{_=c(f,h)}catch{_=null}if(t!==this.renderToken)return;const x=this.toCssSize(this.getAttribute("min-height")),E=this.toCssSize(this.getAttribute("max-height"));x?this.style.setProperty("--db-code-block-min-height",x):this.style.removeProperty("--db-code-block-min-height"),E?this.style.setProperty("--db-code-block-max-height",E):this.style.removeProperty("--db-code-block-max-height"),e(this,[a,`${a}--overflow-${A}`,"auto"!==m&&`${a}--theme-${m}`,y&&`${a}--editable`]);const $=document.createElement("div");$.className=`${a}__toolbar`;const w=document.createElement("div");if(w.className=`${a}__toolbar-left`,r){const e=document.createElement("db-segment-control");e.setAttribute("size","s"),e.setAttribute("options",JSON.stringify(d.map(e=>({value:e.id,label:e.label})))),e.setAttribute("value",this.getActiveId()),w.append(e)}if(u){const e=document.createElement("span");e.className=`${a}__language`,e.textContent=o(h),w.append(e)}if($.append(w),g){const e=document.createElement("db-button");e.className=`${a}__copy-button`,e.setAttribute("type","button"),e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("start-icon",this.copied?"done":"copy"),e.textContent=this.copied?p:v,e.addEventListener("db-click",()=>this.handleCopy()),$.append(e)}const I=document.createElement("div");if(I.className=`${a}__body`,r&&n.description){const e=document.createElement("p");e.className=`${a}__caption`,e.textContent=n.description,I.append(e)}if(y){void 0===this.editedCodes[n.id]&&(this.editedCodes[n.id]=n.code);const e=document.createElement("div");e.className=`${a}__editor`;const t=document.createElement("pre");t.className=`${a}__pre ${a}__pre--mirror`,t.setAttribute("aria-hidden","true");const i=document.createElement("code");i.className=`${a}__code language-${h}`,_?i.innerHTML=_:i.textContent=f,t.append(i);const d=document.createElement("textarea");d.className=`${a}__textarea`,d.value=f,d.spellcheck=!1,d.setAttribute("autocapitalize","off"),d.setAttribute("autocorrect","off"),d.setAttribute("aria-label",s("{0} 코드 편집",[o(h)])),d.addEventListener("input",()=>{this.editedCodes[n.id]=d.value;const e=b&&d.value?c(d.value,h):null;e?i.innerHTML=e:i.textContent=d.value,this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:d.value,itemId:n.id},bubbles:!0,composed:!0}))}),e.append(t,d),I.append(e)}else{const e=document.createElement("pre");e.className=`${a}__pre`;const t=document.createElement("code");t.className=`${a}__code language-${h}`,_?t.innerHTML=_:t.textContent=C,e.append(t),I.append(e)}this.replaceChildren($,I)}}customElements.get("db-code-block")||customElements.define("db-code-block",DbCodeBlock);export{DbCodeBlock};
@@ -1,4 +1,7 @@
1
1
  declare class DbColorPicker extends HTMLElement {
2
+ private unsubscribeLocale?;
3
+ private cancelButton?;
4
+ private applyButton?;
2
5
  private h;
3
6
  private s;
4
7
  private v;
@@ -42,6 +45,7 @@ declare class DbColorPicker extends HTMLElement {
42
45
  static get observedAttributes(): string[];
43
46
  connectedCallback(): void;
44
47
  disconnectedCallback(): void;
48
+ private updateLocale;
45
49
  attributeChangedCallback(name: string): void;
46
50
  private getBool;
47
51
  private getOption;
@@ -1 +1 @@
1
- import{dbText as t}from"../core/i18n.js";import{hexToRgb as e,rgbToHsv as i,hsvToRgb as s,toHex as l,rgbToHsl as n,formatColor as o,normalizeHex as r,isHex as a,clamp as h}from"./color-picker-utils.js";import{getDbComponentIconSize as d,createDbIcon as p}from"./db-icons.js";import{rafThrottle as u}from"../core/dom.js";import{coerceToContract as c}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_PICKER_SIZES as g,COLOR_PICKER_POSITIONS as m}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const E=g,b=["dropdown","modal"],v=["input","swatch"],y=m,I="#006FFF",w=e(I)??{r:0,g:111,b:255},A=i(w.r,w.g,w.b),C=JSON.stringify([{label:"HEX",value:"hex"},{label:"RGB",value:"rgb"},{label:"RGBA",value:"rgba"},{label:"HSL",value:"hsl"},{label:"HSLA",value:"hsla"}]);class DbColorPicker extends HTMLElement{constructor(){super(...arguments),this.h=A.h,this.s=A.s,this.v=A.v,this.a=100,this.open=!1,this.format="hex",this.colorInput=I,this.alphaInput="100",this.isCopied=!1,this.tempColor="",this.dragging=null,this.mounted=!1,this.copiedTimer=null,this.debounceTimer=null,this.lastEmittedHex="",this.suppressNextValueSync=!1,this.didMount=!1,this.triggerInputFocused=!1,this.panelInputFocused=!1,this.panelAlphaInputFocused=!1,this.handleEscape=t=>{"Escape"!==t.key||t.defaultPrevented||t.isComposing||!this.open||"dropdown"===this.getOption("type",b,"dropdown")&&(t.preventDefault(),this.close(),this.toggleBtn?.focus())},this.handleOutsideClick=t=>{if(!this.open||"dropdown"!==this.getOption("type",b,"dropdown"))return;const e=t.target;this.contains(e)||this.formatSelectEl?.contains(e)||(this.open=!1,this.update())},this.handleDocumentMouseMove=u(t=>{"area"===this.dragging&&(this.getBool("disabled")||this.getBool("readonly")||this.updateFromArea(t.clientX,t.clientY))}),this.handleDocumentMouseUp=()=>{"area"===this.dragging&&(this.dragging=null,this.onColorStateChanged(!0))},this.handleModalCancel=()=>{const t=e(this.tempColor);if(t){const e=i(t.r,t.g,t.b);this.h=e.h,this.s=e.s,this.v=e.v}this.open=!1,this.update(),this.dispatchEvent(new CustomEvent("db-cancel",{bubbles:!0,composed:!0}))},this.handleModalApply=()=>{this.open=!1,this.actuallyEmit(),this.dispatchEvent(new CustomEvent("db-apply",{detail:{value:this.getOutward()},bubbles:!0,composed:!0})),this.update()}}static get observedAttributes(){return["size","type","trigger","position","value","default-value","show-input","show-alpha","show-format-selector","show-copy-button","show-eyedropper","disabled","readonly","full-width","error","on-change-format","change-debounce-ms","emit-during-drag"]}connectedCallback(){this.mounted||this.mount(),this.syncFromValueAttr(!0),this.update(),document.addEventListener("mousedown",this.handleOutsideClick),document.addEventListener("mousemove",this.handleDocumentMouseMove),document.addEventListener("mouseup",this.handleDocumentMouseUp),document.addEventListener("keydown",this.handleEscape)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleOutsideClick),document.removeEventListener("mousemove",this.handleDocumentMouseMove),document.removeEventListener("mouseup",this.handleDocumentMouseUp),document.removeEventListener("keydown",this.handleEscape),this.copiedTimer&&clearTimeout(this.copiedTimer),this.debounceTimer&&clearTimeout(this.debounceTimer)}attributeChangedCallback(t){this.mounted&&("value"!==t&&"default-value"!==t||this.syncFromValueAttr(!1),this.update())}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const i=this.getAttribute(t);return""===i||"true"===i}getOption(t,e,i){return c(this.getAttribute(t),e,i)}getIconSize(){return d(this.getOption("size",E,"m"))}getRgb(){return s(this.h,this.s,this.v)}getHex(){const t=this.getRgb();return l(t.r,t.g,t.b)}getHsl(){const t=this.getRgb();return n(t.r,t.g,t.b)}getUiFormatted(){const t=this.getRgb(),e=this.getHex(),i=this.getHsl();return o(this.format,t,e,i,this.a)}getOutward(){return"hex"===("ui"===this.getAttribute("on-change-format")?"ui":"hex")?this.getHex():this.getUiFormatted()}syncFromValueAttr(t){const s=this.getAttribute("value")??(t?this.getAttribute("default-value"):null)??(t?I:null);if(null==s)return;const l=r(s);if(!a(l))return;if(!t&&this.suppressNextValueSync&&l===this.lastEmittedHex)return void(this.suppressNextValueSync=!1);const n=e(l);if(!n)return;const o=i(n.r,n.g,n.b);this.h=o.h,this.s=o.s,this.v=o.v,this.colorInput=l,this.lastEmittedHex=l}actuallyEmit(){const t=r(this.getHex()),e=this.hasAttribute("value")&&a(this.getAttribute("value")||"")?r(this.getAttribute("value")||""):null;e&&e===t||this.lastEmittedHex!==t&&(this.lastEmittedHex=t,this.suppressNextValueSync=!0,this.setAttribute("value",t),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:this.getOutward()},bubbles:!0,composed:!0})))}scheduleEmit(){const t=this.getBool("emit-during-drag",!0);if(this.dragging&&!t)return;const e=Number(this.getAttribute("change-debounce-ms")||"0");if(e>0)return this.debounceTimer&&clearTimeout(this.debounceTimer),void(this.debounceTimer=setTimeout(()=>this.actuallyEmit(),e));this.actuallyEmit()}onColorStateChanged(t=!1){this.didMount?(!t||this.getBool("emit-during-drag",!0),this.scheduleEmit()):this.didMount=!0}updateFromArea(t,e){const i=this.colorFieldEl;if(!i)return;const s=i.getBoundingClientRect(),l=h(t-s.left,0,s.width),n=h(e-s.top,0,s.height);this.s=l/s.width*100,this.v=100-n/s.height*100,this.updateVisuals(),this.onColorStateChanged()}getInputValue(t){return t?t.getAttribute("value")??"":""}setInputValue(t,e){t&&void 0!==e&&t.setAttribute("value",e)}getPanelControlSize(){return"s"===this.getOption("size",E,"m")?"s":"m"}commitColorInput(t){const s="trigger"===t?this.triggerInputEl?.value??"":this.getInputValue(this.panelValueInputEl),l=s.trim();if(/^#([0-9A-Fa-f]{6})$/.test(l)){const t=e(l),s=i(t.r,t.g,t.b);return this.h=s.h,this.s=s.s,this.v=s.v,this.colorInput=r(l),this.updateVisuals(),void this.onColorStateChanged()}let n=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i.exec(s);if(n){const t=h(parseInt(n[1],10),0,255),e=h(parseInt(n[2],10),0,255),s=h(parseInt(n[3],10),0,255),l=i(t,e,s);return this.h=l.h,this.s=l.s,this.v=l.v,this.colorInput=`rgb(${t}, ${e}, ${s})`,this.updateVisuals(),void this.onColorStateChanged()}if(n=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+)\s*\)$/i.exec(l),n){const t=h(parseInt(n[1],10),0,255),e=h(parseInt(n[2],10),0,255),s=h(parseInt(n[3],10),0,255),l=parseFloat(n[4]),o=i(t,e,s);this.h=o.h,this.s=o.s,this.v=o.v,this.a=Math.round(100*l),this.alphaInput=String(this.a),this.colorInput=`rgba(${t}, ${e}, ${s}, ${l})`,this.updateVisuals(),this.onColorStateChanged()}}commitAlphaInput(){const t=Number(this.getInputValue(this.panelAlphaInputEl).trim()||this.alphaInput);if(!Number.isNaN(t)&&t>=0&&t<=100){const e=Math.round(t);this.a=e,this.alphaInput=String(e),this.updateVisuals(),this.onColorStateChanged()}else this.alphaInput=String(this.a),this.panelAlphaInputEl&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput)}async onCopy(){try{await navigator.clipboard.writeText(this.getUiFormatted()),this.isCopied=!0,this.updateCopyButtons(),this.copiedTimer&&clearTimeout(this.copiedTimer),this.copiedTimer=setTimeout(()=>{this.isCopied=!1,this.updateCopyButtons()},1600)}catch{}}async onEyedrop(){try{if("EyeDropper"in window){const t=new window.EyeDropper,{sRGBHex:s}=await t.open(),l=e(s);if(!l)return;const n=i(l.r,l.g,l.b);this.h=n.h,this.s=n.s,this.v=n.v,this.updateVisuals(),this.onColorStateChanged()}}catch{}}toggleOpen(){if(this.getBool("disabled")||this.getBool("readonly"))return;if("modal"===this.getOption("type",b,"dropdown"))return this.tempColor=this.getHex(),this.open=!0,void this.update();this.open=!this.open,this.update()}close(){this.open&&"dropdown"===this.getOption("type",b,"dropdown")&&(this.open=!1,this.update())}mount(){this.mounted=!0;const e=this.getIconSize();this.triggerEl=document.createElement("div"),this.triggerEl.className="designbase-wc-color-picker__trigger",this.triggerEl.addEventListener("click",()=>this.toggleOpen());const i=document.createElement("div");i.className="designbase-wc-color-picker__color-display",this.colorBoxEl=document.createElement("div"),this.colorBoxEl.className="designbase-wc-color-picker__color-box",i.append(this.colorBoxEl),this.triggerInputEl=document.createElement("input"),this.triggerInputEl.type="text",this.triggerInputEl.className="designbase-wc-color-picker__input",this.triggerInputEl.placeholder="#000000",this.triggerInputEl.addEventListener("click",t=>t.stopPropagation()),this.triggerInputEl.addEventListener("focus",()=>{this.triggerInputFocused=!0}),this.triggerInputEl.addEventListener("blur",()=>{this.triggerInputFocused=!1;const t="hex"===this.format?r(this.getUiFormatted()):this.getUiFormatted();this.triggerInputEl&&this.triggerInputEl.value!==t&&(this.triggerInputEl.value=t,this.colorInput=t)}),this.triggerInputEl.addEventListener("input",()=>{this.triggerInputEl&&(this.colorInput=this.triggerInputEl.value)}),this.triggerInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitColorInput("trigger")});const s=document.createElement("div");s.className="designbase-wc-color-picker__trigger-actions",this.triggerCopyBtn=document.createElement("button"),this.triggerCopyBtn.type="button",this.triggerCopyBtn.className="designbase-wc-color-picker__copy-button-inline",this.triggerCopyBtn.setAttribute("aria-label","Copy color value"),this.triggerCopyBtn.addEventListener("click",t=>{t.stopPropagation(),this.onCopy()}),this.toggleBtn=document.createElement("button"),this.toggleBtn.type="button",this.toggleBtn.className="designbase-wc-color-picker__toggle",this.toggleBtn.setAttribute("aria-label","Toggle color picker"),this.toggleBtn.append(p("chevron-down",e)),s.append(this.triggerCopyBtn,this.toggleBtn),this.triggerEl.append(i,this.triggerInputEl,s),this.dropdownEl=document.createElement("div"),this.dropdownEl.className="designbase-wc-color-picker__dropdown",this.dropdownEl.addEventListener("click",t=>t.stopPropagation()),this.dropdownEl.hidden=!0;const l=document.createElement("div");l.className="designbase-wc-color-picker__selector";const n=document.createElement("div");n.className="designbase-wc-color-picker__color-area",this.colorFieldEl=document.createElement("div"),this.colorFieldEl.className="designbase-wc-color-picker__color-field",this.colorPointerEl=document.createElement("div"),this.colorPointerEl.className="designbase-wc-color-picker__color-pointer",this.colorFieldEl.append(this.colorPointerEl),this.colorFieldEl.addEventListener("mousedown",t=>{this.getBool("disabled")||this.getBool("readonly")||(t.preventDefault(),this.dragging="area",this.updateFromArea(t.clientX,t.clientY))}),this.colorFieldEl.addEventListener("touchstart",t=>{if(this.getBool("disabled")||this.getBool("readonly"))return;this.dragging="area";const e=t.touches[0];this.updateFromArea(e.clientX,e.clientY)},{passive:!0}),this.colorFieldEl.addEventListener("touchmove",t=>{if("area"!==this.dragging)return;const e=t.touches[0];this.updateFromArea(e.clientX,e.clientY)},{passive:!0}),this.colorFieldEl.addEventListener("touchend",()=>{"area"===this.dragging&&(this.dragging=null,this.onColorStateChanged(!0))}),n.append(this.colorFieldEl);const o=document.createElement("div");o.className="designbase-wc-color-picker__controls",this.eyedropperBtnEl=document.createElement("db-button"),this.eyedropperBtnEl.setAttribute("variant","tertiary"),this.eyedropperBtnEl.setAttribute("size",this.getPanelControlSize()),this.eyedropperBtnEl.setAttribute("icon-only",""),this.eyedropperBtnEl.setAttribute("start-icon","eyedropper"),this.eyedropperBtnEl.setAttribute("aria-label","Eyedropper tool"),this.eyedropperBtnEl.addEventListener("click",()=>{this.onEyedrop()});const a=document.createElement("div");a.className="designbase-wc-color-picker__slider-container";const d=document.createElement("div");d.className="designbase-wc-color-picker__hue-slider",this.hueSliderEl=document.createElement("input"),this.hueSliderEl.type="range",this.hueSliderEl.min="0",this.hueSliderEl.max="360",this.hueSliderEl.className="designbase-wc-color-picker__slider designbase-wc-color-picker__slider--hue",this.hueSliderEl.addEventListener("input",()=>{this.h=parseFloat(this.hueSliderEl.value),this.updateVisuals(),this.onColorStateChanged()}),d.append(this.hueSliderEl),this.alphaSliderWrapEl=document.createElement("div"),this.alphaSliderWrapEl.className="designbase-wc-color-picker__alpha-slider",this.alphaSliderEl=document.createElement("input"),this.alphaSliderEl.type="range",this.alphaSliderEl.min="0",this.alphaSliderEl.max="100",this.alphaSliderEl.className="designbase-wc-color-picker__slider designbase-wc-color-picker__slider--alpha",this.alphaSliderEl.addEventListener("input",()=>{this.a=h(parseInt(this.alphaSliderEl.value,10),0,100),this.alphaInput=String(this.a),this.panelAlphaInputEl&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput),this.updateVisuals(),this.onColorStateChanged()}),this.alphaSliderWrapEl.append(this.alphaSliderEl),a.append(d,this.alphaSliderWrapEl),o.append(this.eyedropperBtnEl,a);const u=document.createElement("div");u.className="designbase-wc-color-picker__value-display",this.formatSelectEl=document.createElement("db-select"),this.formatSelectEl.setAttribute("size","s"),this.formatSelectEl.setAttribute("position","top"),this.formatSelectEl.setAttribute("show-clear-button","false"),this.formatSelectEl.setAttribute("options",C),this.formatSelectEl.addEventListener("db-change",t=>{const e=t.detail,i=e?.value;i&&(this.format=i,this.updateVisuals())}),this.panelValueInputEl=document.createElement("db-input"),this.panelValueInputEl.classList.add("designbase-wc-color-picker__value-input"),this.panelValueInputEl.setAttribute("size","s"),this.panelValueInputEl.setAttribute("placeholder","#000000"),this.panelValueInputEl.addEventListener("db-focus",()=>{this.panelInputFocused=!0}),this.panelValueInputEl.addEventListener("db-blur",()=>{this.panelInputFocused=!1;const t="hex"===this.format?r(this.getUiFormatted()):this.getUiFormatted();this.getInputValue(this.panelValueInputEl)!==t&&(this.setInputValue(this.panelValueInputEl,t),this.colorInput=t)}),this.panelValueInputEl.addEventListener("db-input",t=>{const e=t.detail;void 0!==e?.value&&(this.colorInput=e.value)}),this.panelValueInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitColorInput("panel")}),this.panelAlphaWrapEl=document.createElement("div"),this.panelAlphaWrapEl.className="designbase-wc-color-picker__alpha-input-wrap",this.panelAlphaInputEl=document.createElement("db-input"),this.panelAlphaInputEl.classList.add("designbase-wc-color-picker__alpha-input"),this.panelAlphaInputEl.setAttribute("size","s"),this.panelAlphaInputEl.setAttribute("placeholder","100"),this.panelAlphaInputEl.setAttribute("aria-label","Alpha percent"),this.panelAlphaInputEl.addEventListener("db-focus",()=>{this.panelAlphaInputFocused=!0}),this.panelAlphaInputEl.addEventListener("db-blur",()=>{this.panelAlphaInputFocused=!1,this.commitAlphaInput()}),this.panelAlphaInputEl.addEventListener("db-input",t=>{const e=t.detail,i=(e?.value??"").replace(/[^\d]/g,"").slice(0,3);i!==e?.value&&this.setInputValue(this.panelAlphaInputEl,i),this.alphaInput=i}),this.panelAlphaInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitAlphaInput()});const c=document.createElement("span");c.className="designbase-wc-color-picker__alpha-suffix",c.textContent="%",this.panelAlphaWrapEl.append(this.panelAlphaInputEl,c),this.panelCopyBtnEl=document.createElement("db-button"),this.panelCopyBtnEl.setAttribute("variant","tertiary"),this.panelCopyBtnEl.setAttribute("size","s"),this.panelCopyBtnEl.setAttribute("icon-only",""),this.panelCopyBtnEl.setAttribute("start-icon","copy"),this.panelCopyBtnEl.setAttribute("aria-label","Copy color value"),this.panelCopyBtnEl.addEventListener("click",()=>{this.onCopy()}),u.append(this.formatSelectEl,this.panelValueInputEl,this.panelAlphaWrapEl,this.panelCopyBtnEl),l.append(n,o,u),this.selectorEl=l,this.dropdownEl.append(l),this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","s"),this.modalEl.setAttribute("title",t("색상 선택")),this.modalEl.setAttribute("close-on-escape","true"),this.modalEl.addEventListener("db-close",this.handleModalCancel),this.modalBodyEl=document.createElement("div"),this.modalBodyEl.className="designbase-wc-modal__body designbase-wc-color-picker__modal-body",this.modalBodyEl.setAttribute("data-modal-part","body");const g=document.createElement("div");g.className="designbase-wc-modal__footer",g.setAttribute("data-modal-part","footer");const m=document.createElement("db-button");m.setAttribute("variant","tertiary"),m.setAttribute("size","m"),m.textContent=t("취소"),m.addEventListener("click",this.handleModalCancel);const E=document.createElement("db-button");E.setAttribute("variant","primary"),E.setAttribute("size","m"),E.textContent=t("적용"),E.addEventListener("click",this.handleModalApply),g.append(m,E),this.modalEl.append(this.modalBodyEl,g),this.replaceChildren(this.triggerEl,this.dropdownEl,this.modalEl)}updateCopyButtons(){const t=this.getIconSize(),e=this.isCopied?"done":"copy";this.triggerCopyBtn&&this.triggerCopyBtn.replaceChildren(p(e,t)),this.panelCopyBtnEl&&this.panelCopyBtnEl.setAttribute("start-icon",e)}updateVisuals(){const t=this.getRgb(),e=this.getHex(),i=this.getBool("show-alpha",!0),s=this.getUiFormatted(),l="hex"===this.format?r(s):s;!this.triggerInputFocused&&this.triggerInputEl&&(this.triggerInputEl.value=l),!this.panelInputFocused&&this.panelValueInputEl&&this.setInputValue(this.panelValueInputEl,l),this.colorBoxEl&&(this.colorBoxEl.style.backgroundColor=i?`rgba(${t.r}, ${t.g}, ${t.b}, ${this.a/100})`:e),this.colorFieldEl&&(this.colorFieldEl.style.backgroundImage=`\n linear-gradient(to top, rgba(0,0,0,1), rgba(0,0,0,0)),\n linear-gradient(to right, #ffffff, hsl(${this.h}, 100%, 50%))\n `),this.colorPointerEl&&(this.colorPointerEl.style.left=`${this.s}%`,this.colorPointerEl.style.top=100-this.v+"%",this.colorPointerEl.style.backgroundColor=`rgb(${t.r}, ${t.g}, ${t.b})`),this.hueSliderEl&&(this.hueSliderEl.value=String(this.h),this.hueSliderEl.style.background="linear-gradient(to right,\n hsl(0,100%,50%),\n hsl(60,100%,50%),\n hsl(120,100%,50%),\n hsl(180,100%,50%),\n hsl(240,100%,50%),\n hsl(300,100%,50%),\n hsl(360,100%,50%))"),this.alphaSliderEl&&(this.alphaSliderEl.value=String(this.a),this.alphaSliderEl.style.backgroundImage=`\n linear-gradient(45deg, var(--db-border-base) 25%, transparent 25%),\n linear-gradient(-45deg, var(--db-border-base) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--db-border-base) 75%),\n linear-gradient(-45deg, transparent 75%, var(--db-border-base) 75%),\n linear-gradient(to right, rgba(${t.r}, ${t.g}, ${t.b}, 0), rgba(${t.r}, ${t.g}, ${t.b}, 1))\n `,this.alphaSliderEl.style.backgroundSize="8px 8px,8px 8px,8px 8px,8px 8px,100% 100%",this.alphaSliderEl.style.backgroundPosition="0 0,0 4px,4px -4px,-4px 0,0 0",this.alphaSliderEl.style.backgroundColor="var(--db-surface-base)"),this.panelAlphaInputEl&&!this.panelAlphaInputFocused&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput),this.formatSelectEl&&this.formatSelectEl.getAttribute("value")!==this.format&&this.formatSelectEl.setAttribute("value",this.format),this.colorInput=l}update(){if(!this.mounted)return;const t=this.getOption("size",E,"m"),e=this.getOption("type",b,"dropdown"),i=this.getOption("position",y,"bottom-start"),s=this.getBool("disabled"),l=this.getBool("readonly"),n=this.getBool("show-input",!0),o=this.getBool("show-alpha",!0),r=this.getBool("show-format-selector",!0),a=this.getBool("show-copy-button",!0),h=this.getBool("show-eyedropper",!0),d="undefined"!=typeof window&&"EyeDropper"in window,p=this.getOption("trigger",v,"input"),u="swatch"===p;if(this.className=["designbase-wc-color-picker",`designbase-wc-color-picker--${t}`,`designbase-wc-color-picker--${i}`,`designbase-wc-color-picker--trigger-${p}`,this.open&&"dropdown"===e&&"designbase-wc-color-picker--open",this.getBool("full-width")&&"designbase-wc-color-picker--full-width",this.getBool("error")&&"designbase-wc-color-picker--error",s&&"designbase-wc-color-picker--disabled",l&&"designbase-wc-color-picker--readonly",!n&&"designbase-wc-color-picker--no-input"].filter(Boolean).join(" "),this.triggerInputEl?.setAttribute("aria-invalid",String(this.getBool("error"))),this.triggerInputEl&&(this.triggerInputEl.hidden=u||!n,this.triggerInputEl.disabled=s,this.triggerInputEl.readOnly=l),this.triggerCopyBtn&&(this.triggerCopyBtn.hidden=u||!(n&&a),this.triggerCopyBtn.disabled=s),this.toggleBtn&&(this.toggleBtn.hidden=u,this.toggleBtn.disabled=s),this.dropdownEl&&(this.dropdownEl.className=`designbase-wc-color-picker__dropdown designbase-wc-color-picker__dropdown--${i}`,this.dropdownEl.hidden=!("dropdown"===e&&this.open)),this.alphaSliderWrapEl&&(this.alphaSliderWrapEl.hidden=!o),this.panelAlphaWrapEl&&(this.panelAlphaWrapEl.hidden=!o),this.formatSelectEl&&(this.formatSelectEl.hidden=!r),this.panelCopyBtnEl&&(this.panelCopyBtnEl.hidden=!a),this.eyedropperBtnEl&&(this.eyedropperBtnEl.hidden=!(h&&d)),this.selectorEl){const t="modal"===e?this.modalBodyEl:this.dropdownEl;t&&this.selectorEl.parentElement!==t&&t.append(this.selectorEl)}this.modalEl&&("modal"===e&&this.open?this.modalEl.setAttribute("open","true"):this.modalEl.removeAttribute("open")),this.updateCopyButtons(),this.updateVisuals()}}customElements.get("db-color-picker")||customElements.define("db-color-picker",DbColorPicker);export{DbColorPicker};
1
+ import{subscribeDbLocale as t,dbText as e}from"../core/i18n.js";import{hexToRgb as i,rgbToHsv as s,hsvToRgb as l,toHex as n,rgbToHsl as o,formatColor as a,normalizeHex as r,isHex as h,clamp as d}from"./color-picker-utils.js";import{getDbComponentIconSize as p,createDbIcon as u}from"./db-icons.js";import{rafThrottle as c}from"../core/dom.js";import{coerceToContract as g}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_PICKER_SIZES as E,COLOR_PICKER_POSITIONS as m}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const b=E,v=["dropdown","modal"],y=["input","swatch"],I=m,w="#006FFF",A=i(w)??{r:0,g:111,b:255},C=s(A.r,A.g,A.b),B=JSON.stringify([{label:"HEX",value:"hex"},{label:"RGB",value:"rgb"},{label:"RGBA",value:"rgba"},{label:"HSL",value:"hsl"},{label:"HSLA",value:"hsla"}]);class DbColorPicker extends HTMLElement{constructor(){super(...arguments),this.h=C.h,this.s=C.s,this.v=C.v,this.a=100,this.open=!1,this.format="hex",this.colorInput=w,this.alphaInput="100",this.isCopied=!1,this.tempColor="",this.dragging=null,this.mounted=!1,this.copiedTimer=null,this.debounceTimer=null,this.lastEmittedHex="",this.suppressNextValueSync=!1,this.didMount=!1,this.triggerInputFocused=!1,this.panelInputFocused=!1,this.panelAlphaInputFocused=!1,this.handleEscape=t=>{"Escape"!==t.key||t.defaultPrevented||t.isComposing||!this.open||"dropdown"===this.getOption("type",v,"dropdown")&&(t.preventDefault(),this.close(),this.toggleBtn?.focus())},this.handleOutsideClick=t=>{if(!this.open||"dropdown"!==this.getOption("type",v,"dropdown"))return;const e=t.target;this.contains(e)||this.formatSelectEl?.contains(e)||(this.open=!1,this.update())},this.handleDocumentMouseMove=c(t=>{"area"===this.dragging&&(this.getBool("disabled")||this.getBool("readonly")||this.updateFromArea(t.clientX,t.clientY))}),this.handleDocumentMouseUp=()=>{"area"===this.dragging&&(this.dragging=null,this.onColorStateChanged(!0))},this.handleModalCancel=()=>{const t=i(this.tempColor);if(t){const e=s(t.r,t.g,t.b);this.h=e.h,this.s=e.s,this.v=e.v}this.open=!1,this.update(),this.dispatchEvent(new CustomEvent("db-cancel",{bubbles:!0,composed:!0}))},this.handleModalApply=()=>{this.open=!1,this.actuallyEmit(),this.dispatchEvent(new CustomEvent("db-apply",{detail:{value:this.getOutward()},bubbles:!0,composed:!0})),this.update()}}static get observedAttributes(){return["size","type","trigger","position","value","default-value","show-input","show-alpha","show-format-selector","show-copy-button","show-eyedropper","disabled","readonly","full-width","error","on-change-format","change-debounce-ms","emit-during-drag"]}connectedCallback(){this.mounted||this.mount(),this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.updateLocale()),this.updateLocale(),this.syncFromValueAttr(!0),this.update(),document.addEventListener("mousedown",this.handleOutsideClick),document.addEventListener("mousemove",this.handleDocumentMouseMove),document.addEventListener("mouseup",this.handleDocumentMouseUp),document.addEventListener("keydown",this.handleEscape)}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,document.removeEventListener("mousedown",this.handleOutsideClick),document.removeEventListener("mousemove",this.handleDocumentMouseMove),document.removeEventListener("mouseup",this.handleDocumentMouseUp),document.removeEventListener("keydown",this.handleEscape),this.copiedTimer&&clearTimeout(this.copiedTimer),this.debounceTimer&&clearTimeout(this.debounceTimer)}updateLocale(){this.triggerCopyBtn?.setAttribute("aria-label",e("색상 값 복사")),this.toggleBtn?.setAttribute("aria-label",e("색상 선택기 열기 또는 닫기")),this.eyedropperBtnEl?.setAttribute("aria-label",e("스포이드 도구")),this.panelAlphaInputEl?.setAttribute("aria-label",e("불투명도 백분율")),this.panelCopyBtnEl?.setAttribute("aria-label",e("색상 값 복사")),this.modalEl?.setAttribute("title",e("색상 선택")),this.cancelButton&&(this.cancelButton.textContent=e("취소")),this.applyButton&&(this.applyButton.textContent=e("적용"))}attributeChangedCallback(t){this.mounted&&("value"!==t&&"default-value"!==t||this.syncFromValueAttr(!1),this.update())}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const i=this.getAttribute(t);return""===i||"true"===i}getOption(t,e,i){return g(this.getAttribute(t),e,i)}getIconSize(){return p(this.getOption("size",b,"m"))}getRgb(){return l(this.h,this.s,this.v)}getHex(){const t=this.getRgb();return n(t.r,t.g,t.b)}getHsl(){const t=this.getRgb();return o(t.r,t.g,t.b)}getUiFormatted(){const t=this.getRgb(),e=this.getHex(),i=this.getHsl();return a(this.format,t,e,i,this.a)}getOutward(){return"hex"===("ui"===this.getAttribute("on-change-format")?"ui":"hex")?this.getHex():this.getUiFormatted()}syncFromValueAttr(t){const e=this.getAttribute("value")??(t?this.getAttribute("default-value"):null)??(t?w:null);if(null==e)return;const l=r(e);if(!h(l))return;if(!t&&this.suppressNextValueSync&&l===this.lastEmittedHex)return void(this.suppressNextValueSync=!1);const n=i(l);if(!n)return;const o=s(n.r,n.g,n.b);this.h=o.h,this.s=o.s,this.v=o.v,this.colorInput=l,this.lastEmittedHex=l}actuallyEmit(){const t=r(this.getHex()),e=this.hasAttribute("value")&&h(this.getAttribute("value")||"")?r(this.getAttribute("value")||""):null;e&&e===t||this.lastEmittedHex!==t&&(this.lastEmittedHex=t,this.suppressNextValueSync=!0,this.setAttribute("value",t),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:this.getOutward()},bubbles:!0,composed:!0})))}scheduleEmit(){const t=this.getBool("emit-during-drag",!0);if(this.dragging&&!t)return;const e=Number(this.getAttribute("change-debounce-ms")||"0");if(e>0)return this.debounceTimer&&clearTimeout(this.debounceTimer),void(this.debounceTimer=setTimeout(()=>this.actuallyEmit(),e));this.actuallyEmit()}onColorStateChanged(t=!1){this.didMount?(!t||this.getBool("emit-during-drag",!0),this.scheduleEmit()):this.didMount=!0}updateFromArea(t,e){const i=this.colorFieldEl;if(!i)return;const s=i.getBoundingClientRect(),l=d(t-s.left,0,s.width),n=d(e-s.top,0,s.height);this.s=l/s.width*100,this.v=100-n/s.height*100,this.updateVisuals(),this.onColorStateChanged()}getInputValue(t){return t?t.getAttribute("value")??"":""}setInputValue(t,e){t&&void 0!==e&&t.setAttribute("value",e)}getPanelControlSize(){return"s"===this.getOption("size",b,"m")?"s":"m"}commitColorInput(t){const e="trigger"===t?this.triggerInputEl?.value??"":this.getInputValue(this.panelValueInputEl),l=e.trim();if(/^#([0-9A-Fa-f]{6})$/.test(l)){const t=i(l),e=s(t.r,t.g,t.b);return this.h=e.h,this.s=e.s,this.v=e.v,this.colorInput=r(l),this.updateVisuals(),void this.onColorStateChanged()}let n=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i.exec(e);if(n){const t=d(parseInt(n[1],10),0,255),e=d(parseInt(n[2],10),0,255),i=d(parseInt(n[3],10),0,255),l=s(t,e,i);return this.h=l.h,this.s=l.s,this.v=l.v,this.colorInput=`rgb(${t}, ${e}, ${i})`,this.updateVisuals(),void this.onColorStateChanged()}if(n=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+)\s*\)$/i.exec(l),n){const t=d(parseInt(n[1],10),0,255),e=d(parseInt(n[2],10),0,255),i=d(parseInt(n[3],10),0,255),l=parseFloat(n[4]),o=s(t,e,i);this.h=o.h,this.s=o.s,this.v=o.v,this.a=Math.round(100*l),this.alphaInput=String(this.a),this.colorInput=`rgba(${t}, ${e}, ${i}, ${l})`,this.updateVisuals(),this.onColorStateChanged()}}commitAlphaInput(){const t=Number(this.getInputValue(this.panelAlphaInputEl).trim()||this.alphaInput);if(!Number.isNaN(t)&&t>=0&&t<=100){const e=Math.round(t);this.a=e,this.alphaInput=String(e),this.updateVisuals(),this.onColorStateChanged()}else this.alphaInput=String(this.a),this.panelAlphaInputEl&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput)}async onCopy(){try{await navigator.clipboard.writeText(this.getUiFormatted()),this.isCopied=!0,this.updateCopyButtons(),this.copiedTimer&&clearTimeout(this.copiedTimer),this.copiedTimer=setTimeout(()=>{this.isCopied=!1,this.updateCopyButtons()},1600)}catch{}}async onEyedrop(){try{if("EyeDropper"in window){const t=new window.EyeDropper,{sRGBHex:e}=await t.open(),l=i(e);if(!l)return;const n=s(l.r,l.g,l.b);this.h=n.h,this.s=n.s,this.v=n.v,this.updateVisuals(),this.onColorStateChanged()}}catch{}}toggleOpen(){if(this.getBool("disabled")||this.getBool("readonly"))return;if("modal"===this.getOption("type",v,"dropdown"))return this.tempColor=this.getHex(),this.open=!0,void this.update();this.open=!this.open,this.update()}close(){this.open&&"dropdown"===this.getOption("type",v,"dropdown")&&(this.open=!1,this.update())}mount(){this.mounted=!0;const t=this.getIconSize();this.triggerEl=document.createElement("div"),this.triggerEl.className="designbase-wc-color-picker__trigger",this.triggerEl.addEventListener("click",()=>this.toggleOpen());const i=document.createElement("div");i.className="designbase-wc-color-picker__color-display",this.colorBoxEl=document.createElement("div"),this.colorBoxEl.className="designbase-wc-color-picker__color-box",i.append(this.colorBoxEl),this.triggerInputEl=document.createElement("input"),this.triggerInputEl.type="text",this.triggerInputEl.className="designbase-wc-color-picker__input",this.triggerInputEl.placeholder="#000000",this.triggerInputEl.addEventListener("click",t=>t.stopPropagation()),this.triggerInputEl.addEventListener("focus",()=>{this.triggerInputFocused=!0}),this.triggerInputEl.addEventListener("blur",()=>{this.triggerInputFocused=!1;const t="hex"===this.format?r(this.getUiFormatted()):this.getUiFormatted();this.triggerInputEl&&this.triggerInputEl.value!==t&&(this.triggerInputEl.value=t,this.colorInput=t)}),this.triggerInputEl.addEventListener("input",()=>{this.triggerInputEl&&(this.colorInput=this.triggerInputEl.value)}),this.triggerInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitColorInput("trigger")});const s=document.createElement("div");s.className="designbase-wc-color-picker__trigger-actions",this.triggerCopyBtn=document.createElement("button"),this.triggerCopyBtn.type="button",this.triggerCopyBtn.className="designbase-wc-color-picker__copy-button-inline",this.triggerCopyBtn.setAttribute("aria-label","Copy color value"),this.triggerCopyBtn.addEventListener("click",t=>{t.stopPropagation(),this.onCopy()}),this.toggleBtn=document.createElement("button"),this.toggleBtn.type="button",this.toggleBtn.className="designbase-wc-color-picker__toggle",this.toggleBtn.setAttribute("aria-label","Toggle color picker"),this.toggleBtn.append(u("chevron-down",t)),s.append(this.triggerCopyBtn,this.toggleBtn),this.triggerEl.append(i,this.triggerInputEl,s),this.dropdownEl=document.createElement("div"),this.dropdownEl.className="designbase-wc-color-picker__dropdown",this.dropdownEl.addEventListener("click",t=>t.stopPropagation()),this.dropdownEl.hidden=!0;const l=document.createElement("div");l.className="designbase-wc-color-picker__selector";const n=document.createElement("div");n.className="designbase-wc-color-picker__color-area",this.colorFieldEl=document.createElement("div"),this.colorFieldEl.className="designbase-wc-color-picker__color-field",this.colorPointerEl=document.createElement("div"),this.colorPointerEl.className="designbase-wc-color-picker__color-pointer",this.colorFieldEl.append(this.colorPointerEl),this.colorFieldEl.addEventListener("mousedown",t=>{this.getBool("disabled")||this.getBool("readonly")||(t.preventDefault(),this.dragging="area",this.updateFromArea(t.clientX,t.clientY))}),this.colorFieldEl.addEventListener("touchstart",t=>{if(this.getBool("disabled")||this.getBool("readonly"))return;this.dragging="area";const e=t.touches[0];this.updateFromArea(e.clientX,e.clientY)},{passive:!0}),this.colorFieldEl.addEventListener("touchmove",t=>{if("area"!==this.dragging)return;const e=t.touches[0];this.updateFromArea(e.clientX,e.clientY)},{passive:!0}),this.colorFieldEl.addEventListener("touchend",()=>{"area"===this.dragging&&(this.dragging=null,this.onColorStateChanged(!0))}),n.append(this.colorFieldEl);const o=document.createElement("div");o.className="designbase-wc-color-picker__controls",this.eyedropperBtnEl=document.createElement("db-button"),this.eyedropperBtnEl.setAttribute("variant","tertiary"),this.eyedropperBtnEl.setAttribute("size",this.getPanelControlSize()),this.eyedropperBtnEl.setAttribute("icon-only",""),this.eyedropperBtnEl.setAttribute("start-icon","eyedropper"),this.eyedropperBtnEl.setAttribute("aria-label","Eyedropper tool"),this.eyedropperBtnEl.addEventListener("click",()=>{this.onEyedrop()});const a=document.createElement("div");a.className="designbase-wc-color-picker__slider-container";const h=document.createElement("div");h.className="designbase-wc-color-picker__hue-slider",this.hueSliderEl=document.createElement("input"),this.hueSliderEl.type="range",this.hueSliderEl.min="0",this.hueSliderEl.max="360",this.hueSliderEl.className="designbase-wc-color-picker__slider designbase-wc-color-picker__slider--hue",this.hueSliderEl.addEventListener("input",()=>{this.h=parseFloat(this.hueSliderEl.value),this.updateVisuals(),this.onColorStateChanged()}),h.append(this.hueSliderEl),this.alphaSliderWrapEl=document.createElement("div"),this.alphaSliderWrapEl.className="designbase-wc-color-picker__alpha-slider",this.alphaSliderEl=document.createElement("input"),this.alphaSliderEl.type="range",this.alphaSliderEl.min="0",this.alphaSliderEl.max="100",this.alphaSliderEl.className="designbase-wc-color-picker__slider designbase-wc-color-picker__slider--alpha",this.alphaSliderEl.addEventListener("input",()=>{this.a=d(parseInt(this.alphaSliderEl.value,10),0,100),this.alphaInput=String(this.a),this.panelAlphaInputEl&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput),this.updateVisuals(),this.onColorStateChanged()}),this.alphaSliderWrapEl.append(this.alphaSliderEl),a.append(h,this.alphaSliderWrapEl),o.append(this.eyedropperBtnEl,a);const p=document.createElement("div");p.className="designbase-wc-color-picker__value-display",this.formatSelectEl=document.createElement("db-select"),this.formatSelectEl.setAttribute("size","s"),this.formatSelectEl.setAttribute("position","top"),this.formatSelectEl.setAttribute("show-clear-button","false"),this.formatSelectEl.setAttribute("options",B),this.formatSelectEl.addEventListener("db-change",t=>{const e=t.detail,i=e?.value;i&&(this.format=i,this.updateVisuals())}),this.panelValueInputEl=document.createElement("db-input"),this.panelValueInputEl.classList.add("designbase-wc-color-picker__value-input"),this.panelValueInputEl.setAttribute("size","s"),this.panelValueInputEl.setAttribute("placeholder","#000000"),this.panelValueInputEl.addEventListener("db-focus",()=>{this.panelInputFocused=!0}),this.panelValueInputEl.addEventListener("db-blur",()=>{this.panelInputFocused=!1;const t="hex"===this.format?r(this.getUiFormatted()):this.getUiFormatted();this.getInputValue(this.panelValueInputEl)!==t&&(this.setInputValue(this.panelValueInputEl,t),this.colorInput=t)}),this.panelValueInputEl.addEventListener("db-input",t=>{const e=t.detail;void 0!==e?.value&&(this.colorInput=e.value)}),this.panelValueInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitColorInput("panel")}),this.panelAlphaWrapEl=document.createElement("div"),this.panelAlphaWrapEl.className="designbase-wc-color-picker__alpha-input-wrap",this.panelAlphaInputEl=document.createElement("db-input"),this.panelAlphaInputEl.classList.add("designbase-wc-color-picker__alpha-input"),this.panelAlphaInputEl.setAttribute("size","s"),this.panelAlphaInputEl.setAttribute("placeholder","100"),this.panelAlphaInputEl.setAttribute("aria-label","Alpha percent"),this.panelAlphaInputEl.addEventListener("db-focus",()=>{this.panelAlphaInputFocused=!0}),this.panelAlphaInputEl.addEventListener("db-blur",()=>{this.panelAlphaInputFocused=!1,this.commitAlphaInput()}),this.panelAlphaInputEl.addEventListener("db-input",t=>{const e=t.detail,i=(e?.value??"").replace(/[^\d]/g,"").slice(0,3);i!==e?.value&&this.setInputValue(this.panelAlphaInputEl,i),this.alphaInput=i}),this.panelAlphaInputEl.addEventListener("keydown",t=>{"Enter"===t.key&&this.commitAlphaInput()});const c=document.createElement("span");c.className="designbase-wc-color-picker__alpha-suffix",c.textContent="%",this.panelAlphaWrapEl.append(this.panelAlphaInputEl,c),this.panelCopyBtnEl=document.createElement("db-button"),this.panelCopyBtnEl.setAttribute("variant","tertiary"),this.panelCopyBtnEl.setAttribute("size","s"),this.panelCopyBtnEl.setAttribute("icon-only",""),this.panelCopyBtnEl.setAttribute("start-icon","copy"),this.panelCopyBtnEl.setAttribute("aria-label","Copy color value"),this.panelCopyBtnEl.addEventListener("click",()=>{this.onCopy()}),p.append(this.formatSelectEl,this.panelValueInputEl,this.panelAlphaWrapEl,this.panelCopyBtnEl),l.append(n,o,p),this.selectorEl=l,this.dropdownEl.append(l),this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","s"),this.modalEl.setAttribute("title",e("색상 선택")),this.modalEl.setAttribute("close-on-escape","true"),this.modalEl.addEventListener("db-close",this.handleModalCancel),this.modalBodyEl=document.createElement("div"),this.modalBodyEl.className="designbase-wc-modal__body designbase-wc-color-picker__modal-body",this.modalBodyEl.setAttribute("data-modal-part","body");const g=document.createElement("div");g.className="designbase-wc-modal__footer",g.setAttribute("data-modal-part","footer");const E=document.createElement("db-button");this.cancelButton=E,E.setAttribute("variant","tertiary"),E.setAttribute("size","m"),E.textContent=e("취소"),E.addEventListener("click",this.handleModalCancel);const m=document.createElement("db-button");this.applyButton=m,m.setAttribute("variant","primary"),m.setAttribute("size","m"),m.textContent=e("적용"),m.addEventListener("click",this.handleModalApply),g.append(E,m),this.modalEl.append(this.modalBodyEl,g),this.replaceChildren(this.triggerEl,this.dropdownEl,this.modalEl)}updateCopyButtons(){const t=this.getIconSize(),e=this.isCopied?"done":"copy";this.triggerCopyBtn&&this.triggerCopyBtn.replaceChildren(u(e,t)),this.panelCopyBtnEl&&this.panelCopyBtnEl.setAttribute("start-icon",e)}updateVisuals(){const t=this.getRgb(),e=this.getHex(),i=this.getBool("show-alpha",!0),s=this.getUiFormatted(),l="hex"===this.format?r(s):s;!this.triggerInputFocused&&this.triggerInputEl&&(this.triggerInputEl.value=l),!this.panelInputFocused&&this.panelValueInputEl&&this.setInputValue(this.panelValueInputEl,l),this.colorBoxEl&&(this.colorBoxEl.style.backgroundColor=i?`rgba(${t.r}, ${t.g}, ${t.b}, ${this.a/100})`:e),this.colorFieldEl&&(this.colorFieldEl.style.backgroundImage=`\n linear-gradient(to top, rgba(0,0,0,1), rgba(0,0,0,0)),\n linear-gradient(to right, #ffffff, hsl(${this.h}, 100%, 50%))\n `),this.colorPointerEl&&(this.colorPointerEl.style.left=`${this.s}%`,this.colorPointerEl.style.top=100-this.v+"%",this.colorPointerEl.style.backgroundColor=`rgb(${t.r}, ${t.g}, ${t.b})`),this.hueSliderEl&&(this.hueSliderEl.value=String(this.h),this.hueSliderEl.style.background="linear-gradient(to right,\n hsl(0,100%,50%),\n hsl(60,100%,50%),\n hsl(120,100%,50%),\n hsl(180,100%,50%),\n hsl(240,100%,50%),\n hsl(300,100%,50%),\n hsl(360,100%,50%))"),this.alphaSliderEl&&(this.alphaSliderEl.value=String(this.a),this.alphaSliderEl.style.backgroundImage=`\n linear-gradient(45deg, var(--db-border-base) 25%, transparent 25%),\n linear-gradient(-45deg, var(--db-border-base) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--db-border-base) 75%),\n linear-gradient(-45deg, transparent 75%, var(--db-border-base) 75%),\n linear-gradient(to right, rgba(${t.r}, ${t.g}, ${t.b}, 0), rgba(${t.r}, ${t.g}, ${t.b}, 1))\n `,this.alphaSliderEl.style.backgroundSize="8px 8px,8px 8px,8px 8px,8px 8px,100% 100%",this.alphaSliderEl.style.backgroundPosition="0 0,0 4px,4px -4px,-4px 0,0 0",this.alphaSliderEl.style.backgroundColor="var(--db-surface-base)"),this.panelAlphaInputEl&&!this.panelAlphaInputFocused&&this.setInputValue(this.panelAlphaInputEl,this.alphaInput),this.formatSelectEl&&this.formatSelectEl.getAttribute("value")!==this.format&&this.formatSelectEl.setAttribute("value",this.format),this.colorInput=l}update(){if(!this.mounted)return;const t=this.getOption("size",b,"m"),e=this.getOption("type",v,"dropdown"),i=this.getOption("position",I,"bottom-start"),s=this.getBool("disabled"),l=this.getBool("readonly"),n=this.getBool("show-input",!0),o=this.getBool("show-alpha",!0),a=this.getBool("show-format-selector",!0),r=this.getBool("show-copy-button",!0),h=this.getBool("show-eyedropper",!0),d="undefined"!=typeof window&&"EyeDropper"in window,p=this.getOption("trigger",y,"input"),u="swatch"===p;if(this.className=["designbase-wc-color-picker",`designbase-wc-color-picker--${t}`,`designbase-wc-color-picker--${i}`,`designbase-wc-color-picker--trigger-${p}`,this.open&&"dropdown"===e&&"designbase-wc-color-picker--open",this.getBool("full-width")&&"designbase-wc-color-picker--full-width",this.getBool("error")&&"designbase-wc-color-picker--error",s&&"designbase-wc-color-picker--disabled",l&&"designbase-wc-color-picker--readonly",!n&&"designbase-wc-color-picker--no-input"].filter(Boolean).join(" "),this.triggerInputEl?.setAttribute("aria-invalid",String(this.getBool("error"))),this.triggerInputEl&&(this.triggerInputEl.hidden=u||!n,this.triggerInputEl.disabled=s,this.triggerInputEl.readOnly=l),this.triggerCopyBtn&&(this.triggerCopyBtn.hidden=u||!(n&&r),this.triggerCopyBtn.disabled=s),this.toggleBtn&&(this.toggleBtn.hidden=u,this.toggleBtn.disabled=s),this.dropdownEl&&(this.dropdownEl.className=`designbase-wc-color-picker__dropdown designbase-wc-color-picker__dropdown--${i}`,this.dropdownEl.hidden=!("dropdown"===e&&this.open)),this.alphaSliderWrapEl&&(this.alphaSliderWrapEl.hidden=!o),this.panelAlphaWrapEl&&(this.panelAlphaWrapEl.hidden=!o),this.formatSelectEl&&(this.formatSelectEl.hidden=!a),this.panelCopyBtnEl&&(this.panelCopyBtnEl.hidden=!r),this.eyedropperBtnEl&&(this.eyedropperBtnEl.hidden=!(h&&d)),this.selectorEl){const t="modal"===e?this.modalBodyEl:this.dropdownEl;t&&this.selectorEl.parentElement!==t&&t.append(this.selectorEl)}this.modalEl&&("modal"===e&&this.open?this.modalEl.setAttribute("open","true"):this.modalEl.removeAttribute("open")),this.updateCopyButtons(),this.updateVisuals()}}customElements.get("db-color-picker")||customElements.define("db-color-picker",DbColorPicker);export{DbColorPicker};
@@ -6,6 +6,7 @@ type DbColorSwatchItem = {
6
6
  name?: string;
7
7
  };
8
8
  declare class DbColorSwatch extends HTMLElement {
9
+ private unsubscribeLocale?;
9
10
  private colors;
10
11
  private selected;
11
12
  private customValue;
@@ -18,6 +19,8 @@ declare class DbColorSwatch extends HTMLElement {
18
19
  static get observedAttributes(): string[];
19
20
  connectedCallback(): void;
20
21
  disconnectedCallback(): void;
22
+ private displayName;
23
+ private updateLocale;
21
24
  private handleOutsideMouseDown;
22
25
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
23
26
  get value(): string;
@@ -1 +1 @@
1
- import{normalizeHex as t,isHex as e}from"./color-picker-utils.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_SWATCH_SIZES as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const o=["rounded","circle"],l=i,a=["dropdown","modal"],c=[{value:"#1A1B25",name:"Dark"},{value:"#FFFFFF",name:"White"},{value:"#EF4444",name:"Red"},{value:"#F59E0B",name:"Orange"},{value:"#22C55E",name:"Green"},{value:"#3B82F6",name:"Blue"},{value:"#8B5CF6",name:"Purple"},{value:"#EC4899",name:"Pink"}];class DbColorSwatch extends HTMLElement{constructor(){super(...arguments),this.colors=c,this.selected="",this.customValue="",this.mounted=!1,this.handleOutsideMouseDown=t=>{if(!this.customWrapEl)return;const e=this.customPickerEl;if(!e||"function"!=typeof e.close)return;t.composedPath().includes(this.customWrapEl)||e.close()}}static get observedAttributes(){return["colors","value","default-value","shape","size","show-name","allow-custom","custom-type","disabled"]}connectedCallback(){this.mounted||(this.parseColors(),this.selected=t(this.getAttribute("value")??this.getAttribute("default-value")??""),this.mounted=!0),this.render(),document.addEventListener("mousedown",this.handleOutsideMouseDown,!0)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleOutsideMouseDown,!0)}attributeChangedCallback(e,s,i){this.mounted&&s!==i&&("colors"===e&&this.parseColors(),"value"===e&&(this.selected=t(i??"")),this.render())}get value(){return this.selected}set value(e){this.selected=t(e),this.mounted&&this.render()}getOption(t,e,i){return s(this.getAttribute(t),e,i)}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}parseColors(){const s=this.getAttribute("colors");if(s)try{const i=JSON.parse(s);if(!Array.isArray(i))return void(this.colors=c);this.colors=i.map(t=>"string"==typeof t?{value:t}:{value:t?.value??"",name:t?.name}).filter(t=>e(t.value)).map(e=>({value:t(e.value),name:e.name})),0===this.colors.length&&(this.colors=c)}catch{this.colors=c}else this.colors=c}isCustomSelected(){if(!this.selected)return!1;return!this.colors.some(t=>t.value.toUpperCase()===this.selected.toUpperCase())}emitChange(t,e){this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t,name:e??""},bubbles:!0,composed:!0}))}selectPreset(t){this.getBool("disabled")||(this.selected=t.value,this.setAttribute("value",this.selected),this.render(),this.emitChange(t.value,t.name))}render(){const t=this.getOption("shape",o,"rounded"),e=this.getOption("size",l,"m"),s=this.getBool("disabled"),i=this.getBool("show-name",!0),a=this.getBool("allow-custom",!0);this.className=["designbase-wc-color-swatch",`designbase-wc-color-swatch--${t}`,`designbase-wc-color-swatch--${e}`,s&&"designbase-wc-color-swatch--disabled"].filter(Boolean).join(" "),this.gridEl||(this.gridEl=document.createElement("div"),this.gridEl.className="designbase-wc-color-swatch__grid",this.presetsEl=document.createElement("div"),this.presetsEl.className="designbase-wc-color-swatch__presets",this.gridEl.append(this.presetsEl)),this.gridEl.parentElement!==this&&this.append(this.gridEl);const c=this.isCustomSelected();this.presetsEl.replaceChildren(...this.colors.map(t=>{const e=!c&&this.selected.toUpperCase()===t.value.toUpperCase();return this.buildSwatch(t,e,i,s)})),a?(this.ensureCustom(),this.updateCustom(e,c,i,s),this.customWrapEl&&this.customWrapEl.parentElement!==this.gridEl&&this.gridEl.append(this.customWrapEl)):this.customWrapEl?.parentElement&&this.customWrapEl.remove()}buildSwatch(t,e,s,i){const o=document.createElement("button");o.type="button",o.className=["designbase-wc-color-swatch__item",e&&"designbase-wc-color-swatch__item--selected"].filter(Boolean).join(" "),o.disabled=i,o.style.setProperty("--db-swatch-color",t.value),o.setAttribute("aria-label",t.name||t.value),o.setAttribute("aria-pressed",String(e));const l=document.createElement("span");if(l.className="designbase-wc-color-swatch__chip",o.append(l),s){const e=document.createElement("span");e.className="designbase-wc-color-swatch__tip",e.textContent=t.name||t.value,o.append(e)}return o.addEventListener("click",()=>this.selectPreset(t)),o}ensureCustom(){this.customWrapEl||(this.customWrapEl=document.createElement("div"),this.customWrapEl.className="designbase-wc-color-swatch__custom",this.customPickerEl=document.createElement("db-color-picker"),this.customPickerEl.setAttribute("trigger","swatch"),this.customPickerEl.setAttribute("show-input","false"),this.customPickerEl.setAttribute("show-copy-button","false"),this.customPickerEl.setAttribute("aria-label","Custom color"),this.customPickerEl.addEventListener("db-change",s=>{s.stopPropagation();const i=s.detail,o=t(i?.value??"");e(o)&&(this.customValue=o,this.selected=o,this.setAttribute("value",o),this.render(),this.emitChange(o,"Custom"))}),this.customTipEl=document.createElement("span"),this.customTipEl.className="designbase-wc-color-swatch__tip",this.customTipEl.textContent="Custom",this.customWrapEl.append(this.customPickerEl,this.customTipEl))}updateCustom(t,e,s,i){this.customWrapEl&&this.customPickerEl&&(this.customWrapEl.classList.toggle("designbase-wc-color-swatch__custom--selected",e),this.customTipEl&&(this.customTipEl.hidden=!s),this.customPickerEl.setAttribute("size",t),this.customPickerEl.setAttribute("type",this.getOption("custom-type",a,"dropdown")),this.customValue&&this.customPickerEl.setAttribute("value",this.customValue),i?this.customPickerEl.setAttribute("disabled",""):this.customPickerEl.removeAttribute("disabled"))}}customElements.get("db-color-swatch")||customElements.define("db-color-swatch",DbColorSwatch);export{DbColorSwatch};
1
+ import{normalizeHex as e,isHex as t}from"./color-picker-utils.js";import{subscribeDbLocale as s,dbText as i}from"../core/i18n.js";import{coerceToContract as o}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_SWATCH_SIZES as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const l=["rounded","circle"],c=a,r=["dropdown","modal"],n=[{value:"#1A1B25",name:"Dark"},{value:"#FFFFFF",name:"White"},{value:"#EF4444",name:"Red"},{value:"#F59E0B",name:"Orange"},{value:"#22C55E",name:"Green"},{value:"#3B82F6",name:"Blue"},{value:"#8B5CF6",name:"Purple"},{value:"#EC4899",name:"Pink"}],u={Dark:"어두운 색",White:"흰색",Red:"빨강",Orange:"주황",Green:"초록",Blue:"파랑",Purple:"보라",Pink:"분홍"};class DbColorSwatch extends HTMLElement{constructor(){super(...arguments),this.colors=n,this.selected="",this.customValue="",this.mounted=!1,this.handleOutsideMouseDown=e=>{if(!this.customWrapEl)return;const t=this.customPickerEl;if(!t||"function"!=typeof t.close)return;e.composedPath().includes(this.customWrapEl)||t.close()}}static get observedAttributes(){return["colors","value","default-value","shape","size","show-name","allow-custom","custom-type","disabled"]}connectedCallback(){this.mounted||(this.parseColors(),this.selected=e(this.getAttribute("value")??this.getAttribute("default-value")??""),this.mounted=!0),this.render(),this.unsubscribeLocale?.(),this.unsubscribeLocale=s(()=>this.updateLocale()),document.addEventListener("mousedown",this.handleOutsideMouseDown,!0)}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,document.removeEventListener("mousedown",this.handleOutsideMouseDown,!0)}displayName(e){return this.colors===n&&e.name&&u[e.name]?i(u[e.name]):e.name||e.value}updateLocale(){this.presetsEl?.querySelectorAll(".designbase-wc-color-swatch__item").forEach((e,t)=>{const s=this.colors[t];if(!s)return;const i=this.displayName(s);e.setAttribute("aria-label",i);const o=e.querySelector(".designbase-wc-color-swatch__tip");o&&(o.textContent=i)}),this.customPickerEl?.setAttribute("aria-label",i("사용자 지정 색상")),this.customTipEl&&(this.customTipEl.textContent=i("사용자 지정"))}attributeChangedCallback(t,s,i){this.mounted&&s!==i&&("colors"===t&&this.parseColors(),"value"===t&&(this.selected=e(i??"")),this.render())}get value(){return this.selected}set value(t){this.selected=e(t),this.mounted&&this.render()}getOption(e,t,s){return o(this.getAttribute(e),t,s)}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const s=this.getAttribute(e);return""===s||"true"===s}parseColors(){const s=this.getAttribute("colors");if(s)try{const i=JSON.parse(s);if(!Array.isArray(i))return void(this.colors=n);this.colors=i.map(e=>"string"==typeof e?{value:e}:{value:e?.value??"",name:e?.name}).filter(e=>t(e.value)).map(t=>({value:e(t.value),name:t.name})),0===this.colors.length&&(this.colors=n)}catch{this.colors=n}else this.colors=n}isCustomSelected(){if(!this.selected)return!1;return!this.colors.some(e=>e.value.toUpperCase()===this.selected.toUpperCase())}emitChange(e,t){this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,name:t??""},bubbles:!0,composed:!0}))}selectPreset(e){this.getBool("disabled")||(this.selected=e.value,this.setAttribute("value",this.selected),this.render(),this.emitChange(e.value,e.name))}render(){const e=this.getOption("shape",l,"rounded"),t=this.getOption("size",c,"m"),s=this.getBool("disabled"),i=this.getBool("show-name",!0),o=this.getBool("allow-custom",!0);this.className=["designbase-wc-color-swatch",`designbase-wc-color-swatch--${e}`,`designbase-wc-color-swatch--${t}`,s&&"designbase-wc-color-swatch--disabled"].filter(Boolean).join(" "),this.gridEl||(this.gridEl=document.createElement("div"),this.gridEl.className="designbase-wc-color-swatch__grid",this.presetsEl=document.createElement("div"),this.presetsEl.className="designbase-wc-color-swatch__presets",this.gridEl.append(this.presetsEl)),this.gridEl.parentElement!==this&&this.append(this.gridEl);const a=this.isCustomSelected();this.presetsEl.replaceChildren(...this.colors.map(e=>{const t=!a&&this.selected.toUpperCase()===e.value.toUpperCase();return this.buildSwatch(e,t,i,s)})),o?(this.ensureCustom(),this.updateCustom(t,a,i,s),this.customWrapEl&&this.customWrapEl.parentElement!==this.gridEl&&this.gridEl.append(this.customWrapEl)):this.customWrapEl?.parentElement&&this.customWrapEl.remove()}buildSwatch(e,t,s,i){const o=document.createElement("button");o.type="button",o.className=["designbase-wc-color-swatch__item",t&&"designbase-wc-color-swatch__item--selected"].filter(Boolean).join(" "),o.disabled=i,o.style.setProperty("--db-swatch-color",e.value),o.setAttribute("aria-label",this.displayName(e)),o.setAttribute("aria-pressed",String(t));const a=document.createElement("span");if(a.className="designbase-wc-color-swatch__chip",o.append(a),s){const t=document.createElement("span");t.className="designbase-wc-color-swatch__tip",t.textContent=this.displayName(e),o.append(t)}return o.addEventListener("click",()=>this.selectPreset(e)),o}ensureCustom(){this.customWrapEl||(this.customWrapEl=document.createElement("div"),this.customWrapEl.className="designbase-wc-color-swatch__custom",this.customPickerEl=document.createElement("db-color-picker"),this.customPickerEl.setAttribute("trigger","swatch"),this.customPickerEl.setAttribute("show-input","false"),this.customPickerEl.setAttribute("show-copy-button","false"),this.customPickerEl.setAttribute("aria-label",i("사용자 지정 색상")),this.customPickerEl.addEventListener("db-change",s=>{s.stopPropagation();const i=s.detail,o=e(i?.value??"");t(o)&&(this.customValue=o,this.selected=o,this.setAttribute("value",o),this.render(),this.emitChange(o,"Custom"))}),this.customTipEl=document.createElement("span"),this.customTipEl.className="designbase-wc-color-swatch__tip",this.customTipEl.textContent=i("사용자 지정"),this.customWrapEl.append(this.customPickerEl,this.customTipEl))}updateCustom(e,t,s,i){this.customWrapEl&&this.customPickerEl&&(this.customWrapEl.classList.toggle("designbase-wc-color-swatch__custom--selected",t),this.customTipEl&&(this.customTipEl.hidden=!s),this.customPickerEl.setAttribute("size",e),this.customPickerEl.setAttribute("type",this.getOption("custom-type",r,"dropdown")),this.customValue&&this.customPickerEl.setAttribute("value",this.customValue),i?this.customPickerEl.setAttribute("disabled",""):this.customPickerEl.removeAttribute("disabled"))}}customElements.get("db-color-swatch")||customElements.define("db-color-swatch",DbColorSwatch);export{DbColorSwatch};
@@ -14,6 +14,8 @@ interface ConfettiParticleOptions {
14
14
  y: number;
15
15
  };
16
16
  colors?: string[];
17
+ /** 색상 프리셋 이름(CONFETTI_PALETTES). colors 가 있으면 colors 가 우선합니다. */
18
+ palette?: string;
17
19
  shapes?: ConfettiShape[];
18
20
  scalar?: number;
19
21
  zIndex?: number;
@@ -24,6 +26,7 @@ interface ConfettiFireworkOptions {
24
26
  interval?: number;
25
27
  particleCount?: number;
26
28
  colors?: string[];
29
+ palette?: string;
27
30
  }
28
31
  declare class DbConfetti extends HTMLElement {
29
32
  static get observedAttributes(): string[];
@@ -49,6 +52,9 @@ declare class DbConfetti extends HTMLElement {
49
52
  set originY(value: number);
50
53
  get colors(): string[];
51
54
  set colors(value: string[]);
55
+ /** 색상 프리셋 이름. `colors` 속성이 있으면 colors 가 우선합니다. */
56
+ get palette(): string;
57
+ set palette(value: string);
52
58
  get shapes(): ConfettiShape[];
53
59
  set shapes(value: ConfettiShape[]);
54
60
  get duration(): number;
@@ -63,9 +69,9 @@ declare class DbConfetti extends HTMLElement {
63
69
  private sync;
64
70
  fire(opts?: ConfettiParticleOptions): void;
65
71
  fireworks(options?: ConfettiFireworkOptions): void;
66
- cannon(): void;
67
- stars(): void;
68
- pride(): void;
72
+ cannon(options?: ConfettiParticleOptions): void;
73
+ stars(options?: ConfettiParticleOptions): void;
74
+ pride(options?: ConfettiParticleOptions): void;
69
75
  snow(): void;
70
76
  fireByMode(): void;
71
77
  private drawStar;
@@ -80,8 +86,8 @@ interface ConfettiFunction {
80
86
  (options?: ConfettiParticleOptions): void;
81
87
  fireworks(options?: ConfettiFireworkOptions): void;
82
88
  cannon(options?: ConfettiParticleOptions): void;
83
- stars(): void;
84
- pride(): void;
89
+ stars(options?: ConfettiParticleOptions): void;
90
+ pride(options?: ConfettiParticleOptions): void;
85
91
  snow(): void;
86
92
  }
87
93
  declare const confetti: ConfettiFunction;
@@ -1 +1 @@
1
- import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CONFETTI_MODES as e,CONFETTI_TRIGGERS as i,CONFETTI_SHAPES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r="designbase-wc-confetti",n=["#26ccff","#a25afd","#ff5e7e","#88ff5a","#fcff42","#ffa62d","#ff36ff"];function randomRange(t,e){return Math.random()*(e-t)+t}function hexToRgb(t){let e=t.replace("#","");3===e.length&&(e=e.split("").map(t=>t+t).join(""));const i=parseInt(e,16);return{r:i>>16&255,g:i>>8&255,b:255&i}}class DbConfetti extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.particles=[],this.animationId=null,this.fireworkTimer=null,this.clickHandler=()=>this.fire(),this.loop=()=>{if(!this.ctx||!this.canvas)return void(this.animationId=null);const t=this.ctx,e=this.canvas.width/(window.devicePixelRatio||1),i=this.canvas.height/(window.devicePixelRatio||1);t.clearRect(0,0,e,i);const s=[],r=this.particles.length;for(let n=0;n<r;n++){const r=this.particles[n];r.tick++,r.vx*=r.drag,r.vy<r.maxFallSpeed?r.vy=r.vy*r.drag+r.gravity:(r.vy=.98*r.vy+.05*r.gravity,r.vy>r.maxFallSpeed&&(r.vy=r.maxFallSpeed)),r.wobble+=r.wobbleSpeed;const a=Math.sin(r.wobble)*r.flutterStrength;r.x+=r.vx+r.drift+a,r.y+=r.vy,r.angle+=r.rotationSpeed;const o=r.tick/r.totalTicks;if(r.opacity=o<.72?1:Math.max(0,1-(o-.72)/.28),r.opacity<=0||r.tick>=r.totalTicks||r.y>i+50||r.x<-80||r.x>e+80)continue;s.push(r),t.save(),t.translate(r.x,r.y),t.rotate(r.angle*Math.PI/180),t.scale(Math.cos(r.wobble),1);const l=hexToRgb(r.color);t.fillStyle=`rgba(${l.r}, ${l.g}, ${l.b}, ${r.opacity.toFixed(3)})`,"circle"===r.shape?(t.beginPath(),t.arc(0,0,r.w/2,0,2*Math.PI),t.fill()):"star"===r.shape?this.drawStar(t,0,0,5,r.w,r.w/2):t.fillRect(-r.w/2,-r.h/2,r.w,r.h),t.restore()}this.particles=s,this.particles.length>0?this.animationId=requestAnimationFrame(this.loop):this.animationId=null}}static get observedAttributes(){return["mode","trigger","particle-count","spread","origin-x","origin-y","colors","shapes","duration","fullscreen"]}get mode(){return t(this.getAttribute("mode"),e,"cannon")}set mode(t){this.setAttribute("mode",t)}get trigger(){return t(this.getAttribute("trigger"),i,"manual")}set trigger(t){this.setAttribute("trigger",t)}get particleCount(){const t=parseInt(this.getAttribute("particle-count")||"60",10);return Number.isFinite(t)&&t>0?t:60}set particleCount(t){this.setAttribute("particle-count",String(t))}get spread(){const t=parseFloat(this.getAttribute("spread")||"70");return Number.isFinite(t)?t:70}set spread(t){this.setAttribute("spread",String(t))}get originX(){const t=parseFloat(this.getAttribute("origin-x")||"0.5");return Number.isFinite(t)?t:.5}set originX(t){this.setAttribute("origin-x",String(t))}get originY(){const t=parseFloat(this.getAttribute("origin-y")||"0.7");return Number.isFinite(t)?t:.7}set originY(t){this.setAttribute("origin-y",String(t))}get colors(){const t=this.getAttribute("colors");if(!t)return n;const e=t.split(",").map(t=>t.trim()).filter(Boolean);return e.length?e:n}set colors(t){this.setAttribute("colors",t.join(","))}get shapes(){const t=this.getAttribute("shapes");if(!t)return["square","circle"];if("mix"===t)return["square","circle","star"];const e=t.split(",").map(t=>t.trim()).filter(t=>s.includes(t));return e.length?e:["square","circle"]}set shapes(t){this.setAttribute("shapes",t.join(","))}get duration(){const t=parseFloat(this.getAttribute("duration")||"3000");return Number.isFinite(t)&&t>0?t:3e3}set duration(t){this.setAttribute("duration",String(t))}get fullscreen(){return this.hasAttribute("fullscreen")}set fullscreen(t){t?this.setAttribute("fullscreen",""):this.removeAttribute("fullscreen")}connectedCallback(){this.setAttribute("aria-hidden","true"),this.built||(this.build(),this.built=!0),this.sync(),"auto"===this.trigger?requestAnimationFrame(()=>this.fireByMode()):"click"===this.trigger&&this.parentElement&&this.parentElement.addEventListener("click",this.clickHandler)}disconnectedCallback(){null!==this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.parentElement&&this.parentElement.removeEventListener("click",this.clickHandler)}attributeChangedCallback(t,e,i){this.built&&("trigger"===t&&this.parentElement&&(this.parentElement.removeEventListener("click",this.clickHandler),"click"===this.trigger&&this.parentElement.addEventListener("click",this.clickHandler)),this.sync())}build(){this.classList.add(r);const t=document.createElement("canvas");t.className=`${r}__canvas`,this.canvas=t,this.ctx=t.getContext("2d"),this.replaceChildren(t),this.updateCanvasSize(),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateCanvasSize()),this.resizeObserver.observe(this.fullscreen?document.body:this.parentElement||this))}updateCanvasSize(){if(!this.canvas)return;const t=window.devicePixelRatio||1;let e=this.clientWidth,i=this.clientHeight;if(this.fullscreen||0===e||0===i){const t=this.parentElement;t&&!this.fullscreen?(e=t.clientWidth,i=t.clientHeight):(e=window.innerWidth,i=window.innerHeight)}0===e&&(e=300),0===i&&(i=300),this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${i}px`,this.ctx&&(this.ctx.resetTransform?.(),this.ctx.scale(t,t))}sync(){this.fullscreen?this.classList.add(`${r}--fullscreen`):this.classList.remove(`${r}--fullscreen`),e.forEach(t=>this.classList.remove(`${r}--${t}`)),this.classList.add(`${r}--${this.mode}`)}fire(t){if(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches&&!1!==t?.disableForReducedMotion)return;this.updateCanvasSize();const e=this.canvas?this.canvas.width/(window.devicePixelRatio||1):400,i=this.canvas?this.canvas.height/(window.devicePixelRatio||1):400,s=this.fullscreen||this.parentElement===document.body||this.parentElement===document.documentElement||e>=window.innerWidth-30&&i>=window.innerHeight-30,r=s?1:Math.min(1,Math.max(.18,i/750)),n=s?1:Math.min(1,Math.max(.22,e/900)),a=Math.min(r,n),o=s?1:Math.max(.18,Math.min(1,.62*r+.04)),l=s?1:Math.max(.26,Math.min(1,.7*r+.15)),c=s?1:Math.max(.35,Math.min(1,.6*r+.25)),h=s?1:Math.max(.7,Math.min(1,.68+.32*a)),d=t?.particleCount??this.particleCount,u=t?.angle??90,f=t?.spread??this.spread,g=(t?.startVelocity??58)*o,m=t?.decay??(s?.925:Math.max(.91,.925-.015*(1-r))),p=(t?.gravity??.42)*l,b=(t?.drift??0)*(s?1:n),v=t?.ticks??380,w=s?v:Math.round(v*(.65+.35*a)),y=t?.colors??this.colors,k=t?.shapes??this.shapes,x=(t?.scalar??1)*h,M=(t?.origin?.x??this.originX)*e,C=(t?.origin?.y??this.originY)*i,R=u*Math.PI/180,A=f*Math.PI/180;for(let t=0;t<d;t++){const t=R+(Math.random()-.5)*A,e=g*randomRange(.65,1.35),i=y[Math.floor(Math.random()*y.length)],r=k[Math.floor(Math.random()*k.length)],n=m*randomRange(.99,1.01),o=p*randomRange(.85,1.15),l=randomRange(2.2,4.2)*x*c,h=randomRange(.8,2.2)*(s?1:Math.max(.5,1.2*a)),d=Math.floor(w*randomRange(.85,1.25));this.particles.push({x:M,y:C,vx:Math.cos(t)*e,vy:-Math.sin(t)*e,w:randomRange(7,12)*x,h:("circle"===r?randomRange(7,12):randomRange(10,18))*x,color:i,shape:r,angle:360*Math.random(),rotationSpeed:randomRange(-4.5,4.5),wobble:10*Math.random(),wobbleSpeed:randomRange(.06,.14),opacity:1,gravity:o,drag:n,drift:b,maxFallSpeed:l,flutterStrength:h,tick:0,totalTicks:d,scalar:x})}null===this.animationId&&this.loop()}fireworks(t){const e=t?.duration??(this.duration||3500),i=t?.interval??320,s=Date.now()+e;null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null);const runBurst=()=>{if(Date.now()>s)return void(null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null));const e=t?.particleCount??Math.floor(randomRange(30,50));this.fire({particleCount:e,startVelocity:42,spread:360,ticks:280,origin:{x:randomRange(.15,.85),y:randomRange(.12,.45)},colors:t?.colors??this.colors})};runBurst(),this.fireworkTimer=window.setInterval(runBurst,i)}cannon(){this.fire({particleCount:this.particleCount,angle:90,spread:75,startVelocity:58,ticks:380,origin:{x:.5,y:.85}})}stars(){this.fire({particleCount:45,spread:360,ticks:260,gravity:.25,decay:.94,startVelocity:38,shapes:["star"],colors:["#ffe600","#ffd700","#ffffff","#ffaa00","#f59e0b"],scalar:1.2})}pride(){const t=["#e40303","#ff8c00","#ffed00","#008026","#004dff","#750787"];this.fire({particleCount:48,angle:60,spread:60,startVelocity:56,ticks:380,origin:{x:0,y:.85},colors:t}),this.fire({particleCount:48,angle:120,spread:60,startVelocity:56,ticks:380,origin:{x:1,y:.85},colors:t})}snow(){this.fire({particleCount:50,angle:270,spread:180,startVelocity:14,gravity:.18,drift:randomRange(-.3,.3),ticks:450,shapes:["circle"],colors:["#ffffff","#e2e8f0","#93c5fd"],origin:{x:randomRange(.1,.9),y:-.05},scalar:.8})}fireByMode(){switch(this.mode){case"fireworks":this.fireworks();break;case"stars":this.stars();break;case"pride":this.pride();break;case"snow":this.snow();break;default:this.cannon()}}drawStar(t,e,i,s,r,n){let a=Math.PI/2*3,o=e,l=i;const c=Math.PI/s;t.beginPath(),t.moveTo(e,i-r);for(let h=0;h<s;h++)o=e+Math.cos(a)*r,l=i+Math.sin(a)*r,t.lineTo(o,l),a+=c,o=e+Math.cos(a)*n,l=i+Math.sin(a)*n,t.lineTo(o,l),a+=c;t.lineTo(e,i-r),t.closePath(),t.fill()}}customElements.get("db-confetti")||customElements.define("db-confetti",DbConfetti);let a=null;function getGlobalConfetti(){return a&&a.isConnected||(a=document.createElement("db-confetti"),a.setAttribute("fullscreen",""),document.body.appendChild(a)),a}const o=Object.assign(t=>{getGlobalConfetti().fire(t)},{fireworks:t=>{getGlobalConfetti().fireworks(t)},cannon:t=>{t?getGlobalConfetti().fire(t):getGlobalConfetti().cannon()},stars:()=>{getGlobalConfetti().stars()},pride:()=>{getGlobalConfetti().pride()},snow:()=>{getGlobalConfetti().snow()}});export{DbConfetti,o as confetti};
1
+ import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CONFETTI_MODES as e,CONFETTI_TRIGGERS as i,CONFETTI_SHAPES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r="designbase-wc-confetti",a={soft:["#7c8cf8","#f08fb0","#f6b26b","#79c9b0","#b79cf0","#f2d675"],pastel:["#ffd1dc","#c7e4ff","#d6f5d6","#fff1b8","#e3d4ff","#ffd9b8"],sunset:["#ff9a6b","#ff6f91","#ffc75f","#f9a8d4","#c44d78","#ffe0a3"],ocean:["#38bdf8","#2dd4bf","#818cf8","#a5f3fc","#0e7490","#bae6fd"],forest:["#4d8b6a","#9bc59d","#d9c98b","#7aa78a","#c9dfb4","#2f6b52"],candy:["#ff8fcf","#8fd3ff","#ffe08f","#b9a4ff","#9ff0c8","#ffb4a2"],gold:["#e8c15a","#f6e3a1","#c99a2e","#fff6d6","#b8860b","#f3d27a"],mono:["#111827","#4b5563","#9ca3af","#d1d5db","#f3f4f6","#6b7280"],classic:["#26ccff","#a25afd","#ff5e7e","#88ff5a","#fcff42","#ffa62d","#ff36ff"]},n="soft",o=a[n];function paletteColors(t){return t&&a[t]?a[t]:null}function randomRange(t,e){return Math.random()*(e-t)+t}function hexToRgb(t){let e=t.replace("#","");3===e.length&&(e=e.split("").map(t=>t+t).join(""));const i=parseInt(e,16);return{r:i>>16&255,g:i>>8&255,b:255&i}}class DbConfetti extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.particles=[],this.animationId=null,this.fireworkTimer=null,this.clickHandler=()=>this.fire(),this.loop=()=>{if(!this.ctx||!this.canvas)return void(this.animationId=null);const t=this.ctx,e=this.canvas.width/(window.devicePixelRatio||1),i=this.canvas.height/(window.devicePixelRatio||1);t.clearRect(0,0,e,i);const s=[],r=this.particles.length;for(let a=0;a<r;a++){const r=this.particles[a];r.tick++,r.vx*=r.drag,r.vy<r.maxFallSpeed?r.vy=r.vy*r.drag+r.gravity:(r.vy=.98*r.vy+.05*r.gravity,r.vy>r.maxFallSpeed&&(r.vy=r.maxFallSpeed)),r.wobble+=r.wobbleSpeed;const n=Math.sin(r.wobble)*r.flutterStrength;r.x+=r.vx+r.drift+n,r.y+=r.vy,r.angle+=r.rotationSpeed;const o=r.tick/r.totalTicks;if(r.opacity=o<.72?1:Math.max(0,1-(o-.72)/.28),r.opacity<=0||r.tick>=r.totalTicks||r.y>i+50||r.x<-80||r.x>e+80)continue;s.push(r),t.save(),t.translate(r.x,r.y),t.rotate(r.angle*Math.PI/180),t.scale(Math.cos(r.wobble),1);const l=hexToRgb(r.color);if(t.fillStyle=`rgba(${l.r}, ${l.g}, ${l.b}, ${r.opacity.toFixed(3)})`,"circle"===r.shape)t.beginPath(),t.arc(0,0,r.w/2,0,2*Math.PI),t.fill();else if("star"===r.shape)this.drawStar(t,0,0,5,r.w,r.w/2);else{const e=.22*Math.min(r.w,r.h);t.beginPath(),t.roundRect(-r.w/2,-r.h/2,r.w,r.h,e),t.fill()}t.restore()}this.particles=s,this.particles.length>0?this.animationId=requestAnimationFrame(this.loop):this.animationId=null}}static get observedAttributes(){return["mode","trigger","particle-count","spread","origin-x","origin-y","colors","palette","shapes","duration","fullscreen"]}get mode(){return t(this.getAttribute("mode"),e,"cannon")}set mode(t){this.setAttribute("mode",t)}get trigger(){return t(this.getAttribute("trigger"),i,"manual")}set trigger(t){this.setAttribute("trigger",t)}get particleCount(){const t=parseInt(this.getAttribute("particle-count")||"60",10);return Number.isFinite(t)&&t>0?t:60}set particleCount(t){this.setAttribute("particle-count",String(t))}get spread(){const t=parseFloat(this.getAttribute("spread")||"70");return Number.isFinite(t)?t:70}set spread(t){this.setAttribute("spread",String(t))}get originX(){const t=parseFloat(this.getAttribute("origin-x")||"0.5");return Number.isFinite(t)?t:.5}set originX(t){this.setAttribute("origin-x",String(t))}get originY(){const t=parseFloat(this.getAttribute("origin-y")||"0.7");return Number.isFinite(t)?t:.7}set originY(t){this.setAttribute("origin-y",String(t))}get colors(){const t=this.getAttribute("colors"),e=paletteColors(this.getAttribute("palette"))??o;if(!t)return e;const i=t.split(",").map(t=>t.trim()).filter(Boolean);return i.length?i:e}set colors(t){this.setAttribute("colors",t.join(","))}get palette(){const t=this.getAttribute("palette");return t&&a[t]?t:n}set palette(t){this.setAttribute("palette",t)}get shapes(){const t=this.getAttribute("shapes");if(!t)return["square","circle"];if("mix"===t)return["square","circle","star"];const e=t.split(",").map(t=>t.trim()).filter(t=>s.includes(t));return e.length?e:["square","circle"]}set shapes(t){this.setAttribute("shapes",t.join(","))}get duration(){const t=parseFloat(this.getAttribute("duration")||"3000");return Number.isFinite(t)&&t>0?t:3e3}set duration(t){this.setAttribute("duration",String(t))}get fullscreen(){return this.hasAttribute("fullscreen")}set fullscreen(t){t?this.setAttribute("fullscreen",""):this.removeAttribute("fullscreen")}connectedCallback(){this.setAttribute("aria-hidden","true"),this.built||(this.build(),this.built=!0),this.sync(),"auto"===this.trigger?requestAnimationFrame(()=>this.fireByMode()):"click"===this.trigger&&this.parentElement&&this.parentElement.addEventListener("click",this.clickHandler)}disconnectedCallback(){null!==this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.parentElement&&this.parentElement.removeEventListener("click",this.clickHandler)}attributeChangedCallback(t,e,i){this.built&&("trigger"===t&&this.parentElement&&(this.parentElement.removeEventListener("click",this.clickHandler),"click"===this.trigger&&this.parentElement.addEventListener("click",this.clickHandler)),this.sync())}build(){this.classList.add(r);const t=document.createElement("canvas");t.className=`${r}__canvas`,this.canvas=t,this.ctx=t.getContext("2d"),this.replaceChildren(t),this.updateCanvasSize(),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateCanvasSize()),this.resizeObserver.observe(this.fullscreen?document.body:this.parentElement||this))}updateCanvasSize(){if(!this.canvas)return;const t=window.devicePixelRatio||1;let e=this.clientWidth,i=this.clientHeight;if(this.fullscreen||0===e||0===i){const t=this.parentElement;t&&!this.fullscreen?(e=t.clientWidth,i=t.clientHeight):(e=window.innerWidth,i=window.innerHeight)}0===e&&(e=300),0===i&&(i=300),this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${i}px`,this.ctx&&(this.ctx.resetTransform?.(),this.ctx.scale(t,t))}sync(){this.fullscreen?this.classList.add(`${r}--fullscreen`):this.classList.remove(`${r}--fullscreen`),e.forEach(t=>this.classList.remove(`${r}--${t}`)),this.classList.add(`${r}--${this.mode}`)}fire(t){if(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches&&!1!==t?.disableForReducedMotion)return;this.updateCanvasSize();const e=this.canvas?this.canvas.width/(window.devicePixelRatio||1):400,i=this.canvas?this.canvas.height/(window.devicePixelRatio||1):400,s=this.fullscreen||this.parentElement===document.body||this.parentElement===document.documentElement||e>=window.innerWidth-30&&i>=window.innerHeight-30,r=s?1:Math.min(1,Math.max(.18,i/750)),a=s?1:Math.min(1,Math.max(.22,e/900)),n=Math.min(r,a),o=s?1:Math.max(.18,Math.min(1,.62*r+.04)),l=s?1:Math.max(.26,Math.min(1,.7*r+.15)),c=s?1:Math.max(.35,Math.min(1,.6*r+.25)),h=s?1:Math.max(.7,Math.min(1,.68+.32*n)),d=t?.particleCount??this.particleCount,f=t?.angle??90,u=t?.spread??this.spread,g=(t?.startVelocity??58)*o,m=t?.decay??(s?.925:Math.max(.91,.925-.015*(1-r))),p=(t?.gravity??.42)*l,b=(t?.drift??0)*(s?1:a),v=t?.ticks??380,w=s?v:Math.round(v*(.65+.35*n)),y=t?.colors??paletteColors(t?.palette)??this.colors,k=t?.shapes??this.shapes,x=(t?.scalar??1)*h,M=(t?.origin?.x??this.originX)*e,C=(t?.origin?.y??this.originY)*i,A=f*Math.PI/180,R=u*Math.PI/180;for(let t=0;t<d;t++){const t=A+(Math.random()-.5)*R,e=g*randomRange(.65,1.35),i=y[Math.floor(Math.random()*y.length)],r=k[Math.floor(Math.random()*k.length)],a=m*randomRange(.99,1.01),o=p*randomRange(.85,1.15),l=randomRange(2.2,4.2)*x*c,h=randomRange(.8,2.2)*(s?1:Math.max(.5,1.2*n)),d=Math.floor(w*randomRange(.85,1.25));this.particles.push({x:M,y:C,vx:Math.cos(t)*e,vy:-Math.sin(t)*e,w:randomRange(5,9)*x,h:("circle"===r?randomRange(5,9):randomRange(9,15))*x,color:i,shape:r,angle:360*Math.random(),rotationSpeed:randomRange(-4.5,4.5),wobble:10*Math.random(),wobbleSpeed:randomRange(.06,.14),opacity:1,gravity:o,drag:a,drift:b,maxFallSpeed:l,flutterStrength:h,tick:0,totalTicks:d,scalar:x})}null===this.animationId&&this.loop()}fireworks(t){const e=t?.duration??(this.duration||3500),i=t?.interval??320,s=Date.now()+e;null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null);const runBurst=()=>{if(Date.now()>s)return void(null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null));const e=t?.particleCount??Math.floor(randomRange(30,50));this.fire({particleCount:e,startVelocity:42,spread:360,ticks:280,origin:{x:randomRange(.15,.85),y:randomRange(.12,.45)},colors:t?.colors??paletteColors(t?.palette)??this.colors})};runBurst(),this.fireworkTimer=window.setInterval(runBurst,i)}cannon(t){this.fire({particleCount:this.particleCount,angle:90,spread:75,startVelocity:58,ticks:380,origin:{x:.5,y:.85},...t})}stars(t){this.fire({particleCount:45,spread:360,ticks:260,gravity:.25,decay:.94,startVelocity:38,shapes:["star"],colors:t?.colors??paletteColors(t?.palette)??a.gold,scalar:1.2})}pride(t){const e=t?.colors??paletteColors(t?.palette)??["#e45757","#f0a04b","#f0d35a","#4fae7b","#5b82e6","#8a63c9"];this.fire({particleCount:48,angle:60,spread:60,startVelocity:56,ticks:380,origin:{x:0,y:.85},colors:e}),this.fire({particleCount:48,angle:120,spread:60,startVelocity:56,ticks:380,origin:{x:1,y:.85},colors:e})}snow(){this.fire({particleCount:50,angle:270,spread:180,startVelocity:14,gravity:.18,drift:randomRange(-.3,.3),ticks:450,shapes:["circle"],colors:["#ffffff","#e2e8f0","#93c5fd"],origin:{x:randomRange(.1,.9),y:-.05},scalar:.8})}fireByMode(){switch(this.mode){case"fireworks":this.fireworks();break;case"stars":this.stars();break;case"pride":this.pride();break;case"snow":this.snow();break;default:this.cannon()}}drawStar(t,e,i,s,r,a){let n=Math.PI/2*3,o=e,l=i;const c=Math.PI/s;t.beginPath(),t.moveTo(e,i-r);for(let h=0;h<s;h++)o=e+Math.cos(n)*r,l=i+Math.sin(n)*r,t.lineTo(o,l),n+=c,o=e+Math.cos(n)*a,l=i+Math.sin(n)*a,t.lineTo(o,l),n+=c;t.lineTo(e,i-r),t.closePath(),t.fill()}}customElements.get("db-confetti")||customElements.define("db-confetti",DbConfetti);let l=null;function getGlobalConfetti(){return l&&l.isConnected||(l=document.createElement("db-confetti"),l.setAttribute("fullscreen",""),document.body.appendChild(l)),l}const c=Object.assign(t=>{getGlobalConfetti().fire(t)},{fireworks:t=>{getGlobalConfetti().fireworks(t)},cannon:t=>{getGlobalConfetti().cannon(t)},stars:t=>{getGlobalConfetti().stars(t)},pride:t=>{getGlobalConfetti().pride(t)},snow:()=>{getGlobalConfetti().snow()}});export{a as CONFETTI_PALETTES,DbConfetti,c as confetti};
@@ -1,6 +1,9 @@
1
1
  declare class DbCookieBanner extends HTMLElement {
2
+ private unsubscribeLocale?;
2
3
  static get observedAttributes(): string[];
3
4
  connectedCallback(): void;
5
+ disconnectedCallback(): void;
6
+ private syncLocale;
4
7
  attributeChangedCallback(): void;
5
8
  private isEnabled;
6
9
  private createButton;
@@ -1 +1 @@
1
- import{sanitizeHref as e}from"../core/safe-url.js";class DbCookieBanner extends HTMLElement{static get observedAttributes(){return["title","description","policy-label","policy-href","accept-label","reject-label","settings-label","show-reject","show-settings","fixed","dismissed"]}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}isEnabled(e,t){const s=this.getAttribute(e);return null===s?t:"false"!==s}createButton(e,t,s,i){const n=document.createElement("db-button");return n.setAttribute("variant",t),n.setAttribute("size","s"),n.textContent=e,n.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent(s,{bubbles:!0,composed:!0})),i&&(this.setAttribute("dismissed",""),this.render())}),n}render(){if(this.hasAttribute("dismissed"))return this.replaceChildren(),this.className="designbase-wc-cookie-banner designbase-wc-cookie-banner--dismissed",this.style.display="none",void this.removeAttribute("role");this.style.display="";const t=this.getAttribute("title")||"쿠키 사용 안내",s=this.getAttribute("description")||"더 나은 서비스 제공을 위해 쿠키를 사용합니다. 계속 이용하시면 쿠키 사용에 동의하는 것으로 간주됩니다.",i=this.getAttribute("policy-label")||"쿠키 정책",n=this.getAttribute("policy-href")||"",a=this.getAttribute("accept-label")||"모두 허용",r=this.getAttribute("reject-label")||"필수만 허용",c=this.getAttribute("settings-label")||"설정",o=this.isEnabled("show-reject",!0),d=this.isEnabled("show-settings",!1),l=this.isEnabled("fixed",!0);this.className=["designbase-wc-cookie-banner",l&&"designbase-wc-cookie-banner--fixed"].filter(Boolean).join(" "),this.setAttribute("role","dialog"),this.setAttribute("aria-modal","false"),this.setAttribute("aria-label",t),this.setAttribute("aria-live","polite");const b=document.createElement("div");b.className="designbase-wc-cookie-banner__inner";const h=document.createElement("div");h.className="designbase-wc-cookie-banner__copy";{const e=document.createElement("p");e.className="designbase-wc-cookie-banner__title",e.textContent=t,h.append(e)}const p=document.createElement("p");p.className="designbase-wc-cookie-banner__description",p.append(document.createTextNode(s));const u=e(n,"");if(u){p.append(document.createTextNode(" "));const e=document.createElement("a");e.className="designbase-wc-cookie-banner__policy",e.href=u,e.target="_blank",e.rel="noopener noreferrer",e.textContent=i,e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-policy",{bubbles:!0,composed:!0}))}),p.append(e)}h.append(p);const m=document.createElement("div");m.className="designbase-wc-cookie-banner__actions",d&&m.append(this.createButton(c,"ghost","db-settings",!1)),o&&m.append(this.createButton(r,"tertiary","db-reject",!0)),m.append(this.createButton(a,"primary","db-accept",!0)),b.append(h,m),this.replaceChildren(b)}}customElements.get("db-cookie-banner")||customElements.define("db-cookie-banner",DbCookieBanner);export{DbCookieBanner};
1
+ import{sanitizeHref as e}from"../core/safe-url.js";import{subscribeDbLocale as t,dbText as i}from"../core/i18n.js";class DbCookieBanner extends HTMLElement{static get observedAttributes(){return["title","description","policy-label","policy-href","accept-label","reject-label","settings-label","show-reject","show-settings","fixed","dismissed"]}connectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.syncLocale()),this.render()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0}syncLocale(){if(this.hasAttribute("dismissed"))return;const e=this.getAttribute("title")||i("쿠키 사용 안내"),t=this.querySelector(".designbase-wc-cookie-banner__title");t&&(t.textContent=e),this.setAttribute("aria-label",e);const s=this.querySelector(".designbase-wc-cookie-banner__description");s?.firstChild&&(s.firstChild.textContent=this.getAttribute("description")||i("더 나은 서비스 제공을 위해 쿠키를 사용합니다. 계속 이용하시면 쿠키 사용에 동의하는 것으로 간주됩니다."));const n=this.querySelector(".designbase-wc-cookie-banner__policy");n&&(n.textContent=this.getAttribute("policy-label")||i("쿠키 정책"));for(const[e,t]of[["settings","설정"],["reject","필수만 허용"],["accept","모두 허용"]]){const s=this.querySelector(`[data-cookie-action="${e}"]`);s&&(s.textContent=this.getAttribute(`${e}-label`)||i(t))}}attributeChangedCallback(){this.render()}isEnabled(e,t){const i=this.getAttribute(e);return null===i?t:"false"!==i}createButton(e,t,i,s){const n=document.createElement("db-button");return n.setAttribute("variant",t),n.setAttribute("size","s"),n.dataset.cookieAction=i.slice(3),n.textContent=e,n.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent(i,{bubbles:!0,composed:!0})),s&&(this.setAttribute("dismissed",""),this.render())}),n}render(){if(this.hasAttribute("dismissed"))return this.replaceChildren(),this.className="designbase-wc-cookie-banner designbase-wc-cookie-banner--dismissed",this.style.display="none",void this.removeAttribute("role");this.style.display="";const t=this.getAttribute("title")||i("쿠키 사용 안내"),s=this.getAttribute("description")||i("더 나은 서비스 제공을 위해 쿠키를 사용합니다. 계속 이용하시면 쿠키 사용에 동의하는 것으로 간주됩니다."),n=this.getAttribute("policy-label")||i("쿠키 정책"),c=this.getAttribute("policy-href")||"",o=this.getAttribute("accept-label")||i("모두 허용"),a=this.getAttribute("reject-label")||i("필수만 허용"),r=this.getAttribute("settings-label")||i("설정"),l=this.isEnabled("show-reject",!0),b=this.isEnabled("show-settings",!1),d=this.isEnabled("fixed",!0);this.className=["designbase-wc-cookie-banner",d&&"designbase-wc-cookie-banner--fixed"].filter(Boolean).join(" "),this.setAttribute("role","dialog"),this.setAttribute("aria-modal","false"),this.setAttribute("aria-label",t),this.setAttribute("aria-live","polite");const h=document.createElement("div");h.className="designbase-wc-cookie-banner__inner";const u=document.createElement("div");if(u.className="designbase-wc-cookie-banner__copy",t){const e=document.createElement("p");e.className="designbase-wc-cookie-banner__title",e.textContent=t,u.append(e)}const p=document.createElement("p");p.className="designbase-wc-cookie-banner__description",p.append(document.createTextNode(s));const m=e(c,"");if(m){p.append(document.createTextNode(" "));const e=document.createElement("a");e.className="designbase-wc-cookie-banner__policy",e.href=m,e.target="_blank",e.rel="noopener noreferrer",e.textContent=n,e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-policy",{bubbles:!0,composed:!0}))}),p.append(e)}u.append(p);const g=document.createElement("div");g.className="designbase-wc-cookie-banner__actions",b&&g.append(this.createButton(r,"ghost","db-settings",!1)),l&&g.append(this.createButton(a,"tertiary","db-reject",!0)),g.append(this.createButton(o,"primary","db-accept",!0)),h.append(u,g),this.replaceChildren(h)}}customElements.get("db-cookie-banner")||customElements.define("db-cookie-banner",DbCookieBanner);export{DbCookieBanner};
@@ -1,10 +1,11 @@
1
1
  declare class DbCountdown extends HTMLElement {
2
2
  private timer;
3
3
  private targetTime;
4
+ private unsubscribeLocale?;
4
5
  static get observedAttributes(): string[];
5
6
  connectedCallback(): void;
6
7
  disconnectedCallback(): void;
7
- attributeChangedCallback(): void;
8
+ attributeChangedCallback(name: string): void;
8
9
  private boolAttr;
9
10
  private optionAttr;
10
11
  private setupTargetTime;
@@ -1 +1 @@
1
- import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COUNTDOWN_SIZES as e,COUNTDOWN_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const o=e,n=s;class DbCountdown extends HTMLElement{constructor(){super(...arguments),this.timer=null,this.targetTime=Date.now()}static get observedAttributes(){return["end-date","duration","size","variant","show-days","show-hours","show-minutes","show-seconds","show-labels"]}connectedCallback(){this.setupTargetTime(),this.start()}disconnectedCallback(){this.stop()}attributeChangedCallback(){this.setupTargetTime(),this.render()}boolAttr(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}optionAttr(e,s,o){return t(this.getAttribute(e),s,o)}setupTargetTime(){const t=this.getAttribute("end-date"),e=Number(this.getAttribute("duration"));if(t){const e=new Date(t).getTime();return void(this.targetTime=Number.isFinite(e)?e:Date.now())}Number.isFinite(e)&&e>0?this.targetTime=Date.now()+1e3*e:this.targetTime=Date.now()}getRemaining(){const t=this.targetTime-Date.now();return t<=0?{days:0,hours:0,minutes:0,seconds:0,total:0}:{days:Math.floor(t/864e5),hours:Math.floor(t/36e5%24),minutes:Math.floor(t/6e4%60),seconds:Math.floor(t/1e3%60),total:t}}stop(){null!==this.timer&&(window.clearInterval(this.timer),this.timer=null)}start(){this.stop(),this.render(),this.timer=window.setInterval(()=>{const t=this.getRemaining();this.render(),this.dispatchEvent(new CustomEvent("db-tick",{detail:t,bubbles:!0,composed:!0})),t.total<=0&&(this.stop(),this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})))},1e3)}two(t){return String(t).padStart(2,"0")}render(){const t=this.optionAttr("size",o,"m"),e=this.optionAttr("variant",n,"default"),s=this.boolAttr("show-labels",!0),i=this.getRemaining();this.className=["designbase-wc-countdown",`designbase-wc-countdown--${t}`,`designbase-wc-countdown--${e}`,s&&"designbase-wc-countdown--with-labels",i.total<=0&&"designbase-wc-countdown--expired"].filter(Boolean).join(" ");const a={days:this.getAttribute("label-days")||"일",hours:this.getAttribute("label-hours")||"시간",minutes:this.getAttribute("label-minutes")||"분",seconds:this.getAttribute("label-seconds")||"초"},r=[{key:"days",value:i.days,show:this.boolAttr("show-days",!0)},{key:"hours",value:i.hours,show:this.boolAttr("show-hours",!0)},{key:"minutes",value:i.minutes,show:this.boolAttr("show-minutes",!0)},{key:"seconds",value:i.seconds,show:this.boolAttr("show-seconds",!0)}].filter(t=>t.show),d=[];for(let t=0;t<r.length;t+=1){const o=r[t],n=document.createElement("div");n.className="designbase-wc-countdown__unit";const i=document.createElement("div");if(i.className="designbase-wc-countdown__value",i.textContent=this.two(o.value),n.append(i),s){const t=document.createElement("div");t.className="designbase-wc-countdown__label",t.textContent=a[o.key],n.append(t)}if(d.push(n),t<r.length-1&&"minimal"!==e){const t=document.createElement("div");t.className="designbase-wc-countdown__separator",t.textContent=":",d.push(t)}}this.replaceChildren(...d)}}customElements.get("db-countdown")||customElements.define("db-countdown",DbCountdown);export{DbCountdown};
1
+ import{subscribeDbLocale as t,t as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COUNTDOWN_SIZES as o,COUNTDOWN_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const i=o,a=n;class DbCountdown extends HTMLElement{constructor(){super(...arguments),this.timer=null,this.targetTime=Date.now()}static get observedAttributes(){return["end-date","duration","size","variant","show-days","show-hours","show-minutes","show-seconds","show-labels","label-days","label-hours","label-minutes","label-seconds"]}connectedCallback(){this.setupTargetTime(),this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.render()),this.start()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.stop()}attributeChangedCallback(t){"end-date"!==t&&"duration"!==t||(this.setupTargetTime(),!this.isConnected)?this.render():this.start()}boolAttr(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}optionAttr(t,e,o){return s(this.getAttribute(t),e,o)}setupTargetTime(){const t=this.getAttribute("end-date"),e=Number(this.getAttribute("duration"));if(t){const e=new Date(t).getTime();return void(this.targetTime=Number.isFinite(e)?e:Date.now())}Number.isFinite(e)&&e>0?this.targetTime=Date.now()+1e3*e:this.targetTime=Date.now()}getRemaining(){const t=this.targetTime-Date.now();return t<=0?{days:0,hours:0,minutes:0,seconds:0,total:0}:{days:Math.floor(t/864e5),hours:Math.floor(t/36e5%24),minutes:Math.floor(t/6e4%60),seconds:Math.floor(t/1e3%60),total:t}}stop(){null!==this.timer&&(window.clearInterval(this.timer),this.timer=null)}start(){this.stop(),this.render(),this.timer=window.setInterval(()=>{const t=this.getRemaining();this.render(),this.dispatchEvent(new CustomEvent("db-tick",{detail:t,bubbles:!0,composed:!0})),t.total<=0&&(this.stop(),this.dispatchEvent(new CustomEvent("db-complete",{bubbles:!0,composed:!0})))},1e3)}two(t){return String(t).padStart(2,"0")}render(){const t=this.optionAttr("size",i,"m"),s=this.optionAttr("variant",a,"default"),o=this.boolAttr("show-labels",!0),n=this.getRemaining();this.className=["designbase-wc-countdown",`designbase-wc-countdown--${t}`,`designbase-wc-countdown--${s}`,o&&"designbase-wc-countdown--with-labels",n.total<=0&&"designbase-wc-countdown--expired"].filter(Boolean).join(" ");const r={days:this.getAttribute("label-days")||e("countdown.days"),hours:this.getAttribute("label-hours")||e("countdown.hours"),minutes:this.getAttribute("label-minutes")||e("countdown.minutes"),seconds:this.getAttribute("label-seconds")||e("countdown.seconds")},d=[{key:"days",value:n.days,show:this.boolAttr("show-days",!0)},{key:"hours",value:n.hours,show:this.boolAttr("show-hours",!0)},{key:"minutes",value:n.minutes,show:this.boolAttr("show-minutes",!0)},{key:"seconds",value:n.seconds,show:this.boolAttr("show-seconds",!0)}].filter(t=>t.show),u=[];for(let t=0;t<d.length;t+=1){const e=d[t],n=document.createElement("div");n.className="designbase-wc-countdown__unit";const i=document.createElement("div");if(i.className="designbase-wc-countdown__value",i.textContent=this.two(e.value),n.append(i),o){const t=document.createElement("div");t.className="designbase-wc-countdown__label",t.textContent=r[e.key],n.append(t)}if(u.push(n),t<d.length-1&&"minimal"!==s){const t=document.createElement("div");t.className="designbase-wc-countdown__separator",t.textContent=":",u.push(t)}}this.replaceChildren(...u)}}customElements.get("db-countdown")||customElements.define("db-countdown",DbCountdown);export{DbCountdown};
@@ -19,9 +19,12 @@ declare class DbDatePicker extends HTMLElement {
19
19
  private tempValue?;
20
20
  private activePresetId;
21
21
  private inputText;
22
+ private unsubscribeLocale?;
23
+ private lastLocale;
22
24
  private boundDocumentMouseDown;
23
25
  connectedCallback(): void;
24
26
  disconnectedCallback(): void;
27
+ private syncLocale;
25
28
  /** 열린 달력은 Escape 로 닫히고 포커스는 트리거로 돌아간다 (A11Y-ESCAPE) */
26
29
  private handleDocumentKeyDown;
27
30
  private boundDocumentKeyDown;
@@ -1 +1 @@
1
- import{dbText as t}from"../core/i18n.js";import{createDbIcon as e,getDbComponentIconSize as i}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{resolveDateLocale as s,startOfDay as n,parseISODate as a,DEFAULT_DATE_PICKER_PRESETS as r,formatDisplayDate as l,toISODate as d,detectActivePresetId as o,addMonths as h,generateWeekdays as u,generateCalendarGrid as c,formatPanelInputDate as p}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as m,DATE_PICKER_VARIANTS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const b="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}attributeChangedCallback(t){if(this.built){if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return s(this.getAttribute("locale"))}set locale(t){this.setAttribute("locale",t||"")}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return n(new Date)}get minDate(){return a(this.getAttribute("min-date"))}get maxDate(){return a(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?r.map(e=>({...e,label:t(e.label)})):[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${b}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${b}__trigger`;const e=document.createElement("button");e.type="button",e.className=`${b}__icon-display`,e.setAttribute("aria-label",t("날짜 선택 열기")),e.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${b}__input`,this.inputEl.setAttribute("aria-label",t("날짜 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${b}__toggle`,i.setAttribute("aria-label",t("날짜 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(e,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${b}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=a(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=a(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(a(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return a(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t){if(!t)return"";if("string"==typeof t){const e=a(t);return e?l(e,this.locale):""}if(Array.isArray(t))return t.map(t=>a(t)).filter(Boolean).map(t=>l(t,this.locale)).join(", ");const e=a(t.start),i=a(t.end);return e&&i?t.start===t.end?l(e,this.locale):`${l(e,this.locale)} ~ ${l(i,this.locale)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=d(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=d(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:d(t),end:d(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:d(s),end:d(i)}:{start:d(i),end:d(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:d(e.start),end:d(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=a(t);if(e&&this.isDateValid(e)){const t=d(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}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))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=d(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||d(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=a(t.start),i=a(t.end))}if(!e)return!1;const s=d(t),n=d(e),r=i?d(i):n;return s>=n&&s<=r}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),s=t.toDateString()===this.today.toDateString(),n=this.isDateSelected(t),r=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=a(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?a(o.end)?.toDateString():void 0,u=isRangeValue(o)?a(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${b}__date`,!i&&this.showOutsideDays&&`${b}__date--outside`,s&&`${b}__date--today`,n&&`${b}__date--selected`,r&&!n&&`${b}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${b}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${b}__date--range-end`,l&&`${b}__date--weekend`,!this.isDateValid(t)&&`${b}__date--disabled`,d.length>0&&`${b}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${b}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${b}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${b}__event ${b}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(s,n={}){const{showPrev:a=!1,showNext:r=!1}=n,l=this.getAttribute("size")||"m",d=i(l),o=document.createElement("div");o.className=`${b}__month`;const p=document.createElement("div");if(p.className=`${b}__header`,a){const i=document.createElement("button");i.type="button",i.className=`${b}__nav-button`,i.setAttribute("aria-label",t("이전 달")),i.disabled=this.disabled||this.readonly,i.appendChild(e("chevron-left",d)),i.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,-1):this.currentMonth=h(this.currentMonth,-1),this.renderCalendar()}),p.appendChild(i)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}const m=document.createElement("div");if(m.className=`${b}__current-month`,m.textContent=s.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),p.appendChild(m),r){const i=document.createElement("button");i.type="button",i.className=`${b}__nav-button`,i.setAttribute("aria-label",t("다음 달")),i.disabled=this.disabled||this.readonly,i.appendChild(e("chevron-right",d)),i.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,1):this.currentMonth=h(this.currentMonth,1),this.renderCalendar()}),p.appendChild(i)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}o.appendChild(p);const g=document.createElement("div");g.className=`${b}__weekdays`,u(this.startOfWeek,this.locale).forEach(t=>{const e=document.createElement("div");e.className=`${b}__weekday`,e.textContent=t,g.appendChild(e)}),o.appendChild(g);const v=document.createElement("div");v.className=`${b}__grid`;const y=this.isPanelLayout;return c(s,this.startOfWeek,y).forEach((t,e)=>{if(!t){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void v.appendChild(t)}const i=t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear();if(!this.showOutsideDays&&!i){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void v.appendChild(t)}v.appendChild(this.renderDateCell(t,s))}),o.appendChild(v),o}renderDefaultCalendar(){const e=document.createElement("div");e.className=`${b}__selector`;const i=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(e.appendChild(this.renderSingleMonth(i,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const i=document.createElement("div");i.className=`${b}__footer`;const s=document.createElement("button");s.type="button",s.className=`${b}__today-button`,s.textContent=t("오늘"),s.disabled=this.disabled||this.readonly,s.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),i.appendChild(s),e.appendChild(i)}return e}renderPanelCalendar(){const e=document.createElement("div");e.className=`${b}__panel`;const i=document.createElement("div");i.className=`${b}__presets`,i.setAttribute("role","listbox"),i.setAttribute("aria-label",t("기간 프리셋")),this.presets.forEach(t=>{const e=document.createElement("button");e.type="button",e.className=[`${b}__preset`,this.activePresetId===t.id&&`${b}__preset--active`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(this.activePresetId===t.id)),e.textContent=t.label,e.addEventListener("click",()=>this.handlePresetSelect(t)),i.appendChild(e)}),e.appendChild(i);const s=document.createElement("div");s.className=`${b}__panel-main`;const n=document.createElement("div");n.className=`${b}__months ${b}__months--count-2`,[0,1].forEach(t=>{const e=h(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),s.appendChild(n);const r=document.createElement("div");r.className=`${b}__panel-footer`;const l=isRangeValue(this.tempValue)?this.tempValue:void 0,d=document.createElement("div");d.className=`${b}__range-display`;const o=document.createElement("span");o.className=`${b}__range-text`,o.textContent=l?.start&&a(l.start)?p(a(l.start),this.locale):"시작일";const u=document.createElement("span");u.className=`${b}__range-separator`,u.textContent="–";const c=document.createElement("span");c.className=`${b}__range-text`,c.textContent=l?.end&&a(l.end)?p(a(l.end),this.locale):"종료일",d.append(o,u,c),r.appendChild(d);const m=document.createElement("div");m.className=`${b}__panel-actions`;const g=document.createElement("db-button");g.setAttribute("variant","secondary"),g.setAttribute("size","m"),g.textContent=t("취소"),g.addEventListener("click",()=>this.handlePendingCancel());const v=document.createElement("db-button");return v.setAttribute("variant","primary"),v.setAttribute("size","m"),v.textContent=t("적용"),v.addEventListener("click",()=>this.handlePendingApply()),m.append(g,v),r.appendChild(m),s.appendChild(r),e.appendChild(s),e}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const s=m.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",n=g.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",a=this.getAttribute("dropdown-position")||"bottom-start",r=i(s);if(this.className=[b,this.inline?`${b}--size-${s}`:`${b}--${s}`,`${b}--variant-${n}`,this.hasAttribute("full-width")&&`${b}--full-width`,this.disabled&&`${b}--disabled`,this.readonly&&`${b}--readonly`,this.isOpen&&`${b}--open`,this.hasAttribute("error")&&`${b}--error`,this.isPanelLayout&&`${b}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const l=this.getAttribute("label")||"";this.labelEl.textContent=l,this.labelEl.hidden=!l,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${b}__icon-display`);d&&(d.innerHTML="",d.appendChild(e("calendar",r)),d.disabled=this.disabled);const o=this.triggerEl.querySelector(`.${b}__toggle`);if(o&&(o.innerHTML="",o.appendChild(e("chevron-down",r)),o.disabled=this.disabled),this.dropdownEl.className=[`${b}__dropdown`,`${b}__dropdown--${a}`,this.isPanelLayout&&`${b}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const e=document.createElement("db-modal");e.setAttribute("open","true"),e.setAttribute("title",this.isPanelLayout?"기간 선택":"날짜 선택"),e.setAttribute("size",this.isPanelLayout?"l":"s"),e.addEventListener("db-close",()=>this.handlePendingCancel());const i=document.createElement("div");if(this.calendarHost=i,this.renderCalendar(),e.append(i),this.usesPendingValue){const i=document.createElement("div");i.className=`${b}__modal-footer`;const s=document.createElement("db-button");s.setAttribute("variant","secondary"),s.setAttribute("size","m"),s.textContent=t("취소"),s.addEventListener("click",()=>this.handlePendingCancel());const n=document.createElement("db-button");n.setAttribute("variant","primary"),n.setAttribute("size","m"),n.textContent=t("적용"),n.addEventListener("click",()=>this.handlePendingApply()),i.append(s,n),e.append(i)}this.appendChild(e)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
1
+ import{subscribeDbLocale as t,dbText as e}from"../core/i18n.js";import{createDbIcon as i,getDbComponentIconSize as s}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{resolveDateLocale as n,startOfDay as a,parseISODate as r,DEFAULT_DATE_PICKER_PRESETS as l,formatDisplayDate as d,toISODate as o,detectActivePresetId as h,addMonths as u,generateWeekdays as c,generateCalendarGrid as p,formatPanelInputDate as m}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as b,DATE_PICKER_VARIANTS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const v="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.lastLocale="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.lastLocale=this.locale,this.unsubscribeLocale?.(),this.unsubscribeLocale=t(()=>this.syncLocale()),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}syncLocale(){const t=this.formatDisplay(this.selectedValue,this.lastLocale||this.locale);this.lastLocale=this.locale,this.inputEl&&document.activeElement!==this.inputEl&&this.inputText===t&&this.syncInputText(),this.inputEl&&(this.inputEl.placeholder=e(this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요"),this.inputEl.setAttribute("aria-label",e("날짜 입력"))),this.triggerEl?.querySelectorAll(`.${v}__icon-display, .${v}__toggle`).forEach(t=>t.setAttribute("aria-label",e("날짜 선택 열기")));const i=this.querySelector("db-modal");i&&i.setAttribute("title",e(this.isPanelLayout?"기간 선택":"날짜 선택"));const s=this.querySelectorAll(`.${v}__modal-footer db-button`);s[0]&&(s[0].textContent=e("취소")),s[1]&&(s[1].textContent=e("적용"));const n=document.activeElement,a=(this.calendarHost?Array.from(this.calendarHost.querySelectorAll("button, db-button")):[]).findIndex(t=>t===n||t.contains(n));this.renderCalendar(),a>=0&&this.calendarHost?.querySelectorAll("button, db-button")[a]?.focus({preventScroll:!0})}attributeChangedCallback(t){if(this.built){if("locale"===t){const t=this.formatDisplay(this.selectedValue,this.lastLocale||this.locale);this.lastLocale=this.locale,this.inputText===t&&document.activeElement!==this.inputEl&&this.syncInputText()}if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return n(this.getAttribute("locale"))}set locale(t){this.setAttribute("locale",t||"")}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return a(new Date)}get minDate(){return r(this.getAttribute("min-date"))}get maxDate(){return r(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?l.map(t=>({...t,label:e(t.label)})):[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${v}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${v}__trigger`;const t=document.createElement("button");t.type="button",t.className=`${v}__icon-display`,t.setAttribute("aria-label",e("날짜 선택 열기")),t.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${v}__input`,this.inputEl.setAttribute("aria-label",e("날짜 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${v}__toggle`,i.setAttribute("aria-label",e("날짜 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(t,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${v}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=r(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=r(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(r(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return r(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t,e=this.locale){if(!t)return"";if("string"==typeof t){const i=r(t);return i?d(i,e):""}if(Array.isArray(t))return t.map(t=>r(t)).filter(Boolean).map(t=>d(t,e)).join(", ");const i=r(t.start),s=r(t.end);return i&&s?t.start===t.end?d(i,e):`${d(i,e)} ~ ${d(s,e)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=o(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=o(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:o(t),end:o(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:o(s),end:o(i)}:{start:o(i),end:o(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:o(e.start),end:o(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=h(isRangeValue(this.selectedValue)?{start:r(this.selectedValue.start),end:r(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=r(t);if(e&&this.isDateValid(e)){const t=o(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}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))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=h(isRangeValue(this.selectedValue)?{start:r(this.selectedValue.start),end:r(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=o(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||o(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=r(t.start),i=r(t.end))}if(!e)return!1;const s=o(t),n=o(e),a=i?o(i):n;return s>=n&&s<=a}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),s=t.toDateString()===this.today.toDateString(),n=this.isDateSelected(t),a=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=r(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?r(o.end)?.toDateString():void 0,u=isRangeValue(o)?r(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${v}__date`,!i&&this.showOutsideDays&&`${v}__date--outside`,s&&`${v}__date--today`,n&&`${v}__date--selected`,a&&!n&&`${v}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${v}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${v}__date--range-end`,l&&`${v}__date--weekend`,!this.isDateValid(t)&&`${v}__date--disabled`,d.length>0&&`${v}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${v}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${v}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${v}__event ${v}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(t,n={}){const{showPrev:a=!1,showNext:r=!1}=n,l=this.getAttribute("size")||"m",d=s(l),o=document.createElement("div");o.className=`${v}__month`;const h=document.createElement("div");if(h.className=`${v}__header`,a){const t=document.createElement("button");t.type="button",t.className=`${v}__nav-button`,t.setAttribute("aria-label",e("이전 달")),t.disabled=this.disabled||this.readonly,t.appendChild(i("chevron-left",d)),t.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=u(this.viewStartMonth,-1):this.currentMonth=u(this.currentMonth,-1),this.renderCalendar()}),h.appendChild(t)}else{const t=document.createElement("span");t.className=`${v}__nav-spacer`,t.setAttribute("aria-hidden","true"),h.appendChild(t)}const m=document.createElement("div");if(m.className=`${v}__current-month`,m.textContent=t.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),h.appendChild(m),r){const t=document.createElement("button");t.type="button",t.className=`${v}__nav-button`,t.setAttribute("aria-label",e("다음 달")),t.disabled=this.disabled||this.readonly,t.appendChild(i("chevron-right",d)),t.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=u(this.viewStartMonth,1):this.currentMonth=u(this.currentMonth,1),this.renderCalendar()}),h.appendChild(t)}else{const t=document.createElement("span");t.className=`${v}__nav-spacer`,t.setAttribute("aria-hidden","true"),h.appendChild(t)}o.appendChild(h);const b=document.createElement("div");b.className=`${v}__weekdays`,c(this.startOfWeek,this.locale).forEach(t=>{const e=document.createElement("div");e.className=`${v}__weekday`,e.textContent=t,b.appendChild(e)}),o.appendChild(b);const g=document.createElement("div");g.className=`${v}__grid`;const y=this.isPanelLayout;return p(t,this.startOfWeek,y).forEach((e,i)=>{if(!e){const t=document.createElement("span");return t.className=`${v}__date ${v}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void g.appendChild(t)}const s=e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear();if(!this.showOutsideDays&&!s){const t=document.createElement("span");return t.className=`${v}__date ${v}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void g.appendChild(t)}g.appendChild(this.renderDateCell(e,t))}),o.appendChild(g),o}renderDefaultCalendar(){const t=document.createElement("div");t.className=`${v}__selector`;const i=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(t.appendChild(this.renderSingleMonth(i,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const i=document.createElement("div");i.className=`${v}__footer`;const s=document.createElement("button");s.type="button",s.className=`${v}__today-button`,s.textContent=e("오늘"),s.disabled=this.disabled||this.readonly,s.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),i.appendChild(s),t.appendChild(i)}return t}renderPanelCalendar(){const t=document.createElement("div");t.className=`${v}__panel`;const i=document.createElement("div");i.className=`${v}__presets`,i.setAttribute("role","listbox"),i.setAttribute("aria-label",e("기간 프리셋")),this.presets.forEach(t=>{const e=document.createElement("button");e.type="button",e.className=[`${v}__preset`,this.activePresetId===t.id&&`${v}__preset--active`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(this.activePresetId===t.id)),e.textContent=t.label,e.addEventListener("click",()=>this.handlePresetSelect(t)),i.appendChild(e)}),t.appendChild(i);const s=document.createElement("div");s.className=`${v}__panel-main`;const n=document.createElement("div");n.className=`${v}__months ${v}__months--count-2`,[0,1].forEach(t=>{const e=u(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),s.appendChild(n);const a=document.createElement("div");a.className=`${v}__panel-footer`;const l=isRangeValue(this.tempValue)?this.tempValue:void 0,d=document.createElement("div");d.className=`${v}__range-display`;const o=document.createElement("span");o.className=`${v}__range-text`,o.textContent=l?.start&&r(l.start)?m(r(l.start),this.locale):e("시작일");const h=document.createElement("span");h.className=`${v}__range-separator`,h.textContent="–";const c=document.createElement("span");c.className=`${v}__range-text`,c.textContent=l?.end&&r(l.end)?m(r(l.end),this.locale):e("종료일"),d.append(o,h,c),a.appendChild(d);const p=document.createElement("div");p.className=`${v}__panel-actions`;const b=document.createElement("db-button");b.setAttribute("variant","secondary"),b.setAttribute("size","m"),b.textContent=e("취소"),b.addEventListener("click",()=>this.handlePendingCancel());const g=document.createElement("db-button");return g.setAttribute("variant","primary"),g.setAttribute("size","m"),g.textContent=e("적용"),g.addEventListener("click",()=>this.handlePendingApply()),p.append(b,g),a.appendChild(p),s.appendChild(a),t.appendChild(s),t}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const t=b.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",n=g.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",a=this.getAttribute("dropdown-position")||"bottom-start",r=s(t);if(this.className=[v,this.inline?`${v}--size-${t}`:`${v}--${t}`,`${v}--variant-${n}`,this.hasAttribute("full-width")&&`${v}--full-width`,this.disabled&&`${v}--disabled`,this.readonly&&`${v}--readonly`,this.isOpen&&`${v}--open`,this.hasAttribute("error")&&`${v}--error`,this.isPanelLayout&&`${v}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const l=this.getAttribute("label")||"";this.labelEl.textContent=l,this.labelEl.hidden=!l,this.inputEl.value=this.inputText,this.inputEl.placeholder=e(this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요"),this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${v}__icon-display`);d&&(d.innerHTML="",d.appendChild(i("calendar",r)),d.disabled=this.disabled);const o=this.triggerEl.querySelector(`.${v}__toggle`);if(o&&(o.innerHTML="",o.appendChild(i("chevron-down",r)),o.disabled=this.disabled),this.dropdownEl.className=[`${v}__dropdown`,`${v}__dropdown--${a}`,this.isPanelLayout&&`${v}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const t=document.createElement("db-modal");t.setAttribute("open","true"),t.setAttribute("title",e(this.isPanelLayout?"기간 선택":"날짜 선택")),t.setAttribute("size",this.isPanelLayout?"l":"s"),t.addEventListener("db-close",()=>this.handlePendingCancel());const i=document.createElement("div");if(this.calendarHost=i,this.renderCalendar(),t.append(i),this.usesPendingValue){const i=document.createElement("div");i.className=`${v}__modal-footer`;const s=document.createElement("db-button");s.setAttribute("variant","secondary"),s.setAttribute("size","m"),s.textContent=e("취소"),s.addEventListener("click",()=>this.handlePendingCancel());const n=document.createElement("db-button");n.setAttribute("variant","primary"),n.setAttribute("size","m"),n.textContent=e("적용"),n.addEventListener("click",()=>this.handlePendingApply()),i.append(s,n),t.append(i)}this.appendChild(t)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
@@ -6,6 +6,7 @@ interface DbDropdownItem {
6
6
  divider?: boolean;
7
7
  }
8
8
  declare class DbDropdown extends HTMLElement {
9
+ private unsubscribeLocale?;
9
10
  static get observedAttributes(): string[];
10
11
  private triggerWrap?;
11
12
  private defaultTrigger?;