@designbasekorea/ui-wc 0.8.13 → 0.9.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 (185) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE-PAYMENT-LOGOS.md +437 -0
  3. package/README.md +51 -3
  4. package/dist/esm/components/db-achievement-list.d.ts +31 -0
  5. package/dist/esm/components/db-achievement-list.js +1 -0
  6. package/dist/esm/components/db-achievement-modal.d.ts +38 -0
  7. package/dist/esm/components/db-achievement-modal.js +1 -0
  8. package/dist/esm/components/db-ai-chain-of-thought.d.ts +14 -0
  9. package/dist/esm/components/db-ai-chain-of-thought.js +1 -0
  10. package/dist/esm/components/db-ai-chat.js +1 -1
  11. package/dist/esm/components/db-ai-checkpoint.d.ts +14 -0
  12. package/dist/esm/components/db-ai-checkpoint.js +1 -0
  13. package/dist/esm/components/db-ai-confirmation.d.ts +14 -0
  14. package/dist/esm/components/db-ai-confirmation.js +1 -0
  15. package/dist/esm/components/db-ai-context.d.ts +15 -0
  16. package/dist/esm/components/db-ai-context.js +1 -0
  17. package/dist/esm/components/db-ai-conversation.d.ts +21 -0
  18. package/dist/esm/components/db-ai-conversation.js +1 -0
  19. package/dist/esm/components/db-ai-execution-quote.d.ts +41 -0
  20. package/dist/esm/components/db-ai-execution-quote.js +1 -0
  21. package/dist/esm/components/db-ai-file-tree.d.ts +14 -0
  22. package/dist/esm/components/db-ai-file-tree.js +1 -0
  23. package/dist/esm/components/db-ai-glow.d.ts +1 -1
  24. package/dist/esm/components/db-ai-inline-citation.d.ts +16 -0
  25. package/dist/esm/components/db-ai-inline-citation.js +1 -0
  26. package/dist/esm/components/db-ai-message.d.ts +19 -0
  27. package/dist/esm/components/db-ai-message.js +1 -0
  28. package/dist/esm/components/db-ai-model-select.d.ts +36 -0
  29. package/dist/esm/components/db-ai-model-select.js +1 -0
  30. package/dist/esm/components/db-ai-plan.d.ts +14 -0
  31. package/dist/esm/components/db-ai-plan.js +1 -0
  32. package/dist/esm/components/db-ai-queue.d.ts +14 -0
  33. package/dist/esm/components/db-ai-queue.js +1 -0
  34. package/dist/esm/components/db-ai-reasoning.d.ts +14 -0
  35. package/dist/esm/components/db-ai-reasoning.js +1 -0
  36. package/dist/esm/components/db-ai-sources.d.ts +14 -0
  37. package/dist/esm/components/db-ai-sources.js +1 -0
  38. package/dist/esm/components/db-ai-stack-trace.d.ts +14 -0
  39. package/dist/esm/components/db-ai-stack-trace.js +1 -0
  40. package/dist/esm/components/db-ai-subagent.d.ts +14 -0
  41. package/dist/esm/components/db-ai-subagent.js +1 -0
  42. package/dist/esm/components/db-ai-task-status.d.ts +26 -0
  43. package/dist/esm/components/db-ai-task-status.js +1 -0
  44. package/dist/esm/components/db-ai-task.d.ts +14 -0
  45. package/dist/esm/components/db-ai-task.js +1 -0
  46. package/dist/esm/components/db-ai-terminal.d.ts +14 -0
  47. package/dist/esm/components/db-ai-terminal.js +1 -0
  48. package/dist/esm/components/db-ai-test-results.d.ts +14 -0
  49. package/dist/esm/components/db-ai-test-results.js +1 -0
  50. package/dist/esm/components/db-ai-tool.d.ts +14 -0
  51. package/dist/esm/components/db-ai-tool.js +1 -0
  52. package/dist/esm/components/db-attachment-list.d.ts +38 -0
  53. package/dist/esm/components/db-attachment-list.js +1 -0
  54. package/dist/esm/components/db-bento-card.d.ts +55 -0
  55. package/dist/esm/components/db-bento-card.js +1 -0
  56. package/dist/esm/components/db-bento-grid.d.ts +25 -0
  57. package/dist/esm/components/db-bento-grid.js +1 -0
  58. package/dist/esm/components/db-boarding-pass-stack.d.ts +49 -0
  59. package/dist/esm/components/db-boarding-pass-stack.js +1 -0
  60. package/dist/esm/components/db-boarding-pass.d.ts +32 -0
  61. package/dist/esm/components/db-boarding-pass.js +1 -0
  62. package/dist/esm/components/db-border-beam.d.ts +52 -0
  63. package/dist/esm/components/db-border-beam.js +1 -0
  64. package/dist/esm/components/db-button.d.ts +1 -1
  65. package/dist/esm/components/db-button.js +1 -1
  66. package/dist/esm/components/db-chat-composer.d.ts +2 -0
  67. package/dist/esm/components/db-chat-composer.js +1 -1
  68. package/dist/esm/components/db-chat-message.d.ts +1 -1
  69. package/dist/esm/components/db-chat-orb.d.ts +1 -1
  70. package/dist/esm/components/db-chat-widget.d.ts +1 -1
  71. package/dist/esm/components/db-color-picker.d.ts +1 -0
  72. package/dist/esm/components/db-color-picker.js +1 -1
  73. package/dist/esm/components/db-confetti.d.ts +90 -0
  74. package/dist/esm/components/db-confetti.js +1 -0
  75. package/dist/esm/components/db-context-bar.d.ts +13 -0
  76. package/dist/esm/components/db-context-bar.js +1 -0
  77. package/dist/esm/components/db-credit-balance.d.ts +17 -0
  78. package/dist/esm/components/db-credit-balance.js +1 -0
  79. package/dist/esm/components/db-credit-card.d.ts +51 -0
  80. package/dist/esm/components/db-credit-card.js +1 -0
  81. package/dist/esm/components/db-credit-dropdown.d.ts +31 -0
  82. package/dist/esm/components/db-credit-dropdown.js +1 -0
  83. package/dist/esm/components/db-credit-history.d.ts +31 -0
  84. package/dist/esm/components/db-credit-history.js +1 -0
  85. package/dist/esm/components/db-credit-recharge-modal.d.ts +35 -0
  86. package/dist/esm/components/db-credit-recharge-modal.js +1 -0
  87. package/dist/esm/components/db-credit-recharge.d.ts +39 -0
  88. package/dist/esm/components/db-credit-recharge.js +1 -0
  89. package/dist/esm/components/db-design-canvas.d.ts +137 -0
  90. package/dist/esm/components/db-design-canvas.js +1 -0
  91. package/dist/esm/components/db-design-toolbar.d.ts +60 -0
  92. package/dist/esm/components/db-design-toolbar.js +1 -0
  93. package/dist/esm/components/db-device-mockup.d.ts +100 -0
  94. package/dist/esm/components/db-device-mockup.js +1 -0
  95. package/dist/esm/components/db-download-progress.d.ts +1 -1
  96. package/dist/esm/components/db-drawer.js +1 -1
  97. package/dist/esm/components/db-dropdown.d.ts +2 -0
  98. package/dist/esm/components/db-dropdown.js +1 -1
  99. package/dist/esm/components/db-email-verify.d.ts +1 -1
  100. package/dist/esm/components/db-file-uploader.d.ts +10 -0
  101. package/dist/esm/components/db-filter-bar.d.ts +34 -0
  102. package/dist/esm/components/db-filter-bar.js +1 -0
  103. package/dist/esm/components/db-flight-status.d.ts +33 -0
  104. package/dist/esm/components/db-flight-status.js +1 -0
  105. package/dist/esm/components/db-floating-action-button.d.ts +24 -14
  106. package/dist/esm/components/db-floating-action-button.js +1 -1
  107. package/dist/esm/components/db-footer.d.ts +3 -0
  108. package/dist/esm/components/db-footer.js +1 -1
  109. package/dist/esm/components/db-glyph-matrix.d.ts +58 -0
  110. package/dist/esm/components/db-glyph-matrix.js +1 -0
  111. package/dist/esm/components/db-icons.d.ts +1 -1
  112. package/dist/esm/components/db-icons.js +1 -1
  113. package/dist/esm/components/db-menu-item.d.ts +2 -0
  114. package/dist/esm/components/db-menu-item.js +1 -1
  115. package/dist/esm/components/db-modal.d.ts +1 -1
  116. package/dist/esm/components/db-modal.js +1 -1
  117. package/dist/esm/components/db-navbar.d.ts +3 -1
  118. package/dist/esm/components/db-navbar.js +1 -1
  119. package/dist/esm/components/db-navigation-rail.d.ts +1 -1
  120. package/dist/esm/components/db-node.d.ts +83 -0
  121. package/dist/esm/components/db-node.js +1 -0
  122. package/dist/esm/components/db-notification-dropdown.d.ts +30 -0
  123. package/dist/esm/components/db-notification-dropdown.js +1 -0
  124. package/dist/esm/components/db-notification-inbox.d.ts +25 -0
  125. package/dist/esm/components/db-notification-inbox.js +1 -0
  126. package/dist/esm/components/db-otp-input.d.ts +1 -1
  127. package/dist/esm/components/db-phone-verify.d.ts +1 -1
  128. package/dist/esm/components/db-plan-overview.d.ts +26 -0
  129. package/dist/esm/components/db-plan-overview.js +1 -0
  130. package/dist/esm/components/db-popover.js +1 -1
  131. package/dist/esm/components/db-progressive-blur.d.ts +35 -0
  132. package/dist/esm/components/db-progressive-blur.js +1 -0
  133. package/dist/esm/components/db-receipt.d.ts +37 -0
  134. package/dist/esm/components/db-receipt.js +1 -0
  135. package/dist/esm/components/db-search-bar.js +1 -1
  136. package/dist/esm/components/db-segment-control.js +1 -1
  137. package/dist/esm/components/db-select.js +1 -1
  138. package/dist/esm/components/db-sidebar.d.ts +14 -1
  139. package/dist/esm/components/db-sidebar.js +1 -1
  140. package/dist/esm/components/db-split-view.d.ts +2 -0
  141. package/dist/esm/components/db-split-view.js +1 -1
  142. package/dist/esm/components/db-textarea.js +1 -1
  143. package/dist/esm/components/db-ticket.d.ts +18 -0
  144. package/dist/esm/components/db-ticket.js +1 -0
  145. package/dist/esm/components/db-time-picker.d.ts +1 -1
  146. package/dist/esm/components/db-tool-button.d.ts +57 -0
  147. package/dist/esm/components/db-tool-button.js +1 -0
  148. package/dist/esm/components/db-tweet-card.d.ts +101 -0
  149. package/dist/esm/components/db-tweet-card.js +1 -0
  150. package/dist/esm/components/db-two-factor.d.ts +1 -1
  151. package/dist/esm/components/db-voice-control.d.ts +25 -0
  152. package/dist/esm/components/db-voice-control.js +1 -0
  153. package/dist/esm/components/db-workspace-invite-modal.d.ts +51 -0
  154. package/dist/esm/components/db-workspace-invite-modal.js +1 -0
  155. package/dist/esm/components/db-workspace-members.d.ts +36 -0
  156. package/dist/esm/components/db-workspace-members.js +1 -0
  157. package/dist/esm/components/device-mockup-style.js +1 -0
  158. package/dist/esm/components/flight-route.js +1 -0
  159. package/dist/esm/components/node-style.js +1 -0
  160. package/dist/esm/components/paper-card.d.ts +26 -0
  161. package/dist/esm/components/paper-card.js +1 -0
  162. package/dist/esm/components/random-gradient-palettes.d.ts +4 -0
  163. package/dist/esm/core/ai-element.d.ts +47 -0
  164. package/dist/esm/core/ai-element.js +1 -0
  165. package/dist/esm/core/credit-ui.js +1 -0
  166. package/dist/esm/core/i18n.d.ts +153 -0
  167. package/dist/esm/core/i18n.js +1 -1
  168. package/dist/esm/core/notification-ui.d.ts +17 -0
  169. package/dist/esm/core/notification-ui.js +1 -0
  170. package/dist/esm/helpers/payment-brands.d.ts +56 -0
  171. package/dist/esm/helpers/payment-brands.js +1 -0
  172. package/dist/esm/helpers/toast.d.ts +2 -3
  173. package/dist/esm/index.d.ts +62 -2
  174. package/dist/esm/index.js +1 -1
  175. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  176. package/dist/esm/ui-contracts/dist/components.d.d.ts +76 -0
  177. package/dist/esm/ui-contracts/dist/primitives.d.d.ts +21 -0
  178. package/dist/index.cjs +1 -1
  179. package/dist/index.css +1 -1
  180. package/dist/index.d.ts +2149 -23
  181. package/dist/index.esm.js +1 -1
  182. package/dist/react/index.cjs +1 -1
  183. package/dist/react/index.d.ts +786 -6727
  184. package/dist/react/index.esm.js +1 -1
  185. package/package.json +13 -7
