@designbasekorea/ui-wc 0.8.13 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE-PAYMENT-LOGOS.md +437 -0
  3. package/README.md +67 -3
  4. package/dist/esm/components/date-picker-utils.js +1 -1
  5. package/dist/esm/components/db-accordion.js +1 -1
  6. package/dist/esm/components/db-achievement-list.d.ts +31 -0
  7. package/dist/esm/components/db-achievement-list.js +1 -0
  8. package/dist/esm/components/db-achievement-modal.d.ts +38 -0
  9. package/dist/esm/components/db-achievement-modal.js +1 -0
  10. package/dist/esm/components/db-activity-heatmap.js +1 -1
  11. package/dist/esm/components/db-ad-banner.js +1 -1
  12. package/dist/esm/components/db-ai-chain-of-thought.d.ts +14 -0
  13. package/dist/esm/components/db-ai-chain-of-thought.js +1 -0
  14. package/dist/esm/components/db-ai-chat.js +1 -1
  15. package/dist/esm/components/db-ai-checkpoint.d.ts +14 -0
  16. package/dist/esm/components/db-ai-checkpoint.js +1 -0
  17. package/dist/esm/components/db-ai-confirmation.d.ts +14 -0
  18. package/dist/esm/components/db-ai-confirmation.js +1 -0
  19. package/dist/esm/components/db-ai-context.d.ts +15 -0
  20. package/dist/esm/components/db-ai-context.js +1 -0
  21. package/dist/esm/components/db-ai-conversation.d.ts +21 -0
  22. package/dist/esm/components/db-ai-conversation.js +1 -0
  23. package/dist/esm/components/db-ai-execution-quote.d.ts +41 -0
  24. package/dist/esm/components/db-ai-execution-quote.js +1 -0
  25. package/dist/esm/components/db-ai-file-tree.d.ts +14 -0
  26. package/dist/esm/components/db-ai-file-tree.js +1 -0
  27. package/dist/esm/components/db-ai-glow.d.ts +1 -1
  28. package/dist/esm/components/db-ai-inline-citation.d.ts +16 -0
  29. package/dist/esm/components/db-ai-inline-citation.js +1 -0
  30. package/dist/esm/components/db-ai-message.d.ts +19 -0
  31. package/dist/esm/components/db-ai-message.js +1 -0
  32. package/dist/esm/components/db-ai-model-select.d.ts +36 -0
  33. package/dist/esm/components/db-ai-model-select.js +1 -0
  34. package/dist/esm/components/db-ai-plan.d.ts +14 -0
  35. package/dist/esm/components/db-ai-plan.js +1 -0
  36. package/dist/esm/components/db-ai-queue.d.ts +14 -0
  37. package/dist/esm/components/db-ai-queue.js +1 -0
  38. package/dist/esm/components/db-ai-reasoning.d.ts +14 -0
  39. package/dist/esm/components/db-ai-reasoning.js +1 -0
  40. package/dist/esm/components/db-ai-sources.d.ts +14 -0
  41. package/dist/esm/components/db-ai-sources.js +1 -0
  42. package/dist/esm/components/db-ai-stack-trace.d.ts +14 -0
  43. package/dist/esm/components/db-ai-stack-trace.js +1 -0
  44. package/dist/esm/components/db-ai-subagent.d.ts +14 -0
  45. package/dist/esm/components/db-ai-subagent.js +1 -0
  46. package/dist/esm/components/db-ai-task-status.d.ts +26 -0
  47. package/dist/esm/components/db-ai-task-status.js +1 -0
  48. package/dist/esm/components/db-ai-task.d.ts +14 -0
  49. package/dist/esm/components/db-ai-task.js +1 -0
  50. package/dist/esm/components/db-ai-terminal.d.ts +14 -0
  51. package/dist/esm/components/db-ai-terminal.js +1 -0
  52. package/dist/esm/components/db-ai-test-results.d.ts +14 -0
  53. package/dist/esm/components/db-ai-test-results.js +1 -0
  54. package/dist/esm/components/db-ai-tool.d.ts +14 -0
  55. package/dist/esm/components/db-ai-tool.js +1 -0
  56. package/dist/esm/components/db-alert.js +1 -1
  57. package/dist/esm/components/db-app-badge.js +1 -1
  58. package/dist/esm/components/db-attachment-list.d.ts +38 -0
  59. package/dist/esm/components/db-attachment-list.js +1 -0
  60. package/dist/esm/components/db-audio-player.js +1 -1
  61. package/dist/esm/components/db-bento-card.d.ts +55 -0
  62. package/dist/esm/components/db-bento-card.js +1 -0
  63. package/dist/esm/components/db-bento-grid.d.ts +25 -0
  64. package/dist/esm/components/db-bento-grid.js +1 -0
  65. package/dist/esm/components/db-boarding-pass-stack.d.ts +49 -0
  66. package/dist/esm/components/db-boarding-pass-stack.js +1 -0
  67. package/dist/esm/components/db-boarding-pass.d.ts +32 -0
  68. package/dist/esm/components/db-boarding-pass.js +1 -0
  69. package/dist/esm/components/db-border-beam.d.ts +52 -0
  70. package/dist/esm/components/db-border-beam.js +1 -0
  71. package/dist/esm/components/db-bottom-navigation.js +1 -1
  72. package/dist/esm/components/db-bottom-sheet.js +1 -1
  73. package/dist/esm/components/db-breadcrumbs.js +1 -1
  74. package/dist/esm/components/db-button.d.ts +1 -1
  75. package/dist/esm/components/db-button.js +1 -1
  76. package/dist/esm/components/db-calendar.js +1 -1
  77. package/dist/esm/components/db-card.js +1 -1
  78. package/dist/esm/components/db-carousel.d.ts +3 -3
  79. package/dist/esm/components/db-carousel.js +1 -1
  80. package/dist/esm/components/db-chat-composer.d.ts +2 -0
  81. package/dist/esm/components/db-chat-composer.js +1 -1
  82. package/dist/esm/components/db-chat-message.d.ts +1 -1
  83. package/dist/esm/components/db-chat-orb.d.ts +1 -1
  84. package/dist/esm/components/db-chat-room.js +1 -1
  85. package/dist/esm/components/db-chat-widget.d.ts +1 -1
  86. package/dist/esm/components/db-chat-widget.js +1 -1
  87. package/dist/esm/components/db-chip.js +1 -1
  88. package/dist/esm/components/db-code-block.js +1 -1
  89. package/dist/esm/components/db-color-picker.d.ts +1 -0
  90. package/dist/esm/components/db-color-picker.js +1 -1
  91. package/dist/esm/components/db-confetti.d.ts +90 -0
  92. package/dist/esm/components/db-confetti.js +1 -0
  93. package/dist/esm/components/db-context-bar.d.ts +13 -0
  94. package/dist/esm/components/db-context-bar.js +1 -0
  95. package/dist/esm/components/db-credit-balance.d.ts +17 -0
  96. package/dist/esm/components/db-credit-balance.js +1 -0
  97. package/dist/esm/components/db-credit-card.d.ts +51 -0
  98. package/dist/esm/components/db-credit-card.js +1 -0
  99. package/dist/esm/components/db-credit-dropdown.d.ts +31 -0
  100. package/dist/esm/components/db-credit-dropdown.js +1 -0
  101. package/dist/esm/components/db-credit-history.d.ts +31 -0
  102. package/dist/esm/components/db-credit-history.js +1 -0
  103. package/dist/esm/components/db-credit-recharge-modal.d.ts +35 -0
  104. package/dist/esm/components/db-credit-recharge-modal.js +1 -0
  105. package/dist/esm/components/db-credit-recharge.d.ts +39 -0
  106. package/dist/esm/components/db-credit-recharge.js +1 -0
  107. package/dist/esm/components/db-date-picker.js +1 -1
  108. package/dist/esm/components/db-design-canvas.d.ts +137 -0
  109. package/dist/esm/components/db-design-canvas.js +1 -0
  110. package/dist/esm/components/db-design-toolbar.d.ts +60 -0
  111. package/dist/esm/components/db-design-toolbar.js +1 -0
  112. package/dist/esm/components/db-device-mockup.d.ts +100 -0
  113. package/dist/esm/components/db-device-mockup.js +1 -0
  114. package/dist/esm/components/db-download-progress.d.ts +1 -1
  115. package/dist/esm/components/db-download-progress.js +1 -1
  116. package/dist/esm/components/db-drawer.js +1 -1
  117. package/dist/esm/components/db-dropdown.d.ts +2 -0
  118. package/dist/esm/components/db-dropdown.js +1 -1
  119. package/dist/esm/components/db-dropzone.js +1 -1
  120. package/dist/esm/components/db-email-verify.d.ts +1 -7
  121. package/dist/esm/components/db-email-verify.js +1 -1
  122. package/dist/esm/components/db-file-uploader.d.ts +10 -0
  123. package/dist/esm/components/db-file-uploader.js +1 -1
  124. package/dist/esm/components/db-filter-bar.d.ts +34 -0
  125. package/dist/esm/components/db-filter-bar.js +1 -0
  126. package/dist/esm/components/db-flight-status.d.ts +33 -0
  127. package/dist/esm/components/db-flight-status.js +1 -0
  128. package/dist/esm/components/db-floating-action-button.d.ts +24 -14
  129. package/dist/esm/components/db-floating-action-button.js +1 -1
  130. package/dist/esm/components/db-footer.d.ts +3 -0
  131. package/dist/esm/components/db-footer.js +1 -1
  132. package/dist/esm/components/db-gantt.js +1 -1
  133. package/dist/esm/components/db-glyph-matrix.d.ts +58 -0
  134. package/dist/esm/components/db-glyph-matrix.js +1 -0
  135. package/dist/esm/components/db-icons.d.ts +1 -1
  136. package/dist/esm/components/db-icons.js +1 -1
  137. package/dist/esm/components/db-image-list.d.ts +2 -0
  138. package/dist/esm/components/db-image-list.js +1 -1
  139. package/dist/esm/components/db-indicator.js +1 -1
  140. package/dist/esm/components/db-input.js +1 -1
  141. package/dist/esm/components/db-kanban.js +1 -1
  142. package/dist/esm/components/db-lightbox.d.ts +4 -0
  143. package/dist/esm/components/db-lightbox.js +1 -1
  144. package/dist/esm/components/db-markdown-editor.js +1 -1
  145. package/dist/esm/components/db-marquee.d.ts +2 -10
  146. package/dist/esm/components/db-marquee.js +1 -1
  147. package/dist/esm/components/db-menu-item.d.ts +2 -0
  148. package/dist/esm/components/db-menu-item.js +1 -1
  149. package/dist/esm/components/db-modal.d.ts +1 -1
  150. package/dist/esm/components/db-modal.js +1 -1
  151. package/dist/esm/components/db-navbar.d.ts +3 -1
  152. package/dist/esm/components/db-navbar.js +1 -1
  153. package/dist/esm/components/db-navigation-rail.d.ts +1 -1
  154. package/dist/esm/components/db-node.d.ts +83 -0
  155. package/dist/esm/components/db-node.js +1 -0
  156. package/dist/esm/components/db-notification-dropdown.d.ts +30 -0
  157. package/dist/esm/components/db-notification-dropdown.js +1 -0
  158. package/dist/esm/components/db-notification-inbox.d.ts +25 -0
  159. package/dist/esm/components/db-notification-inbox.js +1 -0
  160. package/dist/esm/components/db-onboarding-modal.js +1 -1
  161. package/dist/esm/components/db-otp-input.d.ts +1 -1
  162. package/dist/esm/components/db-otp-input.js +1 -1
  163. package/dist/esm/components/db-page-header.d.ts +8 -0
  164. package/dist/esm/components/db-page-header.js +1 -1
  165. package/dist/esm/components/db-pagination.js +1 -1
  166. package/dist/esm/components/db-phone-verify.d.ts +1 -1
  167. package/dist/esm/components/db-phone-verify.js +1 -1
  168. package/dist/esm/components/db-plan-overview.d.ts +26 -0
  169. package/dist/esm/components/db-plan-overview.js +1 -0
  170. package/dist/esm/components/db-popover.js +1 -1
  171. package/dist/esm/components/db-progress-step.js +1 -1
  172. package/dist/esm/components/db-progressive-blur.d.ts +35 -0
  173. package/dist/esm/components/db-progressive-blur.js +1 -0
  174. package/dist/esm/components/db-receipt.d.ts +37 -0
  175. package/dist/esm/components/db-receipt.js +1 -0
  176. package/dist/esm/components/db-resizable-panels.js +1 -1
  177. package/dist/esm/components/db-search-bar.js +1 -1
  178. package/dist/esm/components/db-section-testimonials.d.ts +1 -4
  179. package/dist/esm/components/db-section-testimonials.js +1 -1
  180. package/dist/esm/components/db-segment-control.d.ts +0 -4
  181. package/dist/esm/components/db-segment-control.js +1 -1
  182. package/dist/esm/components/db-select.js +1 -1
  183. package/dist/esm/components/db-share.js +1 -1
  184. package/dist/esm/components/db-sidebar.d.ts +14 -1
  185. package/dist/esm/components/db-sidebar.js +1 -1
  186. package/dist/esm/components/db-split-view.d.ts +2 -0
  187. package/dist/esm/components/db-split-view.js +1 -1
  188. package/dist/esm/components/db-stepper.d.ts +0 -3
  189. package/dist/esm/components/db-stepper.js +1 -1
  190. package/dist/esm/components/db-table.js +1 -1
  191. package/dist/esm/components/db-testimonial.js +1 -1
  192. package/dist/esm/components/db-textarea.js +1 -1
  193. package/dist/esm/components/db-ticket.d.ts +18 -0
  194. package/dist/esm/components/db-ticket.js +1 -0
  195. package/dist/esm/components/db-time-picker.d.ts +1 -1
  196. package/dist/esm/components/db-time-picker.js +1 -1
  197. package/dist/esm/components/db-tool-button.d.ts +57 -0
  198. package/dist/esm/components/db-tool-button.js +1 -0
  199. package/dist/esm/components/db-top-banner.js +1 -1
  200. package/dist/esm/components/db-tutorial.js +1 -1
  201. package/dist/esm/components/db-tweet-card.d.ts +101 -0
  202. package/dist/esm/components/db-tweet-card.js +1 -0
  203. package/dist/esm/components/db-two-factor.d.ts +5 -11
  204. package/dist/esm/components/db-two-factor.js +1 -1
  205. package/dist/esm/components/db-video-player.js +1 -1
  206. package/dist/esm/components/db-voice-control.d.ts +25 -0
  207. package/dist/esm/components/db-voice-control.js +1 -0
  208. package/dist/esm/components/db-workspace-invite-modal.d.ts +51 -0
  209. package/dist/esm/components/db-workspace-invite-modal.js +1 -0
  210. package/dist/esm/components/db-workspace-members.d.ts +36 -0
  211. package/dist/esm/components/db-workspace-members.js +1 -0
  212. package/dist/esm/components/db-youtube-player.js +1 -1
  213. package/dist/esm/components/device-mockup-style.js +1 -0
  214. package/dist/esm/components/flight-route.js +1 -0
  215. package/dist/esm/components/input-validation.js +1 -1
  216. package/dist/esm/components/node-style.js +1 -0
  217. package/dist/esm/components/paper-card.d.ts +26 -0
  218. package/dist/esm/components/paper-card.js +1 -0
  219. package/dist/esm/components/random-gradient-palettes.d.ts +4 -0
  220. package/dist/esm/core/ai-element.d.ts +47 -0
  221. package/dist/esm/core/ai-element.js +1 -0
  222. package/dist/esm/core/credit-ui.js +1 -0
  223. package/dist/esm/core/i18n-copy.js +1 -0
  224. package/dist/esm/core/i18n-en.js +1 -0
  225. package/dist/esm/core/i18n.d.ts +206 -1
  226. package/dist/esm/core/i18n.js +1 -1
  227. package/dist/esm/core/notification-ui.d.ts +17 -0
  228. package/dist/esm/core/notification-ui.js +1 -0
  229. package/dist/esm/helpers/payment-brands.d.ts +56 -0
  230. package/dist/esm/helpers/payment-brands.js +1 -0
  231. package/dist/esm/helpers/toast.d.ts +2 -3
  232. package/dist/esm/index.d.ts +63 -3
  233. package/dist/esm/index.js +1 -1
  234. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-AGE5BHQ4.js +1 -0
  235. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-GM4TCAP5.js +1 -0
  236. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-GSN4JZN7.js +1 -0
  237. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-VJJVQGV4.js +1 -0
  238. package/dist/esm/node_modules/@designbasekorea/carousel/dist/chunks/chunk-YWLMJGDH.js +1 -0
  239. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  240. package/dist/esm/ui-contracts/dist/components.d.d.ts +76 -0
  241. package/dist/esm/ui-contracts/dist/primitives.d.d.ts +21 -0
  242. package/dist/index.cjs +1 -1
  243. package/dist/index.css +1 -1
  244. package/dist/index.d.ts +2223 -63
  245. package/dist/index.esm.js +1 -1
  246. package/dist/react/index.cjs +1 -1
  247. package/dist/react/index.d.ts +793 -6726
  248. package/dist/react/index.esm.js +1 -1
  249. package/package.json +16 -9
@@ -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{dbText as t}from"../core/i18n.js";import{DbDesignToolbar as e}from"./db-design-toolbar.js";class DbContextBar extends e{connectedCallback(){this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("선택 요소 작업")),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{t}from"../core/i18n.js";import{getPaymentBrand as e}from"../helpers/payment-brands.js";import{DbElement as i}from"../core/base-element.js";const r=["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 i{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 r.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(t,i){const r=e(i);if(t.dataset.network===i)return;if(t.dataset.network=i,!r)return delete t.dataset.brand,t.style.removeProperty("--db-cc-network-mask"),void(t.textContent=i);const s=document.createElement("img");t.dataset.brand=r.id;const a="cardSrc"in r?r.cardSrc:r.src;s.src=a,t.style.setProperty("--db-cc-network-mask",`url("${a}")`),s.alt=r.label,s.width=120,s.height=80,s.draggable=!1,t.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 c=node("span","db-credit-card__foot");this.networkBack=node("span","db-credit-card__network"),this.expiryBack=node("span","db-credit-card__expiry"),c.append(this.networkBack,this.expiryBack),this.back.append(this.issuerBack,n,d,this.note,c),e.append(this.front,this.back);const o=node("span","db-credit-card__tilt");o.append(e),t.append(o),this.button=t,this.prepend(t)}sync(){const e=this.getAttribute("issuer")||"Studio",i=this.getAttribute("holder")||"",r=this.getAttribute("last-four")||"",s=/^\d{4}$/.test(r)?r:"••••",a=this.getAttribute("network")||"",n=this.getAttribute("expiry")||"";this.dataset.orientation=this.orientation,this.dataset.variant=this.variant,this.issuerFront.textContent=e,this.issuerBack.textContent=e,this.syncNetwork(this.networkFront,a),this.syncNetwork(this.networkBack,a),this.number.textContent=`•••• •••• •••• ${s}`,this.holderFront.textContent=i,this.holderFront.title=i,this.holderBack.textContent=i,this.expiryFront.textContent=n,this.expiryBack.textContent=n,this.security.textContent=this.getAttribute("security-code")||"•••",this.security.setAttribute("aria-label",t("creditCard.security").replace("{code}",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("creditCard.label").replace("{issuer}",e).replace("{lastFour}","••••"===s?"":t("creditCard.ending").replace("{digits}",s))),this.button.setAttribute("aria-pressed",String(this.flipped)),this.button.setAttribute("aria-description",[t("creditCard.showing").replace("{side}",t(this.flipped?"creditCard.back":"creditCard.front")),i,a,n?t("creditCard.expiry").replace("{expiry}",n):"",this.flipped?t("creditCard.security").replace("{code}",this.security.textContent||""):"",t("creditCard.show").replace("{side}",t(this.flipped?"creditCard.front":"creditCard.back"))].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};
@@ -1 +1 @@
1
- import{createDbIcon as t,getDbComponentIconSize as e}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{startOfDay as i,parseISODate as s,DEFAULT_DATE_PICKER_PRESETS as n,formatDisplayDate as a,toISODate as r,detectActivePresetId as l,addMonths as d,generateWeekdays as o,generateCalendarGrid as h,formatPanelInputDate as u}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as c,DATE_PICKER_VARIANTS as p}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const m="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}attributeChangedCallback(t){if(this.built){if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return this.getAttribute("locale")||"ko-KR"}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return i(new Date)}get minDate(){return s(this.getAttribute("min-date"))}get maxDate(){return s(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?n:[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${m}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${m}__trigger`;const t=document.createElement("button");t.type="button",t.className=`${m}__icon-display`,t.setAttribute("aria-label","날짜 선택 열기"),t.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${m}__input`,this.inputEl.setAttribute("aria-label","날짜 입력"),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const e=document.createElement("button");e.type="button",e.className=`${m}__toggle`,e.setAttribute("aria-label","날짜 선택 열기"),e.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(t,this.inputEl,e),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${m}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=s(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=s(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(s(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return s(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t){if(!t)return"";if("string"==typeof t){const e=s(t);return e?a(e,this.locale):""}if(Array.isArray(t))return t.map(t=>s(t)).filter(Boolean).map(t=>a(t,this.locale)).join(", ");const e=s(t.start),i=s(t.end);return e&&i?t.start===t.end?a(e,this.locale):`${a(e,this.locale)} ~ ${a(i,this.locale)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=r(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=r(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:r(t),end:r(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:r(s),end:r(i)}:{start:r(i),end:r(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:r(e.start),end:r(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=l(isRangeValue(this.selectedValue)?{start:s(this.selectedValue.start),end:s(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=s(t);if(e&&this.isDateValid(e)){const t=r(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=l(isRangeValue(this.selectedValue)?{start:s(this.selectedValue.start),end:s(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=r(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||r(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=s(t.start),i=s(t.end))}if(!e)return!1;const n=r(t),a=r(e),l=i?r(i):a;return n>=a&&n<=l}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),n=t.toDateString()===this.today.toDateString(),a=this.isDateSelected(t),r=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=s(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?s(o.end)?.toDateString():void 0,u=isRangeValue(o)?s(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${m}__date`,!i&&this.showOutsideDays&&`${m}__date--outside`,n&&`${m}__date--today`,a&&`${m}__date--selected`,r&&!a&&`${m}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${m}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${m}__date--range-end`,l&&`${m}__date--weekend`,!this.isDateValid(t)&&`${m}__date--disabled`,d.length>0&&`${m}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${m}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${m}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${m}__event ${m}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(i,s={}){const{showPrev:n=!1,showNext:a=!1}=s,r=this.getAttribute("size")||"m",l=e(r),u=document.createElement("div");u.className=`${m}__month`;const c=document.createElement("div");if(c.className=`${m}__header`,n){const e=document.createElement("button");e.type="button",e.className=`${m}__nav-button`,e.setAttribute("aria-label","이전 달"),e.disabled=this.disabled||this.readonly,e.appendChild(t("chevron-left",l)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=d(this.viewStartMonth,-1):this.currentMonth=d(this.currentMonth,-1),this.renderCalendar()}),c.appendChild(e)}else{const t=document.createElement("span");t.className=`${m}__nav-spacer`,t.setAttribute("aria-hidden","true"),c.appendChild(t)}const p=document.createElement("div");if(p.className=`${m}__current-month`,p.textContent=i.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),c.appendChild(p),a){const e=document.createElement("button");e.type="button",e.className=`${m}__nav-button`,e.setAttribute("aria-label","다음 달"),e.disabled=this.disabled||this.readonly,e.appendChild(t("chevron-right",l)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=d(this.viewStartMonth,1):this.currentMonth=d(this.currentMonth,1),this.renderCalendar()}),c.appendChild(e)}else{const t=document.createElement("span");t.className=`${m}__nav-spacer`,t.setAttribute("aria-hidden","true"),c.appendChild(t)}u.appendChild(c);const g=document.createElement("div");g.className=`${m}__weekdays`,o(this.startOfWeek).forEach(t=>{const e=document.createElement("div");e.className=`${m}__weekday`,e.textContent=t,g.appendChild(e)}),u.appendChild(g);const b=document.createElement("div");b.className=`${m}__grid`;const v=this.isPanelLayout;return h(i,this.startOfWeek,v).forEach((t,e)=>{if(!t){const t=document.createElement("span");return t.className=`${m}__date ${m}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void b.appendChild(t)}const s=t.getMonth()===i.getMonth()&&t.getFullYear()===i.getFullYear();if(!this.showOutsideDays&&!s){const t=document.createElement("span");return t.className=`${m}__date ${m}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void b.appendChild(t)}b.appendChild(this.renderDateCell(t,i))}),u.appendChild(b),u}renderDefaultCalendar(){const t=document.createElement("div");t.className=`${m}__selector`;const e=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(t.appendChild(this.renderSingleMonth(e,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const e=document.createElement("div");e.className=`${m}__footer`;const i=document.createElement("button");i.type="button",i.className=`${m}__today-button`,i.textContent="오늘",i.disabled=this.disabled||this.readonly,i.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),e.appendChild(i),t.appendChild(e)}return t}renderPanelCalendar(){const t=document.createElement("div");t.className=`${m}__panel`;const e=document.createElement("div");e.className=`${m}__presets`,e.setAttribute("role","listbox"),e.setAttribute("aria-label","기간 프리셋"),this.presets.forEach(t=>{const i=document.createElement("button");i.type="button",i.className=[`${m}__preset`,this.activePresetId===t.id&&`${m}__preset--active`].filter(Boolean).join(" "),i.setAttribute("role","option"),i.setAttribute("aria-selected",String(this.activePresetId===t.id)),i.textContent=t.label,i.addEventListener("click",()=>this.handlePresetSelect(t)),e.appendChild(i)}),t.appendChild(e);const i=document.createElement("div");i.className=`${m}__panel-main`;const n=document.createElement("div");n.className=`${m}__months ${m}__months--count-2`,[0,1].forEach(t=>{const e=d(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),i.appendChild(n);const a=document.createElement("div");a.className=`${m}__panel-footer`;const r=isRangeValue(this.tempValue)?this.tempValue:void 0,l=document.createElement("div");l.className=`${m}__range-display`;const o=document.createElement("span");o.className=`${m}__range-text`,o.textContent=r?.start&&s(r.start)?u(s(r.start),this.locale):"시작일";const h=document.createElement("span");h.className=`${m}__range-separator`,h.textContent="–";const c=document.createElement("span");c.className=`${m}__range-text`,c.textContent=r?.end&&s(r.end)?u(s(r.end),this.locale):"종료일",l.append(o,h,c),a.appendChild(l);const p=document.createElement("div");p.className=`${m}__panel-actions`;const g=document.createElement("db-button");g.setAttribute("variant","secondary"),g.setAttribute("size","m"),g.textContent="취소",g.addEventListener("click",()=>this.handlePendingCancel());const b=document.createElement("db-button");return b.setAttribute("variant","primary"),b.setAttribute("size","m"),b.textContent="적용",b.addEventListener("click",()=>this.handlePendingApply()),p.append(g,b),a.appendChild(p),i.appendChild(a),t.appendChild(i),t}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const i=c.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",s=p.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",n=this.getAttribute("dropdown-position")||"bottom-start",a=e(i);if(this.className=[m,this.inline?`${m}--size-${i}`:`${m}--${i}`,`${m}--variant-${s}`,this.hasAttribute("full-width")&&`${m}--full-width`,this.disabled&&`${m}--disabled`,this.readonly&&`${m}--readonly`,this.isOpen&&`${m}--open`,this.hasAttribute("error")&&`${m}--error`,this.isPanelLayout&&`${m}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const r=this.getAttribute("label")||"";this.labelEl.textContent=r,this.labelEl.hidden=!r,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const l=this.triggerEl.querySelector(`.${m}__icon-display`);l&&(l.innerHTML="",l.appendChild(t("calendar",a)),l.disabled=this.disabled);const d=this.triggerEl.querySelector(`.${m}__toggle`);if(d&&(d.innerHTML="",d.appendChild(t("chevron-down",a)),d.disabled=this.disabled),this.dropdownEl.className=[`${m}__dropdown`,`${m}__dropdown--${n}`,this.isPanelLayout&&`${m}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const t=document.createElement("db-modal");t.setAttribute("open","true"),t.setAttribute("title",this.isPanelLayout?"기간 선택":"날짜 선택"),t.setAttribute("size",this.isPanelLayout?"l":"s"),t.addEventListener("db-close",()=>this.handlePendingCancel());const e=document.createElement("div");if(this.calendarHost=e,this.renderCalendar(),t.append(e),this.usesPendingValue){const e=document.createElement("div");e.className=`${m}__modal-footer`;const i=document.createElement("db-button");i.setAttribute("variant","secondary"),i.setAttribute("size","m"),i.textContent="취소",i.addEventListener("click",()=>this.handlePendingCancel());const s=document.createElement("db-button");s.setAttribute("variant","primary"),s.setAttribute("size","m"),s.textContent="적용",s.addEventListener("click",()=>this.handlePendingApply()),e.append(i,s),t.append(e)}this.appendChild(t)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
1
+ import{dbText as t,getDbLocale as e}from"../core/i18n.js";import{createDbIcon as i,getDbComponentIconSize as s}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{startOfDay as n,parseISODate as a,DEFAULT_DATE_PICKER_PRESETS as r,formatDisplayDate as l,toISODate as d,detectActivePresetId as o,addMonths as h,generateWeekdays as u,generateCalendarGrid as c,formatPanelInputDate as p}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as m,DATE_PICKER_VARIANTS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const b="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}attributeChangedCallback(t){if(this.built){if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return this.getAttribute("locale")||("ko"===e()?"ko-KR":"en-US")}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return n(new Date)}get minDate(){return a(this.getAttribute("min-date"))}get maxDate(){return a(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?r.map(e=>({...e,label:t(e.label)})):[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${b}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${b}__trigger`;const e=document.createElement("button");e.type="button",e.className=`${b}__icon-display`,e.setAttribute("aria-label",t("날짜 선택 열기")),e.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${b}__input`,this.inputEl.setAttribute("aria-label",t("날짜 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${b}__toggle`,i.setAttribute("aria-label",t("날짜 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(e,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${b}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=a(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=a(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(a(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return a(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t){if(!t)return"";if("string"==typeof t){const e=a(t);return e?l(e,this.locale):""}if(Array.isArray(t))return t.map(t=>a(t)).filter(Boolean).map(t=>l(t,this.locale)).join(", ");const e=a(t.start),i=a(t.end);return e&&i?t.start===t.end?l(e,this.locale):`${l(e,this.locale)} ~ ${l(i,this.locale)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=d(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=d(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:d(t),end:d(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:d(s),end:d(i)}:{start:d(i),end:d(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:d(e.start),end:d(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=a(t);if(e&&this.isDateValid(e)){const t=d(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=d(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||d(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=a(t.start),i=a(t.end))}if(!e)return!1;const s=d(t),n=d(e),r=i?d(i):n;return s>=n&&s<=r}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),s=t.toDateString()===this.today.toDateString(),n=this.isDateSelected(t),r=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=a(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?a(o.end)?.toDateString():void 0,u=isRangeValue(o)?a(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${b}__date`,!i&&this.showOutsideDays&&`${b}__date--outside`,s&&`${b}__date--today`,n&&`${b}__date--selected`,r&&!n&&`${b}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${b}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${b}__date--range-end`,l&&`${b}__date--weekend`,!this.isDateValid(t)&&`${b}__date--disabled`,d.length>0&&`${b}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${b}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${b}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${b}__event ${b}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(e,n={}){const{showPrev:a=!1,showNext:r=!1}=n,l=this.getAttribute("size")||"m",d=s(l),o=document.createElement("div");o.className=`${b}__month`;const p=document.createElement("div");if(p.className=`${b}__header`,a){const e=document.createElement("button");e.type="button",e.className=`${b}__nav-button`,e.setAttribute("aria-label",t("이전 달")),e.disabled=this.disabled||this.readonly,e.appendChild(i("chevron-left",d)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,-1):this.currentMonth=h(this.currentMonth,-1),this.renderCalendar()}),p.appendChild(e)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}const m=document.createElement("div");if(m.className=`${b}__current-month`,m.textContent=e.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),p.appendChild(m),r){const e=document.createElement("button");e.type="button",e.className=`${b}__nav-button`,e.setAttribute("aria-label",t("다음 달")),e.disabled=this.disabled||this.readonly,e.appendChild(i("chevron-right",d)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,1):this.currentMonth=h(this.currentMonth,1),this.renderCalendar()}),p.appendChild(e)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}o.appendChild(p);const g=document.createElement("div");g.className=`${b}__weekdays`,u(this.startOfWeek,this.locale).forEach(t=>{const e=document.createElement("div");e.className=`${b}__weekday`,e.textContent=t,g.appendChild(e)}),o.appendChild(g);const v=document.createElement("div");v.className=`${b}__grid`;const y=this.isPanelLayout;return c(e,this.startOfWeek,y).forEach((t,i)=>{if(!t){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void v.appendChild(t)}const s=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear();if(!this.showOutsideDays&&!s){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void v.appendChild(t)}v.appendChild(this.renderDateCell(t,e))}),o.appendChild(v),o}renderDefaultCalendar(){const e=document.createElement("div");e.className=`${b}__selector`;const i=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(e.appendChild(this.renderSingleMonth(i,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const i=document.createElement("div");i.className=`${b}__footer`;const s=document.createElement("button");s.type="button",s.className=`${b}__today-button`,s.textContent=t("오늘"),s.disabled=this.disabled||this.readonly,s.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),i.appendChild(s),e.appendChild(i)}return e}renderPanelCalendar(){const e=document.createElement("div");e.className=`${b}__panel`;const i=document.createElement("div");i.className=`${b}__presets`,i.setAttribute("role","listbox"),i.setAttribute("aria-label",t("기간 프리셋")),this.presets.forEach(t=>{const e=document.createElement("button");e.type="button",e.className=[`${b}__preset`,this.activePresetId===t.id&&`${b}__preset--active`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(this.activePresetId===t.id)),e.textContent=t.label,e.addEventListener("click",()=>this.handlePresetSelect(t)),i.appendChild(e)}),e.appendChild(i);const s=document.createElement("div");s.className=`${b}__panel-main`;const n=document.createElement("div");n.className=`${b}__months ${b}__months--count-2`,[0,1].forEach(t=>{const e=h(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),s.appendChild(n);const r=document.createElement("div");r.className=`${b}__panel-footer`;const l=isRangeValue(this.tempValue)?this.tempValue:void 0,d=document.createElement("div");d.className=`${b}__range-display`;const o=document.createElement("span");o.className=`${b}__range-text`,o.textContent=l?.start&&a(l.start)?p(a(l.start),this.locale):"시작일";const u=document.createElement("span");u.className=`${b}__range-separator`,u.textContent="–";const c=document.createElement("span");c.className=`${b}__range-text`,c.textContent=l?.end&&a(l.end)?p(a(l.end),this.locale):"종료일",d.append(o,u,c),r.appendChild(d);const m=document.createElement("div");m.className=`${b}__panel-actions`;const g=document.createElement("db-button");g.setAttribute("variant","secondary"),g.setAttribute("size","m"),g.textContent=t("취소"),g.addEventListener("click",()=>this.handlePendingCancel());const v=document.createElement("db-button");return v.setAttribute("variant","primary"),v.setAttribute("size","m"),v.textContent=t("적용"),v.addEventListener("click",()=>this.handlePendingApply()),m.append(g,v),r.appendChild(m),s.appendChild(r),e.appendChild(s),e}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const e=m.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",n=g.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",a=this.getAttribute("dropdown-position")||"bottom-start",r=s(e);if(this.className=[b,this.inline?`${b}--size-${e}`:`${b}--${e}`,`${b}--variant-${n}`,this.hasAttribute("full-width")&&`${b}--full-width`,this.disabled&&`${b}--disabled`,this.readonly&&`${b}--readonly`,this.isOpen&&`${b}--open`,this.hasAttribute("error")&&`${b}--error`,this.isPanelLayout&&`${b}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const l=this.getAttribute("label")||"";this.labelEl.textContent=l,this.labelEl.hidden=!l,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${b}__icon-display`);d&&(d.innerHTML="",d.appendChild(i("calendar",r)),d.disabled=this.disabled);const o=this.triggerEl.querySelector(`.${b}__toggle`);if(o&&(o.innerHTML="",o.appendChild(i("chevron-down",r)),o.disabled=this.disabled),this.dropdownEl.className=[`${b}__dropdown`,`${b}__dropdown--${a}`,this.isPanelLayout&&`${b}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const e=document.createElement("db-modal");e.setAttribute("open","true"),e.setAttribute("title",this.isPanelLayout?"기간 선택":"날짜 선택"),e.setAttribute("size",this.isPanelLayout?"l":"s"),e.addEventListener("db-close",()=>this.handlePendingCancel());const i=document.createElement("div");if(this.calendarHost=i,this.renderCalendar(),e.append(i),this.usesPendingValue){const i=document.createElement("div");i.className=`${b}__modal-footer`;const s=document.createElement("db-button");s.setAttribute("variant","secondary"),s.setAttribute("size","m"),s.textContent=t("취소"),s.addEventListener("click",()=>this.handlePendingCancel());const n=document.createElement("db-button");n.setAttribute("variant","primary"),n.setAttribute("size","m"),n.textContent=t("적용"),n.addEventListener("click",()=>this.handlePendingApply()),i.append(s,n),e.append(i)}this.appendChild(e)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
@@ -0,0 +1,137 @@
1
+ import './db-button.js';
2
+ import './db-input.js';
3
+ import './db-card.js';
4
+ import './db-badge.js';
5
+
6
+ interface DesignCanvasNode {
7
+ id: string;
8
+ type: 'frame' | 'image' | 'text' | 'shape' | 'component';
9
+ name: string;
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ rotation?: number;
15
+ flipX?: boolean;
16
+ flipY?: boolean;
17
+ src?: string;
18
+ slot?: string;
19
+ fill?: string;
20
+ opacity?: number;
21
+ radius?: number;
22
+ locked?: boolean;
23
+ text?: string;
24
+ fontSize?: number;
25
+ fontWeight?: number;
26
+ textColor?: string;
27
+ textAlign?: 'left' | 'center' | 'right';
28
+ shape?: 'rectangle' | 'ellipse' | 'triangle' | 'line';
29
+ component?: 'button' | 'input' | 'card' | 'badge';
30
+ stroke?: string;
31
+ strokeWidth?: number;
32
+ }
33
+ interface DesignCanvasViewport {
34
+ x: number;
35
+ y: number;
36
+ zoom: number;
37
+ }
38
+ interface DesignCanvasChange {
39
+ nodes: DesignCanvasNode[];
40
+ selectedId: string | null;
41
+ reason: string;
42
+ }
43
+ type Point = {
44
+ x: number;
45
+ y: number;
46
+ };
47
+ /** DOM canvas with serializable nodes. Slot a React/Vue-owned frame using node.slot. */
48
+ declare class DbDesignCanvas extends HTMLElement {
49
+ static get observedAttributes(): string[];
50
+ private data;
51
+ private selected;
52
+ private view;
53
+ private surface?;
54
+ private world?;
55
+ private toolbar?;
56
+ private contextBar?;
57
+ private status?;
58
+ private selection?;
59
+ private input?;
60
+ private objectElements;
61
+ private slots;
62
+ private observer?;
63
+ private resizeObserver?;
64
+ private gesture?;
65
+ private pointers;
66
+ private pinch?;
67
+ private space;
68
+ private hand;
69
+ private creationTool;
70
+ private shapeTool;
71
+ private componentTool;
72
+ private editing?;
73
+ private past;
74
+ private future;
75
+ private reading;
76
+ private generation;
77
+ get nodes(): DesignCanvasNode[];
78
+ set nodes(value: DesignCanvasNode[] | string);
79
+ get selectedId(): string | null;
80
+ set selectedId(value: string | null);
81
+ get viewport(): DesignCanvasViewport;
82
+ set viewport(value: DesignCanvasViewport);
83
+ get minZoom(): number;
84
+ get maxZoom(): number;
85
+ get readOnly(): boolean;
86
+ set readOnly(value: boolean);
87
+ connectedCallback(): void;
88
+ disconnectedCallback(): void;
89
+ attributeChangedCallback(name: string): void;
90
+ private normalizeNode;
91
+ private ensureStructure;
92
+ private collectSlots;
93
+ private draw;
94
+ private drawText;
95
+ private drawShape;
96
+ private drawComponent;
97
+ private beginTextEdit;
98
+ private drawViewport;
99
+ private drawSelection;
100
+ private syncToolbar;
101
+ private syncContext;
102
+ private insertNode;
103
+ private positionContext;
104
+ private toolAction;
105
+ private select;
106
+ private emit;
107
+ private emitViewport;
108
+ private remember;
109
+ undo(): void;
110
+ redo(): void;
111
+ private point;
112
+ zoomTo(zoom: number, anchor?: Point): void;
113
+ fitToContent(): void;
114
+ private editable;
115
+ private onPointerDown;
116
+ private onPointerMove;
117
+ private onPointerUp;
118
+ private cancelGesture;
119
+ private onPointerCancel;
120
+ private onLostCapture;
121
+ private onWheel;
122
+ private onKeyUp;
123
+ private onBlur;
124
+ private onKeyDown;
125
+ private onDragOver;
126
+ private onDragLeave;
127
+ private onDrop;
128
+ importImages(files: File[], point?: Point): Promise<void>;
129
+ }
130
+ declare global {
131
+ interface HTMLElementTagNameMap {
132
+ 'db-design-canvas': DbDesignCanvas;
133
+ }
134
+ }
135
+
136
+ export { DbDesignCanvas };
137
+ export type { DesignCanvasChange, DesignCanvasNode, DesignCanvasViewport };