@@ -1 +1 @@
1
- import{hexToRgb as t,rgbToHsv as e,hsvToRgb as i,toHex as s,rgbToHsl as l,formatColor as n,normalizeHex as o,isHex as r,clamp as a}from"./color-picker-utils.js";import{getDbComponentIconSize as h,createDbIcon as d}from"./db-icons.js";import{rafThrottle as p}from"../core/dom.js";import{coerceToContract as u}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_PICKER_SIZES as c,COLOR_PICKER_POSITIONS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const m=c,E=["dropdown","modal"],b=["input","swatch"],v=g,y="#006FFF",I=t(y)??{r:0,g:111,b:255},w=e(I.r,I.g,I.b),A=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=w.h,this.s=w.s,this.v=w.v,this.a=100,this.open=!1,this.format="hex",this.colorInput=y,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.handleOutsideClick=t=>{if(!this.open||"dropdown"!==this.getOption("type",E,"dropdown"))return;const e=t.target;this.contains(e)||this.formatSelectEl?.contains(e)||(this.open=!1,this.update())},this.handleDocumentMouseMove=p(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 i=t(this.tempColor);if(i){const t=e(i.r,i.g,i.b);this.h=t.h,this.s=t.s,this.v=t.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)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleOutsideClick),document.removeEventListener("mousemove",this.handleDocumentMouseMove),document.removeEventListener("mouseup",this.handleDocumentMouseUp),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 u(this.getAttribute(t),e,i)}getIconSize(){return h(this.getOption("size",m,"m"))}getRgb(){return i(this.h,this.s,this.v)}getHex(){const t=this.getRgb();return s(t.r,t.g,t.b)}getHsl(){const t=this.getRgb();return l(t.r,t.g,t.b)}getUiFormatted(){const t=this.getRgb(),e=this.getHex(),i=this.getHsl();return n(this.format,t,e,i,this.a)}getOutward(){return"hex"===("ui"===this.getAttribute("on-change-format")?"ui":"hex")?this.getHex():this.getUiFormatted()}syncFromValueAttr(i){const s=this.getAttribute("value")??(i?this.getAttribute("default-value"):null)??(i?y:null);if(null==s)return;const l=o(s);if(!r(l))return;if(!i&&this.suppressNextValueSync&&l===this.lastEmittedHex)return void(this.suppressNextValueSync=!1);const n=t(l);if(!n)return;const a=e(n.r,n.g,n.b);this.h=a.h,this.s=a.s,this.v=a.v,this.colorInput=l,this.lastEmittedHex=l}actuallyEmit(){const t=o(this.getHex()),e=this.hasAttribute("value")&&r(this.getAttribute("value")||"")?o(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=a(t-s.left,0,s.width),n=a(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",m,"m")?"s":"m"}commitColorInput(i){const s="trigger"===i?this.triggerInputEl?.value??"":this.getInputValue(this.panelValueInputEl),l=s.trim();if(/^#([0-9A-Fa-f]{6})$/.test(l)){const i=t(l),s=e(i.r,i.g,i.b);return this.h=s.h,this.s=s.s,this.v=s.v,this.colorInput=o(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=a(parseInt(n[1],10),0,255),i=a(parseInt(n[2],10),0,255),s=a(parseInt(n[3],10),0,255),l=e(t,i,s);return this.h=l.h,this.s=l.s,this.v=l.v,this.colorInput=`rgb(${t}, ${i}, ${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=a(parseInt(n[1],10),0,255),i=a(parseInt(n[2],10),0,255),s=a(parseInt(n[3],10),0,255),l=parseFloat(n[4]),o=e(t,i,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}, ${i}, ${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 i=new window.EyeDropper,{sRGBHex:s}=await i.open(),l=t(s);if(!l)return;const n=e(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",E,"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",E,"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 e=document.createElement("div");e.className="designbase-wc-color-picker__color-display",this.colorBoxEl=document.createElement("div"),this.colorBoxEl.className="designbase-wc-color-picker__color-box",e.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?o(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 i=document.createElement("div");i.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(d("chevron-down",t)),i.append(this.triggerCopyBtn,this.toggleBtn),this.triggerEl.append(e,this.triggerInputEl,i),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 s=document.createElement("div");s.className="designbase-wc-color-picker__selector";const l=document.createElement("div");l.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))}),l.append(this.colorFieldEl);const n=document.createElement("div");n.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 r=document.createElement("div");r.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=a(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),r.append(h,this.alphaSliderWrapEl),n.append(this.eyedropperBtnEl,r);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",A),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?o(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 u=document.createElement("span");u.className="designbase-wc-color-picker__alpha-suffix",u.textContent="%",this.panelAlphaWrapEl.append(this.panelAlphaInputEl,u),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),s.append(l,n,p),this.selectorEl=s,this.dropdownEl.append(s),this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","s"),this.modalEl.setAttribute("title","색상 선택"),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 c=document.createElement("div");c.className="designbase-wc-modal__footer",c.setAttribute("data-modal-part","footer");const g=document.createElement("db-button");g.setAttribute("variant","tertiary"),g.setAttribute("size","m"),g.textContent="취소",g.addEventListener("click",this.handleModalCancel);const m=document.createElement("db-button");m.setAttribute("variant","primary"),m.setAttribute("size","m"),m.textContent="적용",m.addEventListener("click",this.handleModalApply),c.append(g,m),this.modalEl.append(this.modalBodyEl,c),this.replaceChildren(this.triggerEl,this.dropdownEl,this.modalEl)}updateCopyButtons(){const t=this.getIconSize(),e=this.isCopied?"done":"copy";this.triggerCopyBtn&&this.triggerCopyBtn.replaceChildren(d(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?o(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",m,"m"),e=this.getOption("type",E,"dropdown"),i=this.getOption("position",v,"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",b,"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{hexToRgb as t,rgbToHsv as e,hsvToRgb as i,toHex as s,rgbToHsl as l,formatColor as n,normalizeHex as o,isHex as a,clamp as r}from"./color-picker-utils.js";import{getDbComponentIconSize as h,createDbIcon as d}from"./db-icons.js";import{rafThrottle as p}from"../core/dom.js";import{coerceToContract as u}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{COLOR_PICKER_SIZES as c,COLOR_PICKER_POSITIONS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const E=c,m=["dropdown","modal"],b=["input","swatch"],v=g,y="#006FFF",I=t(y)??{r:0,g:111,b:255},w=e(I.r,I.g,I.b),A=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=w.h,this.s=w.s,this.v=w.v,this.a=100,this.open=!1,this.format="hex",this.colorInput=y,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",m,"dropdown")&&(t.preventDefault(),this.close(),this.toggleBtn?.focus())},this.handleOutsideClick=t=>{if(!this.open||"dropdown"!==this.getOption("type",m,"dropdown"))return;const e=t.target;this.contains(e)||this.formatSelectEl?.contains(e)||(this.open=!1,this.update())},this.handleDocumentMouseMove=p(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 i=t(this.tempColor);if(i){const t=e(i.r,i.g,i.b);this.h=t.h,this.s=t.s,this.v=t.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 u(this.getAttribute(t),e,i)}getIconSize(){return h(this.getOption("size",E,"m"))}getRgb(){return i(this.h,this.s,this.v)}getHex(){const t=this.getRgb();return s(t.r,t.g,t.b)}getHsl(){const t=this.getRgb();return l(t.r,t.g,t.b)}getUiFormatted(){const t=this.getRgb(),e=this.getHex(),i=this.getHsl();return n(this.format,t,e,i,this.a)}getOutward(){return"hex"===("ui"===this.getAttribute("on-change-format")?"ui":"hex")?this.getHex():this.getUiFormatted()}syncFromValueAttr(i){const s=this.getAttribute("value")??(i?this.getAttribute("default-value"):null)??(i?y:null);if(null==s)return;const l=o(s);if(!a(l))return;if(!i&&this.suppressNextValueSync&&l===this.lastEmittedHex)return void(this.suppressNextValueSync=!1);const n=t(l);if(!n)return;const r=e(n.r,n.g,n.b);this.h=r.h,this.s=r.s,this.v=r.v,this.colorInput=l,this.lastEmittedHex=l}actuallyEmit(){const t=o(this.getHex()),e=this.hasAttribute("value")&&a(this.getAttribute("value")||"")?o(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=r(t-s.left,0,s.width),n=r(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(i){const s="trigger"===i?this.triggerInputEl?.value??"":this.getInputValue(this.panelValueInputEl),l=s.trim();if(/^#([0-9A-Fa-f]{6})$/.test(l)){const i=t(l),s=e(i.r,i.g,i.b);return this.h=s.h,this.s=s.s,this.v=s.v,this.colorInput=o(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=r(parseInt(n[1],10),0,255),i=r(parseInt(n[2],10),0,255),s=r(parseInt(n[3],10),0,255),l=e(t,i,s);return this.h=l.h,this.s=l.s,this.v=l.v,this.colorInput=`rgb(${t}, ${i}, ${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=r(parseInt(n[1],10),0,255),i=r(parseInt(n[2],10),0,255),s=r(parseInt(n[3],10),0,255),l=parseFloat(n[4]),o=e(t,i,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}, ${i}, ${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 i=new window.EyeDropper,{sRGBHex:s}=await i.open(),l=t(s);if(!l)return;const n=e(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",m,"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",m,"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 e=document.createElement("div");e.className="designbase-wc-color-picker__color-display",this.colorBoxEl=document.createElement("div"),this.colorBoxEl.className="designbase-wc-color-picker__color-box",e.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?o(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 i=document.createElement("div");i.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(d("chevron-down",t)),i.append(this.triggerCopyBtn,this.toggleBtn),this.triggerEl.append(e,this.triggerInputEl,i),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 s=document.createElement("div");s.className="designbase-wc-color-picker__selector";const l=document.createElement("div");l.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))}),l.append(this.colorFieldEl);const n=document.createElement("div");n.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=r(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),n.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",A),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?o(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 u=document.createElement("span");u.className="designbase-wc-color-picker__alpha-suffix",u.textContent="%",this.panelAlphaWrapEl.append(this.panelAlphaInputEl,u),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),s.append(l,n,p),this.selectorEl=s,this.dropdownEl.append(s),this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","s"),this.modalEl.setAttribute("title","색상 선택"),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 c=document.createElement("div");c.className="designbase-wc-modal__footer",c.setAttribute("data-modal-part","footer");const g=document.createElement("db-button");g.setAttribute("variant","tertiary"),g.setAttribute("size","m"),g.textContent="취소",g.addEventListener("click",this.handleModalCancel);const E=document.createElement("db-button");E.setAttribute("variant","primary"),E.setAttribute("size","m"),E.textContent="적용",E.addEventListener("click",this.handleModalApply),c.append(g,E),this.modalEl.append(this.modalBodyEl,c),this.replaceChildren(this.triggerEl,this.dropdownEl,this.modalEl)}updateCopyButtons(){const t=this.getIconSize(),e=this.isCopied?"done":"copy";this.triggerCopyBtn&&this.triggerCopyBtn.replaceChildren(d(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?o(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",m,"dropdown"),i=this.getOption("position",v,"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",b,"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};
@@ -0,0 +1,90 @@
1
+ import { ConfettiMode, ConfettiTrigger, ConfettiShape } from '../ui-contracts/dist/components.d.js';
2
+
3
+ interface ConfettiParticleOptions {
4
+ particleCount?: number;
5
+ angle?: number;
6
+ spread?: number;
7
+ startVelocity?: number;
8
+ decay?: number;
9
+ gravity?: number;
10
+ drift?: number;
11
+ ticks?: number;
12
+ origin?: {
13
+ x: number;
14
+ y: number;
15
+ };
16
+ colors?: string[];
17
+ shapes?: ConfettiShape[];
18
+ scalar?: number;
19
+ zIndex?: number;
20
+ disableForReducedMotion?: boolean;
21
+ }
22
+ interface ConfettiFireworkOptions {
23
+ duration?: number;
24
+ interval?: number;
25
+ particleCount?: number;
26
+ colors?: string[];
27
+ }
28
+ declare class DbConfetti extends HTMLElement {
29
+ static get observedAttributes(): string[];
30
+ private built;
31
+ private canvas?;
32
+ private ctx?;
33
+ private particles;
34
+ private animationId;
35
+ private fireworkTimer;
36
+ private resizeObserver?;
37
+ private clickHandler;
38
+ get mode(): ConfettiMode;
39
+ set mode(value: ConfettiMode);
40
+ get trigger(): ConfettiTrigger;
41
+ set trigger(value: ConfettiTrigger);
42
+ get particleCount(): number;
43
+ set particleCount(value: number);
44
+ get spread(): number;
45
+ set spread(value: number);
46
+ get originX(): number;
47
+ set originX(value: number);
48
+ get originY(): number;
49
+ set originY(value: number);
50
+ get colors(): string[];
51
+ set colors(value: string[]);
52
+ get shapes(): ConfettiShape[];
53
+ set shapes(value: ConfettiShape[]);
54
+ get duration(): number;
55
+ set duration(value: number);
56
+ get fullscreen(): boolean;
57
+ set fullscreen(value: boolean);
58
+ connectedCallback(): void;
59
+ disconnectedCallback(): void;
60
+ attributeChangedCallback(name: string, _oldVal: string | null, _newVal: string | null): void;
61
+ private build;
62
+ private updateCanvasSize;
63
+ private sync;
64
+ fire(opts?: ConfettiParticleOptions): void;
65
+ fireworks(options?: ConfettiFireworkOptions): void;
66
+ cannon(): void;
67
+ stars(): void;
68
+ pride(): void;
69
+ snow(): void;
70
+ fireByMode(): void;
71
+ private drawStar;
72
+ private loop;
73
+ }
74
+ declare global {
75
+ interface HTMLElementTagNameMap {
76
+ 'db-confetti': DbConfetti;
77
+ }
78
+ }
79
+ interface ConfettiFunction {
80
+ (options?: ConfettiParticleOptions): void;
81
+ fireworks(options?: ConfettiFireworkOptions): void;
82
+ cannon(options?: ConfettiParticleOptions): void;
83
+ stars(): void;
84
+ pride(): void;
85
+ snow(): void;
86
+ }
87
+ declare const confetti: ConfettiFunction;
88
+
89
+ export { DbConfetti, confetti };
90
+ export type { ConfettiFireworkOptions, ConfettiFunction, ConfettiParticleOptions };
@@ -0,0 +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};
@@ -0,0 +1,13 @@
1
+ import { DbDesignToolbar } from './db-design-toolbar.js';
2
+
3
+ /** Compact contextual actions. The consumer owns selection, visibility and positioning. */
4
+ declare class DbContextBar extends DbDesignToolbar {
5
+ connectedCallback(): void;
6
+ }
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'db-context-bar': DbContextBar;
10
+ }
11
+ }
12
+
13
+ export { DbContextBar };
@@ -0,0 +1 @@
1
+ import{DbDesignToolbar as t}from"./db-design-toolbar.js";class DbContextBar extends t{connectedCallback(){this.hasAttribute("aria-label")||this.setAttribute("aria-label","선택 요소 작업"),super.connectedCallback(),this.classList.add("designbase-wc-context-bar")}}customElements.get("db-context-bar")||customElements.define("db-context-bar",DbContextBar);export{DbContextBar};
@@ -0,0 +1,17 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+ import './db-button.js';
3
+
4
+ /** Server-supplied available balance; held/spent are separate amounts, never subtracted here. */
5
+ declare class DbCreditBalance extends DbElement {
6
+ static get observedAttributes(): string[];
7
+ connectedCallback(): void;
8
+ attributeChangedCallback(): void;
9
+ private render;
10
+ }
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ 'db-credit-balance': DbCreditBalance;
14
+ }
15
+ }
16
+
17
+ export { DbCreditBalance };
@@ -0,0 +1 @@
1
+ import{DbElement as t}from"../core/base-element.js";import{creditNumber as e,textNode as i,creditText as a,creditAction as r,replaceView as s}from"../core/credit-ui.js";import{t as n}from"../core/i18n.js";import"./db-button.js";class DbCreditBalance extends t{static get observedAttributes(){return["available","held","spent","label","unit","low-threshold","loading","error","recharge-label","disabled","compact"]}connectedCallback(){this.cleanups.listen(this,"db-click",t=>{t.target instanceof HTMLElement&&"recharge"===t.target.dataset.action&&(this.hasAttribute("disabled")||this.hasAttribute("loading")||this.hasAttribute("error")||this.dbEmit("recharge"))}),this.render()}attributeChangedCallback(){this.isConnected&&this.render()}render(){this.classList.add("designbase-wc-credit-balance");const t="designbase-wc-credit-balance",l=this.hasAttribute("loading"),d=this.getAttribute("error"),b=e(this.getAttribute("available")),c=e(this.getAttribute("low-threshold"));this.toggleAttribute("data-low",null!==b&&null!==c&&b<=c),this.setAttribute("aria-busy",String(l));const o=i("div",`${t}__content`,"");o.append(i("span",`${t}__label`,this.getAttribute("label")||n("credits.available")));const h=i("div",`${t}__value`,l?n("loading"):d?"—":a(b));if(h.setAttribute("role","status"),h.setAttribute("aria-atomic","true"),l||d||h.append(i("span",`${t}__unit`,this.getAttribute("unit")||n("credits.unit"))),o.append(h),d){const e=i("p",`${t}__error`,d);e.setAttribute("role","alert"),o.append(e)}else if(!l){const r=i("div",`${t}__meta`,"");for(const[t,s]of[["held","credits.held"],["spent","credits.spent"]])this.hasAttribute(t)&&r.append(i("span","",`${n(s)} ${a(e(this.getAttribute(t)))}`));o.append(r),this.hasAttribute("data-low")&&o.append(i("p",`${t}__warning`,n("credits.low")))}const u=[o],p=this.getAttribute("recharge-label");p&&u.push(r("recharge",p,l||this.hasAttribute("error")||this.hasAttribute("disabled"))),s(this,...u)}}customElements.get("db-credit-balance")||customElements.define("db-credit-balance",DbCreditBalance);export{DbCreditBalance};
@@ -0,0 +1,51 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+
3
+ declare const ORIENTATIONS: readonly ["horizontal", "vertical"];
4
+ declare const VARIANTS: readonly ["default", "contrast", "metal", "blue", "sage", "rose", "cobalt", "coral", "lime"];
5
+ type DbCreditCardOrientation = typeof ORIENTATIONS[number];
6
+ type DbCreditCardVariant = typeof VARIANTS[number];
7
+ interface DbCreditCardFlip {
8
+ flipped: boolean;
9
+ }
10
+ /** Saved-card presentation, not a payment form. Front/back state reflects to `flipped`. */
11
+ declare class DbCreditCard extends DbElement {
12
+ static get observedAttributes(): string[];
13
+ private button?;
14
+ private front;
15
+ private back;
16
+ private issuerFront;
17
+ private issuerBack;
18
+ private networkFront;
19
+ private networkBack;
20
+ private number;
21
+ private holderFront;
22
+ private holderBack;
23
+ private expiryFront;
24
+ private expiryBack;
25
+ private security;
26
+ private note;
27
+ get flipped(): boolean;
28
+ set flipped(value: boolean);
29
+ get orientation(): DbCreditCardOrientation;
30
+ set orientation(value: DbCreditCardOrientation);
31
+ get variant(): DbCreditCardVariant;
32
+ set variant(value: DbCreditCardVariant);
33
+ get disabled(): boolean;
34
+ set disabled(value: boolean);
35
+ connectedCallback(): void;
36
+ disconnectedCallback(): void;
37
+ private releaseSurface;
38
+ private resetSurface;
39
+ private syncNetwork;
40
+ attributeChangedCallback(): void;
41
+ private build;
42
+ private sync;
43
+ }
44
+ declare global {
45
+ interface HTMLElementTagNameMap {
46
+ 'db-credit-card': DbCreditCard;
47
+ }
48
+ }
49
+
50
+ export { DbCreditCard };
51
+ export type { DbCreditCardFlip, DbCreditCardOrientation, DbCreditCardVariant };
@@ -0,0 +1 @@
1
+ import{getPaymentBrand as t}from"../helpers/payment-brands.js";import{DbElement as e}from"../core/base-element.js";const i=["default","contrast","metal","blue","sage","rose","cobalt","coral","lime"],node=(t,e,i="")=>{const r=document.createElement(t);return r.className=e,r.textContent=i,r};class DbCreditCard extends e{static get observedAttributes(){return["issuer","holder","last-four","expiry","network","security-code","back-note","orientation","variant","flipped","disabled","label"]}get flipped(){return this.hasAttribute("flipped")}set flipped(t){this.toggleAttribute("flipped",Boolean(t))}get orientation(){return"vertical"===this.getAttribute("orientation")?"vertical":"horizontal"}set orientation(t){this.setAttribute("orientation",t)}get variant(){const t=this.getAttribute("variant");return i.find(e=>e===t)||"default"}set variant(t){this.setAttribute("variant",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}connectedCallback(){this.classList.add("db-credit-card"),this.upgradeProperties(["flipped","orientation","variant","disabled"]),this.button||this.build(),this.cleanups.listen(this.button,"click",()=>{this.disabled||(this.flipped=!this.flipped,this.dbEmit("flip",{flipped:this.flipped}))}),this.cleanups.listen(this.button,"pointermove",t=>{const e=t;if(this.disabled||"mouse"!==e.pointerType||!matchMedia("(hover: hover) and (pointer: fine)").matches||matchMedia("(prefers-reduced-motion: reduce)").matches)return;const i=this.button.getBoundingClientRect(),r=Math.max(0,Math.min(1,(e.clientX-i.left)/i.width)),s=Math.max(0,Math.min(1,(e.clientY-i.top)/i.height));this.dataset.pointerActive="",this.style.setProperty("--db-cc-rotate-x",7*(.5-s)+"deg"),this.style.setProperty("--db-cc-rotate-y",7*(r-.5)+"deg"),this.style.setProperty("--db-cc-pointer-x",100*r+"%"),this.style.setProperty("--db-cc-pointer-y",100*s+"%"),this.style.setProperty("--db-cc-glare","1")}),this.cleanups.listen(this.button,"pointerleave",()=>this.releaseSurface());for(const t of["pointercancel","blur"])this.cleanups.listen(this.button,t,()=>this.releaseSurface());this.cleanups.listen(matchMedia("(prefers-reduced-motion: reduce)"),"change",()=>this.resetSurface()),this.sync()}disconnectedCallback(){this.resetSurface(),super.disconnectedCallback()}releaseSurface(){if(this.hasAttribute("data-pointer-active"))for(const t of["x","y"]){const e=`--db-cc-pointer-${t}`,i=parseFloat(this.style.getPropertyValue(e));Number.isFinite(i)&&this.style.setProperty(e,`${Math.max(-20,Math.min(120,i+.6*(i-50)))}%`)}delete this.dataset.pointerActive;for(const t of["rotate-x","rotate-y","glare"])this.style.removeProperty(`--db-cc-${t}`)}resetSurface(){delete this.dataset.pointerActive;for(const t of["rotate-x","rotate-y","pointer-x","pointer-y","glare"])this.style.removeProperty(`--db-cc-${t}`)}syncNetwork(e,i){const r=t(i);if(e.dataset.network===i)return;if(e.dataset.network=i,!r)return delete e.dataset.brand,e.style.removeProperty("--db-cc-network-mask"),void(e.textContent=i);const s=document.createElement("img");e.dataset.brand=r.id;const a="cardSrc"in r?r.cardSrc:r.src;s.src=a,e.style.setProperty("--db-cc-network-mask",`url("${a}")`),s.alt=r.label,s.width=120,s.height=80,s.draggable=!1,e.replaceChildren(s)}attributeChangedCallback(){this.button&&this.sync()}build(){const t=document.createElement("button");t.type="button",t.className="db-credit-card__button";const e=node("span","db-credit-card__frame");this.front=node("span","db-credit-card__face db-credit-card__face--front");const i=node("span","db-credit-card__head");this.issuerFront=node("span","db-credit-card__issuer"),this.networkFront=node("span","db-credit-card__network"),i.append(this.issuerFront,this.networkFront);const r=node("span","db-credit-card__middle"),s=node("span","db-credit-card__chip");s.setAttribute("aria-hidden","true"),s.append(node("span","")),r.append(s),this.number=node("span","db-credit-card__number");const a=node("span","db-credit-card__foot");this.holderFront=node("span","db-credit-card__holder"),this.expiryFront=node("span","db-credit-card__expiry"),a.append(this.holderFront,this.expiryFront),this.front.append(i,r,this.number,a),this.back=node("span","db-credit-card__face db-credit-card__face--back"),this.issuerBack=node("span","db-credit-card__issuer");const n=node("span","db-credit-card__stripe");n.setAttribute("aria-hidden","true");const d=node("span","db-credit-card__signature");this.holderBack=node("span","db-credit-card__signature-name"),this.security=node("span","db-credit-card__security"),d.append(this.holderBack,this.security),this.note=node("span","db-credit-card__note");const o=node("span","db-credit-card__foot");this.networkBack=node("span","db-credit-card__network"),this.expiryBack=node("span","db-credit-card__expiry"),o.append(this.networkBack,this.expiryBack),this.back.append(this.issuerBack,n,d,this.note,o),e.append(this.front,this.back);const c=node("span","db-credit-card__tilt");c.append(e),t.append(c),this.button=t,this.prepend(t)}sync(){const t=this.getAttribute("issuer")||"Studio",e=this.getAttribute("holder")||"",i=this.getAttribute("last-four")||"",r=/^\d{4}$/.test(i)?i:"••••",s=this.getAttribute("network")||"",a=this.getAttribute("expiry")||"";this.dataset.orientation=this.orientation,this.dataset.variant=this.variant,this.issuerFront.textContent=t,this.issuerBack.textContent=t,this.syncNetwork(this.networkFront,s),this.syncNetwork(this.networkBack,s),this.number.textContent=`•••• •••• •••• ${r}`,this.holderFront.textContent=e,this.holderFront.title=e,this.holderBack.textContent=e,this.expiryFront.textContent=a,this.expiryBack.textContent=a,this.security.textContent=this.getAttribute("security-code")||"•••",this.security.setAttribute("aria-label",`보안 코드 ${this.security.textContent}`),this.note.textContent=this.getAttribute("back-note")||"",this.button.disabled=this.disabled,this.disabled&&this.resetSurface(),this.button.setAttribute("aria-label",this.getAttribute("label")||`${t} 카드${"••••"===r?"":`, 끝자리 ${r}`}, 뒤집기`),this.button.setAttribute("aria-pressed",String(this.flipped)),this.button.setAttribute("aria-description",[(this.flipped?"뒷면":"앞면")+" 표시 중",e,s,a?`유효기간 ${a}`:"",this.flipped?`보안 코드 ${this.security.textContent}`:"",`누르면 ${this.flipped?"앞면":"뒷면"}을 표시합니다`].filter(Boolean).join(". ")),this.front.setAttribute("aria-hidden",String(this.flipped)),this.back.setAttribute("aria-hidden",String(!this.flipped)),this.front.inert=this.flipped,this.back.inert=!this.flipped}}customElements.get("db-credit-card")||customElements.define("db-credit-card",DbCreditCard);export{DbCreditCard};
@@ -0,0 +1,31 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+ import './db-button.js';
3
+ import './db-credit-balance.js';
4
+
5
+ /** Header balance disclosure. Native Popover keeps live nodes/listeners in the top layer. */
6
+ declare class DbCreditDropdown extends DbElement {
7
+ private trigger?;
8
+ private popup?;
9
+ private balance?;
10
+ private recharge?;
11
+ private history?;
12
+ private description?;
13
+ private readonly popupId;
14
+ static get observedAttributes(): string[];
15
+ get open(): boolean;
16
+ set open(value: boolean);
17
+ connectedCallback(): void;
18
+ disconnectedCallback(): void;
19
+ attributeChangedCallback(): void;
20
+ private closeAndFocus;
21
+ private ensureView;
22
+ private sync;
23
+ private position;
24
+ }
25
+ declare global {
26
+ interface HTMLElementTagNameMap {
27
+ 'db-credit-dropdown': DbCreditDropdown;
28
+ }
29
+ }
30
+
31
+ export { DbCreditDropdown };
@@ -0,0 +1 @@
1
+ import{DbElement as t}from"../core/base-element.js";import{creditAction as e,textNode as i,creditText as s,creditNumber as r}from"../core/credit-ui.js";import{dbUid as o}from"../core/uid.js";import{t as p}from"../core/i18n.js";import{createDbIcon as n}from"./db-icons.js";import"./db-button.js";import"./db-credit-balance.js";class DbCreditDropdown extends t{constructor(){super(...arguments),this.popupId=o("credit-dropdown")}static get observedAttributes(){return["available","held","spent","low-threshold","unit","label","description","recharge-label","history-label","loading","error","disabled","open"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){this.toggleAttribute("open",t)}connectedCallback(){this.upgradeProperties(["open"]),this.ensureView(),this.cleanups.listen(this.trigger,"db-click",()=>{this.open=!this.open}),this.cleanups.listen(this.trigger,"keydown",t=>{"ArrowDown"===t.key&&(t.preventDefault(),this.open=!0)}),this.cleanups.listen(this.popup,"toggle",()=>{const t=this.popup.matches(":popover-open");t!==this.open&&this.toggleAttribute("open",t),this.trigger.setAttribute("aria-expanded",String(t)),this.dbEmit("open-change",{open:t})}),this.cleanups.listen(this.recharge,"db-click",()=>{this.closeAndFocus(),this.dbEmit("recharge")}),this.cleanups.listen(this.history,"db-click",()=>{this.closeAndFocus(),this.dbEmit("history")}),this.cleanups.listen(document,"focusin",t=>{this.open&&t.target instanceof Node&&!this.contains(t.target)&&(this.open=!1)}),this.cleanups.listen(window,"resize",()=>this.position()),this.cleanups.listen(window,"scroll",()=>this.position(),{capture:!0,passive:!0}),this.sync()}disconnectedCallback(){this.popup?.matches(":popover-open")&&this.popup.hidePopover(),super.disconnectedCallback()}attributeChangedCallback(){this.isConnected&&this.sync()}closeAndFocus(){this.open=!1,this.trigger?.focus()}ensureView(){if(this.trigger)return;this.classList.add("designbase-wc-credit-dropdown"),this.trigger=e("toggle-credits","",!1),this.trigger.classList.add("designbase-wc-credit-dropdown__trigger"),this.trigger.setAttribute("size","m"),this.trigger.setAttribute("aria-haspopup","dialog"),this.trigger.setAttribute("aria-controls",this.popupId),this.popup=document.createElement("div"),this.popup.id=this.popupId,this.popup.popover="auto",this.popup.className="designbase-wc-credit-dropdown__panel",this.popup.setAttribute("role","dialog"),this.popup.setAttribute("aria-modal","false"),this.balance=document.createElement("db-credit-balance"),this.balance.setAttribute("compact",""),this.description=i("p","designbase-wc-credit-dropdown__description","");const t=i("div","designbase-wc-credit-dropdown__footer","");this.recharge=e("recharge","",!1),this.recharge.setAttribute("variant","primary"),this.recharge.setAttribute("size","m"),this.history=e("history","",!1),this.history.setAttribute("variant","tertiary"),t.append(this.recharge,this.history),this.popup.append(this.balance,this.description,t),this.append(this.trigger,this.popup)}sync(){if(!this.trigger||!this.popup||!this.balance)return;const t=this.getAttribute("label")||p("credits.available"),e=this.hasAttribute("loading")?p("loading"):this.hasAttribute("error")?"—":s(r(this.getAttribute("available"))),o=this.getAttribute("unit")||p("credits.unit");this.trigger.replaceChildren(n("sparkle",16),i("span","designbase-wc-credit-dropdown__number",e),i("span","designbase-wc-credit-dropdown__unit",o),n("chevron-down",14)),this.trigger.setAttribute("aria-label",`${t} ${e} ${o}`),this.trigger.setAttribute("aria-expanded",String(this.open)),this.trigger.toggleAttribute("disabled",this.hasAttribute("disabled")),this.popup.setAttribute("aria-label",t);for(const t of["available","held","spent","low-threshold","unit","label","loading","error"]){const e=this.getAttribute(t);null===e?this.balance.removeAttribute(t):this.balance.setAttribute(t,e)}this.description.textContent=this.getAttribute("description")||"",this.description.hidden=!this.description.textContent;for(const[t,e]of[[this.recharge,"recharge-label"],[this.history,"history-label"]])t.textContent=this.getAttribute(e)||"",t.hidden=!t.textContent,t.toggleAttribute("disabled",this.hasAttribute("disabled")||this.hasAttribute("loading"));const h=this.open&&!this.hasAttribute("disabled");h&&!this.popup.matches(":popover-open")?(this.popup.showPopover(),this.position(),(this.popup.querySelector("db-button:not([hidden]):not([disabled])")||this.popup).focus()):!h&&this.popup.matches(":popover-open")&&this.popup.hidePopover(),this.position()}position(){if(!this.popup?.matches(":popover-open")||!this.trigger)return;const t=this.trigger.getBoundingClientRect(),e=this.popup.offsetWidth,i=this.popup.offsetHeight;this.popup.style.left=`${Math.max(8,Math.min(t.right-e,innerWidth-e-8))}px`,this.popup.style.top=`${Math.max(8,Math.min(t.bottom+8,innerHeight-i-8))}px`}}customElements.get("db-credit-dropdown")||customElements.define("db-credit-dropdown",DbCreditDropdown);export{DbCreditDropdown};
@@ -0,0 +1,31 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+ import './db-button.js';
3
+
4
+ type DbCreditEntryKind = 'grant' | 'charge' | 'hold' | 'release';
5
+ interface DbCreditEntry {
6
+ id: string;
7
+ label: string;
8
+ /** App formats the date in its explicit locale/timezone. */
9
+ dateLabel: string;
10
+ kind: DbCreditEntryKind;
11
+ /** Null means unresolved. Holds are separate from settled debits. */
12
+ amount: number | null;
13
+ }
14
+ /** Read-only history supplied by the app. Does not sum a balance from partial rows. */
15
+ declare class DbCreditHistory extends DbElement {
16
+ private entryData;
17
+ static get observedAttributes(): string[];
18
+ get entries(): DbCreditEntry[];
19
+ set entries(value: DbCreditEntry[]);
20
+ connectedCallback(): void;
21
+ attributeChangedCallback(): void;
22
+ private render;
23
+ }
24
+ declare global {
25
+ interface HTMLElementTagNameMap {
26
+ 'db-credit-history': DbCreditHistory;
27
+ }
28
+ }
29
+
30
+ export { DbCreditHistory };
31
+ export type { DbCreditEntry, DbCreditEntryKind };
@@ -0,0 +1 @@
1
+ import{DbElement as t}from"../core/base-element.js";import{textNode as e,creditAction as i,creditText as s,replaceView as r}from"../core/credit-ui.js";import{t as n}from"../core/i18n.js";import"./db-button.js";class DbCreditHistory extends t{constructor(){super(...arguments),this.entryData=[]}static get observedAttributes(){return["label","unit","loading","error","disabled"]}get entries(){return this.entryData.map(t=>({...t}))}set entries(t){const e=new Set;this.entryData=Array.isArray(t)?t.filter(t=>!(!t||"string"!=typeof t.id||!t.id||e.has(t.id)||"string"!=typeof t.label||"string"!=typeof t.dateLabel||!["grant","charge","hold","release"].includes(t.kind)||null!==t.amount&&("number"!=typeof t.amount||!Number.isSafeInteger(t.amount)||t.amount<0))&&(e.add(t.id),!0)).map(t=>({...t})):[],this.isConnected&&this.render()}connectedCallback(){this.upgradeProperties(["entries"]),this.cleanups.listen(this,"db-click",t=>{t.target instanceof HTMLElement&&"retry"===t.target.dataset.action&&!this.hasAttribute("loading")&&!this.hasAttribute("disabled")&&this.dbEmit("retry")}),this.render()}attributeChangedCallback(){this.isConnected&&this.render()}render(){const t="designbase-wc-credit-history";this.classList.add(t);const a=this.hasAttribute("loading"),o=this.getAttribute("error");this.setAttribute("aria-busy",String(a));const d=[e("h3",`${t}__title`,this.getAttribute("label")||n("history.title"))];if(a||o||!this.entryData.length){const s=e("p",`${t}__message`,a?n("loading"):o||n("history.empty"));s.setAttribute("role",o&&!a?"alert":"status"),d.push(s),o&&!a&&d.push(i("retry",n("plan.retry"),this.hasAttribute("disabled")))}else{const i=e("ul",`${t}__list`,"");for(const r of this.entryData){const a=e("li",`${t}__row`,"");a.dataset.kind=r.kind;const o=e("div",`${t}__info`,"");o.append(e("strong","",r.label),e("span",`${t}__date`,r.dateLabel));const d=e("div",`${t}__amount`,"");d.append(e("span",`${t}__kind`,n(`history.${r.kind}`)));const l="grant"===r.kind||"release"===r.kind?"+":"charge"===r.kind?"−":"";d.append(e("strong","",null===r.amount?n("history.unresolved"):`${l}${s(r.amount)} ${this.getAttribute("unit")||n("credits.unit")}`)),a.append(o,d),i.append(a)}d.push(i)}r(this,...d)}}customElements.get("db-credit-history")||customElements.define("db-credit-history",DbCreditHistory);export{DbCreditHistory};
@@ -0,0 +1,35 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+ import './db-modal.js';
3
+ import { DbCreditPlan } from './db-credit-recharge.js';
4
+ import './db-credit-balance.js';
5
+
6
+ /** Reuses the canonical modal (portal, focus trap, scroll lock) and controlled plan selector. */
7
+ declare class DbCreditRechargeModal extends DbElement {
8
+ private modal?;
9
+ private selector?;
10
+ private balance?;
11
+ private intro?;
12
+ private confirm?;
13
+ private footnote?;
14
+ private planData;
15
+ static get observedAttributes(): string[];
16
+ get plans(): DbCreditPlan[];
17
+ set plans(value: DbCreditPlan[]);
18
+ get open(): boolean;
19
+ set open(value: boolean);
20
+ connectedCallback(): void;
21
+ disconnectedCallback(): void;
22
+ attributeChangedCallback(name: string): void;
23
+ private readPlans;
24
+ private blocked;
25
+ private selected;
26
+ private ensureView;
27
+ private sync;
28
+ }
29
+ declare global {
30
+ interface HTMLElementTagNameMap {
31
+ 'db-credit-recharge-modal': DbCreditRechargeModal;
32
+ }
33
+ }
34
+
35
+ export { DbCreditRechargeModal };
@@ -0,0 +1 @@
1
+ import{DbElement as t}from"../core/base-element.js";import{textNode as e,creditAction as i}from"../core/credit-ui.js";import{t as s}from"../core/i18n.js";import"./db-modal.js";import"./db-credit-recharge.js";import"./db-credit-balance.js";class DbCreditRechargeModal extends t{constructor(){super(...arguments),this.planData=[]}static get observedAttributes(){return["open","plans","selected-id","available","unit","title","description","footnote","submit-label","loading","error","disabled"]}get plans(){return this.planData.map(t=>({...t}))}set plans(t){const e=document.createElement("db-credit-recharge");e.plans=t,this.planData=e.plans,this.isConnected&&this.sync()}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){this.toggleAttribute("open",t)}connectedCallback(){this.upgradeProperties(["plans","open"]),this.hasAttribute("plans")&&this.readPlans(),this.ensureView(),this.cleanups.listen(this.modal,"db-close",t=>{t.stopPropagation(),this.open=!1,this.dbEmit("close")}),this.cleanups.listen(this.selector,"db-plan-change",t=>{t.stopPropagation(),this.dbEmit("plan-change",t.detail)}),this.cleanups.listen(this.confirm,"db-click",()=>{const t=this.selected();t&&!this.blocked()&&this.dbEmit("checkout",{planId:t.id})}),this.sync()}disconnectedCallback(){this.modal?.remove(),super.disconnectedCallback(),this.modal=void 0}attributeChangedCallback(t){"plans"===t&&this.readPlans(),this.isConnected&&this.sync()}readPlans(){try{this.plans=JSON.parse(this.getAttribute("plans")||"[]")}catch{this.planData=[]}}blocked(){return this.hasAttribute("disabled")||this.hasAttribute("loading")}selected(){return this.planData.find(t=>t.id===this.getAttribute("selected-id")&&!t.disabled)}ensureView(){if(this.modal)return;this.modal=document.createElement("db-modal"),this.modal.setAttribute("size","l");const t=e("div","designbase-wc-credit-recharge-modal__body","");t.setAttribute("data-modal-part","body"),this.intro=e("p","designbase-wc-credit-recharge-modal__intro",""),this.balance=document.createElement("db-credit-balance"),this.balance.setAttribute("compact",""),this.balance.setAttribute("label",s("credits.remaining")),this.selector=document.createElement("db-credit-recharge"),this.selector.setAttribute("selection-only",""),this.selector.setAttribute("card-selection",""),this.selector.setAttribute("label",s("credits.choosePlan")),this.selector.classList.add("designbase-wc-credit-recharge-modal__selector"),this.footnote=e("p","designbase-wc-credit-recharge-modal__footnote",""),t.append(this.intro,this.selector,this.footnote);const o=e("div","designbase-wc-credit-recharge-modal__footer","");o.setAttribute("data-modal-part","footer"),this.confirm=i("checkout",s("credits.checkout"),!0),this.confirm.setAttribute("variant","primary"),this.confirm.setAttribute("size","m"),o.append(this.balance,this.confirm),this.modal.append(t,o),this.append(this.modal)}sync(){if(!this.modal||!this.selector)return;const t=this.getAttribute("title")||s("credits.recharge");this.modal.getAttribute("title")!==t&&this.modal.setAttribute("title",t);const e=this.hasAttribute("loading");this.modal.getAttribute("show-close-button")!==String(!e)&&this.modal.setAttribute("show-close-button",String(!e)),this.modal.getAttribute("close-on-escape")!==String(!e)&&this.modal.setAttribute("close-on-escape",String(!e)),this.modal.getAttribute("close-on-outside-click")!==String(!e)&&this.modal.setAttribute("close-on-outside-click",String(!e)),this.intro.textContent=this.getAttribute("description")||s("credits.rechargeDescription");for(const t of["available","unit"]){const e=this.getAttribute(t);null===e?this.balance.removeAttribute(t):this.balance.setAttribute(t,e)}this.selector.plans=this.planData;for(const t of["selected-id","unit","loading","disabled","error"]){const e=this.getAttribute(t);null===e?this.selector.removeAttribute(t):this.selector.setAttribute(t,e)}this.footnote.textContent=this.getAttribute("footnote")||"",this.footnote.hidden=!this.footnote.textContent;const i=this.selected();this.confirm.textContent=e?s("credits.paymentPending"):this.getAttribute("submit-label")||s("credits.checkout"),this.confirm.toggleAttribute("disabled",this.blocked()||!i),this.confirm.toggleAttribute("loading",e),this.modal.open!==this.open&&(this.modal.open=this.open)}}customElements.get("db-credit-recharge-modal")||customElements.define("db-credit-recharge-modal",DbCreditRechargeModal);export{DbCreditRechargeModal};
@@ -0,0 +1,39 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+ import './db-button.js';
3
+ import './db-badge.js';
4
+
5
+ interface DbCreditPlan {
6
+ id: string;
7
+ label: string;
8
+ credits: number;
9
+ /** Preformatted display price; the server must resolve the actual price by id. */
10
+ priceLabel: string;
11
+ description?: string;
12
+ badge?: string;
13
+ disabled?: boolean;
14
+ }
15
+ interface DbCreditPlanSelection {
16
+ planId: string;
17
+ }
18
+ /** Controlled selector. Emits intent only; never grants credits or marks payment successful. */
19
+ declare class DbCreditRecharge extends DbElement {
20
+ private readonly groupName;
21
+ private planData;
22
+ static get observedAttributes(): string[];
23
+ get plans(): DbCreditPlan[];
24
+ set plans(value: DbCreditPlan[]);
25
+ connectedCallback(): void;
26
+ attributeChangedCallback(name: string): void;
27
+ private readPlans;
28
+ private blocked;
29
+ private selected;
30
+ private render;
31
+ }
32
+ declare global {
33
+ interface HTMLElementTagNameMap {
34
+ 'db-credit-recharge': DbCreditRecharge;
35
+ }
36
+ }
37
+
38
+ export { DbCreditRecharge };
39
+ export type { DbCreditPlan, DbCreditPlanSelection };
@@ -0,0 +1 @@
1
+ import{DbElement as t}from"../core/base-element.js";import{textNode as e,creditText as i,creditAction as s,replaceView as a}from"../core/credit-ui.js";import{t as n}from"../core/i18n.js";import{dbUid as r}from"../core/uid.js";import"./db-button.js";import"./db-badge.js";function parsePlans(t){if(!Array.isArray(t))return[];const e=new Set;return t.filter(t=>{if(!t||"object"!=typeof t)return!1;const i=t;return!("string"!=typeof i.id||!i.id||e.has(i.id)||"string"!=typeof i.label||"string"!=typeof i.priceLabel||"number"!=typeof i.credits||!Number.isSafeInteger(i.credits)||i.credits<0||void 0!==i.description&&"string"!=typeof i.description||void 0!==i.badge&&"string"!=typeof i.badge||void 0!==i.disabled&&"boolean"!=typeof i.disabled)&&(e.add(i.id),!0)}).map(t=>({...t}))}class DbCreditRecharge extends t{constructor(){super(...arguments),this.groupName=r("credit-plans"),this.planData=[]}static get observedAttributes(){return["plans","selected-id","label","unit","submit-label","loading","disabled","error","description","selection-only","card-selection"]}get plans(){return this.planData.map(t=>({...t}))}set plans(t){this.planData=parsePlans(t),this.isConnected&&this.render()}connectedCallback(){this.upgradeProperties(["plans"]),this.hasAttribute("plans")&&this.readPlans(),this.cleanups.listen(this,"change",t=>{const e=t.target;if(e instanceof HTMLInputElement&&e.name===this.groupName&&!this.blocked()){const t=this.planData.find(t=>t.id===e.value&&!t.disabled);t&&this.dbEmit("plan-change",{planId:t.id}),this.render()}}),this.cleanups.listen(this,"click",t=>{const e=t.target instanceof Element?t.target.closest("button[data-plan-id]"):null;if(!e||!this.contains(e)||this.blocked())return;const i=this.planData.find(t=>t.id===e.dataset.planId&&!t.disabled);i&&this.dbEmit("plan-change",{planId:i.id}),this.render()}),this.cleanups.listen(this,"db-click",t=>{if(!(t.target instanceof HTMLElement)||"checkout"!==t.target.dataset.action)return;const e=this.selected();e&&!this.blocked()&&this.dbEmit("checkout",{planId:e.id})}),this.render()}attributeChangedCallback(t){"plans"===t&&this.readPlans(),this.isConnected&&this.render()}readPlans(){try{this.planData=parsePlans(JSON.parse(this.getAttribute("plans")||"[]"))}catch{this.planData=[]}}blocked(){return this.hasAttribute("disabled")||this.hasAttribute("loading")}selected(){return this.planData.find(t=>t.id===this.getAttribute("selected-id")&&!t.disabled)}render(){const t="designbase-wc-credit-recharge";this.classList.add(t),this.setAttribute("aria-busy",String(this.hasAttribute("loading")));const r=document.createElement("fieldset");r.className=`${t}__fieldset`,r.disabled=this.blocked(),r.append(e("legend",`${t}__title`,this.getAttribute("label")||n("credits.recharge")));const d=e("div",`${t}__plans`,"");for(const s of this.planData){const a=this.hasAttribute("card-selection"),r=e(a?"button":"label",`${t}__plan`,"");if(r instanceof HTMLButtonElement){r.type="button",r.dataset.planId=s.id,r.dataset.action=`plan:${s.id}`,r.disabled=Boolean(s.disabled),r.setAttribute("aria-pressed",String(s.id===this.getAttribute("selected-id")));const i=e("span",`${t}__plan-header`,"");if(i.append(e("span",`${t}__name`,s.label)),s.badge){const a=e("db-badge",`${t}__badge`,s.badge);a.setAttribute("variant","primary"),a.setAttribute("size","m"),i.append(a)}r.append(i)}else{const i=document.createElement("input");i.type="radio",i.name=this.groupName,i.value=s.id,i.dataset.action=`plan:${s.id}`,i.checked=s.id===this.getAttribute("selected-id"),i.disabled=Boolean(s.disabled),r.append(i,e("span",`${t}__name`,s.label)),s.badge&&r.append(e("span",`${t}__badge`,s.badge))}r.append(e("strong",`${t}__amount`,`${i(s.credits)} ${this.getAttribute("unit")||n("credits.unit")}`)),r.append(e("span",`${t}__price`,s.priceLabel)),s.description&&r.append(e("span",`${t}__description`,s.description)),d.append(r)}this.planData.length||d.append(e("p",`${t}__description`,n("credits.noPlans"))),r.append(d);const l=[r];this.hasAttribute("description")&&l.push(e("p",`${t}__description`,this.getAttribute("description")||""));const c=this.getAttribute("error");if(c){const i=e("p",`${t}__error`,c);i.setAttribute("role","alert"),l.push(i)}const o=s("checkout",this.getAttribute("submit-label")||n("credits.checkout"),this.blocked()||!this.selected());o.setAttribute("variant","primary"),o.toggleAttribute("loading",this.hasAttribute("loading")),this.hasAttribute("selection-only")||l.push(o),a(this,...l)}}customElements.get("db-credit-recharge")||customElements.define("db-credit-recharge",DbCreditRecharge);export{DbCreditRecharge};