@designbasekorea/ui-wc 0.8.12 → 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 (186) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE-PAYMENT-LOGOS.md +437 -0
  3. package/README.md +61 -23
  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-form.js +1 -1
  110. package/dist/esm/components/db-glyph-matrix.d.ts +58 -0
  111. package/dist/esm/components/db-glyph-matrix.js +1 -0
  112. package/dist/esm/components/db-icons.d.ts +1 -1
  113. package/dist/esm/components/db-icons.js +1 -1
  114. package/dist/esm/components/db-menu-item.d.ts +2 -0
  115. package/dist/esm/components/db-menu-item.js +1 -1
  116. package/dist/esm/components/db-modal.d.ts +1 -1
  117. package/dist/esm/components/db-modal.js +1 -1
  118. package/dist/esm/components/db-navbar.d.ts +3 -1
  119. package/dist/esm/components/db-navbar.js +1 -1
  120. package/dist/esm/components/db-navigation-rail.d.ts +1 -1
  121. package/dist/esm/components/db-node.d.ts +83 -0
  122. package/dist/esm/components/db-node.js +1 -0
  123. package/dist/esm/components/db-notification-dropdown.d.ts +30 -0
  124. package/dist/esm/components/db-notification-dropdown.js +1 -0
  125. package/dist/esm/components/db-notification-inbox.d.ts +25 -0
  126. package/dist/esm/components/db-notification-inbox.js +1 -0
  127. package/dist/esm/components/db-otp-input.d.ts +1 -1
  128. package/dist/esm/components/db-phone-verify.d.ts +1 -1
  129. package/dist/esm/components/db-plan-overview.d.ts +26 -0
  130. package/dist/esm/components/db-plan-overview.js +1 -0
  131. package/dist/esm/components/db-popover.js +1 -1
  132. package/dist/esm/components/db-progressive-blur.d.ts +35 -0
  133. package/dist/esm/components/db-progressive-blur.js +1 -0
  134. package/dist/esm/components/db-receipt.d.ts +37 -0
  135. package/dist/esm/components/db-receipt.js +1 -0
  136. package/dist/esm/components/db-search-bar.js +1 -1
  137. package/dist/esm/components/db-segment-control.js +1 -1
  138. package/dist/esm/components/db-select.js +1 -1
  139. package/dist/esm/components/db-sidebar.d.ts +14 -1
  140. package/dist/esm/components/db-sidebar.js +1 -1
  141. package/dist/esm/components/db-split-view.d.ts +2 -0
  142. package/dist/esm/components/db-split-view.js +1 -1
  143. package/dist/esm/components/db-textarea.js +1 -1
  144. package/dist/esm/components/db-ticket.d.ts +18 -0
  145. package/dist/esm/components/db-ticket.js +1 -0
  146. package/dist/esm/components/db-time-picker.d.ts +1 -1
  147. package/dist/esm/components/db-tool-button.d.ts +57 -0
  148. package/dist/esm/components/db-tool-button.js +1 -0
  149. package/dist/esm/components/db-tweet-card.d.ts +101 -0
  150. package/dist/esm/components/db-tweet-card.js +1 -0
  151. package/dist/esm/components/db-two-factor.d.ts +1 -1
  152. package/dist/esm/components/db-voice-control.d.ts +25 -0
  153. package/dist/esm/components/db-voice-control.js +1 -0
  154. package/dist/esm/components/db-workspace-invite-modal.d.ts +51 -0
  155. package/dist/esm/components/db-workspace-invite-modal.js +1 -0
  156. package/dist/esm/components/db-workspace-members.d.ts +36 -0
  157. package/dist/esm/components/db-workspace-members.js +1 -0
  158. package/dist/esm/components/device-mockup-style.js +1 -0
  159. package/dist/esm/components/flight-route.js +1 -0
  160. package/dist/esm/components/node-style.js +1 -0
  161. package/dist/esm/components/paper-card.d.ts +26 -0
  162. package/dist/esm/components/paper-card.js +1 -0
  163. package/dist/esm/components/random-gradient-palettes.d.ts +4 -0
  164. package/dist/esm/core/ai-element.d.ts +47 -0
  165. package/dist/esm/core/ai-element.js +1 -0
  166. package/dist/esm/core/credit-ui.js +1 -0
  167. package/dist/esm/core/i18n.d.ts +153 -0
  168. package/dist/esm/core/i18n.js +1 -1
  169. package/dist/esm/core/notification-ui.d.ts +17 -0
  170. package/dist/esm/core/notification-ui.js +1 -0
  171. package/dist/esm/helpers/payment-brands.d.ts +56 -0
  172. package/dist/esm/helpers/payment-brands.js +1 -0
  173. package/dist/esm/helpers/toast.d.ts +2 -3
  174. package/dist/esm/index.d.ts +62 -2
  175. package/dist/esm/index.js +1 -1
  176. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  177. package/dist/esm/ui-contracts/dist/components.d.d.ts +76 -0
  178. package/dist/esm/ui-contracts/dist/primitives.d.d.ts +21 -0
  179. package/dist/index.cjs +1 -1
  180. package/dist/index.css +1 -1
  181. package/dist/index.d.ts +2149 -23
  182. package/dist/index.esm.js +1 -1
  183. package/dist/react/index.cjs +1 -1
  184. package/dist/react/index.d.ts +786 -6727
  185. package/dist/react/index.esm.js +1 -1
  186. package/package.json +13 -7
@@ -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 };
@@ -0,0 +1 @@
1
+ import"./db-button.js";import"./db-input.js";import"./db-card.js";import"./db-badge.js";const clamp=(t,e,i)=>Math.min(i,Math.max(e,t)),num=(t,e)=>"number"==typeof t&&Number.isFinite(t)?t:e,clone=t=>t.map(t=>({...t})),same=(t,e)=>t.length===e.length&&t.every((t,i)=>Object.keys({...t,...e[i]}).every(s=>t[s]===e[i][s]));class DbDesignCanvas extends HTMLElement{constructor(){super(...arguments),this.data=[],this.selected=null,this.view={x:0,y:0,zoom:1},this.objectElements=new Map,this.slots=new Map,this.pointers=new Map,this.space=!1,this.hand=!1,this.creationTool="frame",this.shapeTool="rectangle",this.componentTool="button",this.past=[],this.future=[],this.reading=new Set,this.generation=0,this.beginTextEdit=t=>{if(this.hand||this.space)return;const e=t.target.closest("[data-node-id]")||document.elementFromPoint(t.clientX,t.clientY)?.closest("[data-node-id]"),i=this.data.find(t=>t.id===e?.dataset.nodeId);if(!i||"text"!==i.type||i.locked||this.readOnly)return;const s=e.querySelector(".designbase-wc-design-canvas__text");if(s.isContentEditable)return;t.preventDefault(),this.editing={id:i.id,before:this.nodes},s.contentEditable="plaintext-only",s.setAttribute("role","textbox"),s.setAttribute("aria-label","텍스트 편집"),s.tabIndex=0,s.focus();const finish=(t=!1)=>{if(this.editing?.id!==i.id)return;const e=this.editing.before;this.editing=void 0,s.removeEventListener("input",input),s.removeEventListener("keydown",key),s.removeEventListener("blur",blur),s.contentEditable="false",s.removeAttribute("role"),s.removeAttribute("aria-label"),s.tabIndex=-1,t?this.data=e:same(e,this.data)||this.remember(e),this.emit(t?"text-cancel":"text")},input=()=>{const t=(s.innerText||"").slice(0,1e4);this.data=this.data.map(e=>e.id===i.id?{...e,text:t}:e),this.emit("text-input")},key=t=>{("Escape"===t.key||"Enter"===t.key&&(t.ctrlKey||t.metaKey))&&(t.preventDefault(),t.stopPropagation(),finish("Escape"===t.key),s.blur(),this.surface?.focus({preventScroll:!0}))},blur=()=>finish();s.addEventListener("input",input),s.addEventListener("keydown",key),s.addEventListener("blur",blur)},this.toolAction=t=>{t.stopPropagation();const{id:e,optionId:i}=t.detail;if("select"===e||"pan"===e)return this.hand="pan"===e,void this.drawViewport();if("image"===e)return void(this.readOnly||this.input?.click());if("undo"===e)return void this.undo();if("redo"===e)return void this.redo();if("zoom-in"===e)return void this.zoomTo(1.2*this.view.zoom);if("zoom-out"===e)return void this.zoomTo(this.view.zoom/1.2);if("fit"===e||"zoom"===e&&"fit"===i)return void this.fitToContent();if("zoom"===e){const t=Number(i)/100;return void(t>0&&this.zoomTo(t))}if(this.readOnly)return;if(["frame","text","shape","component"].includes(e))return void this.insertNode(e,i);const s=this.data.find(t=>t.id===this.selected);if(s&&(!s.locked||"lock"===e)&&("duplicate"!==e||!(s.slot||this.data.length>=100))){if(this.remember(this.data),"duplicate"===e){const t={...s,id:crypto.randomUUID(),name:`${s.name} 복사`,x:s.x+24,y:s.y+24};this.data=[...this.data,t],this.select(t.id)}else if("delete"===e)this.data=this.data.filter(t=>t.id!==s.id),this.select(null);else if("arrange"===e){const t=this.data.filter(t=>t.id!==s.id);this.data="front"===i?[...t,s]:[s,...t]}else{const t={...s};if("lock"===e&&(t.locked=!s.locked),"rotate"===e&&(t.rotation="reset"===i?0:(s.rotation||0)+("left"===i?-90:90)),"flip-x"===e&&(t.flipX=!s.flipX),"flip-y"===e&&(t.flipY=!s.flipY),("align"===e||e.startsWith("align-"))&&this.surface){const o="align"===e?i:e.slice(6),n=-this.view.x/this.view.zoom,a=-this.view.y/this.view.zoom,r=this.surface.clientWidth/this.view.zoom/2,h=this.surface.clientHeight/this.view.zoom/2,d=(s.rotation||0)*Math.PI/180,l=Math.abs(s.width*Math.cos(d))+Math.abs(s.height*Math.sin(d)),c=Math.abs(s.width*Math.sin(d))+Math.abs(s.height*Math.cos(d));"center"===o&&(t.x=n-s.width/2),"middle"===o&&(t.y=a-s.height/2),"left"===o&&(t.x=n-r+(l-s.width)/2+24),"right"===o&&(t.x=n+r-(l+s.width)/2-24),"top"===o&&(t.y=a-h+(c-s.height)/2+24),"bottom"===o&&(t.y=a+h-(c+s.height)/2-24)}this.data=this.data.map(e=>e.id===s.id?t:e)}this.emit(e)}},this.onPointerDown=t=>{if(t.target.closest("db-tool-button,db-design-toolbar,db-context-bar"))return;if(0!==t.button&&1!==t.button)return;if(this.pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),"touch"===t.pointerType&&2===this.pointers.size){this.cancelGesture();const[e,i]=[...this.pointers.values()],s={clientX:(e.x+i.x)/2,clientY:(e.y+i.y)/2};return this.pinch={distance:Math.hypot(e.x-i.x,e.y-i.y),zoom:this.view.zoom,world:this.point(s)},void this.surface.setPointerCapture(t.pointerId)}if(this.editable(t))return;const e=t.target,i=e.closest("[data-handle]")?.dataset.handle,s=e.closest("[data-node-id]")?.dataset.nodeId;s&&this.select(s);const o=this.data.find(t=>t.id===this.selected),n=this.space||this.hand||1===t.button;if(!n&&!i&&!s)return this.surface.focus({preventScroll:!0}),this.surface.setPointerCapture(t.pointerId),void this.select(null);if((n||o&&!o.locked&&!this.readOnly)&&(n||!e.closest("db-button,button,a,input,textarea,select")||i)){if(t.preventDefault(),this.surface.focus({preventScroll:!0}),this.gesture={kind:n?"pan":"rotate"===i?"rotate":i?"resize":"move",pointer:t.pointerId,start:{x:t.clientX,y:t.clientY},viewport:this.viewport,node:o?{...o}:void 0,handle:i,before:this.nodes},"rotate"===this.gesture.kind&&o){const e=this.point(t);this.gesture.angle=Math.atan2(e.y-o.y-o.height/2,e.x-o.x-o.width/2)}this.surface.setPointerCapture(t.pointerId),this.drawViewport()}},this.onPointerMove=t=>{if(this.pointers.has(t.pointerId)&&this.pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.pinch&&this.pointers.size>=2){const[t,e]=[...this.pointers.values()],i=this.surface.getBoundingClientRect();return this.view.zoom=clamp(this.pinch.zoom*Math.hypot(t.x-e.x,t.y-e.y)/Math.max(1,this.pinch.distance),this.minZoom,this.maxZoom),this.view.x=(t.x+e.x)/2-i.left-this.surface.clientWidth/2-this.pinch.world.x*this.view.zoom,this.view.y=(t.y+e.y)/2-i.top-this.surface.clientHeight/2-this.pinch.world.y*this.view.zoom,void this.emitViewport()}const e=this.gesture;if(!e||e.pointer!==t.pointerId)return;if("pan"===e.kind)return this.view.x=e.viewport.x+t.clientX-e.start.x,this.view.y=e.viewport.y+t.clientY-e.start.y,void this.emitViewport();const i=e.node;let s={...i};const o=(t.clientX-e.start.x)/e.viewport.zoom,n=(t.clientY-e.start.y)/e.viewport.zoom,a=(i.rotation||0)*Math.PI/180;if("move"===e.kind){const e=Number(this.getAttribute("snap-to-grid"))||0,round=i=>e>0&&!t.altKey?Math.round(i/e)*e:Math.round(i);s.x=round(i.x+o),s.y=round(i.y+n)}if("rotate"===e.kind){const o=this.point(t),n=Math.atan2(o.y-i.y-i.height/2,o.x-i.x-i.width/2),a=(i.rotation||0)+180*(n-e.angle)/Math.PI;s.rotation=t.shiftKey?15*Math.round(a/15):Math.round(a)}if("resize"===e.kind){const r=o*Math.cos(a)+n*Math.sin(a),h=-o*Math.sin(a)+n*Math.cos(a),d=e.handle;let l=clamp(i.width+(d.includes("e")?r:d.includes("w")?-r:0),16,8e3),c=clamp(i.height+(d.includes("s")?h:d.includes("n")?-h:0),16,8e3);if(t.shiftKey&&2===d.length){const t=Math.max(l/i.width,c/i.height),e=clamp(t,Math.max(16/i.width,16/i.height),Math.min(8e3/i.width,8e3/i.height));l=i.width*e,c=i.height*e}const u=(l-i.width)/2*(d.includes("w")?-1:d.includes("e")?1:0),p=(c-i.height)/2*(d.includes("n")?-1:d.includes("s")?1:0);s.width=Math.round(l),s.height=Math.round(c),s.x=i.x+i.width/2+u*Math.cos(a)-p*Math.sin(a)-s.width/2,s.y=i.y+i.height/2+u*Math.sin(a)+p*Math.cos(a)-s.height/2}this.data=this.data.map(t=>t.id===i.id?s:t),this.emit(e.kind)},this.onPointerUp=t=>{this.pointers.delete(t.pointerId),this.pointers.size<2&&(this.pinch=void 0);const e=this.gesture;e?.pointer===t.pointerId&&(this.gesture=void 0,"pan"===e.kind||same(e.before,this.data)||(this.remember(e.before),this.emit("commit"))),this.surface?.hasPointerCapture(t.pointerId)&&this.surface.releasePointerCapture(t.pointerId),this.drawViewport()},this.onPointerCancel=t=>{this.pointers.delete(t.pointerId),this.pinch=void 0,this.cancelGesture(),this.drawViewport()},this.onLostCapture=t=>{this.gesture?.pointer===t.pointerId&&this.cancelGesture()},this.onWheel=t=>{t.target.closest("db-context-bar")||this.gesture||this.pinch||(t.preventDefault(),t.ctrlKey||t.metaKey?this.zoomTo(this.view.zoom*Math.exp(.002*-t.deltaY),{x:t.clientX,y:t.clientY}):(this.view.x-=t.deltaX,this.view.y-=t.deltaY,this.emitViewport()))},this.onKeyUp=t=>{"Space"!==t.code&&" "!==t.key||(this.space=!1,this.drawViewport())},this.onBlur=()=>{this.space=!1,this.cancelGesture(),this.pointers.clear(),this.pinch=void 0,this.drawViewport()},this.onKeyDown=t=>{if(t.defaultPrevented||t.target.closest("db-tool-button,db-design-toolbar,db-context-bar"))return;if(this.editable(t))return;if("Space"===t.code||" "===t.key)return t.preventDefault(),this.space=!0,void this.drawViewport();if("Escape"===t.key)return t.preventDefault(),void(this.gesture?this.cancelGesture():this.select(null));if("h"!==t.key.toLowerCase()||t.ctrlKey||t.metaKey||(this.hand=!0,this.drawViewport()),"v"!==t.key.toLowerCase()||t.ctrlKey||t.metaKey||(this.hand=!1,this.drawViewport()),(t.ctrlKey||t.metaKey)&&"z"===t.key.toLowerCase())return t.preventDefault(),void(t.shiftKey?this.redo():this.undo());if((t.ctrlKey||t.metaKey)&&"y"===t.key.toLowerCase())return t.preventDefault(),void this.redo();if("+"===t.key||"="===t.key)return t.preventDefault(),void this.zoomTo(1.2*this.view.zoom);if("-"===t.key)return t.preventDefault(),void this.zoomTo(this.view.zoom/1.2);if("0"===t.key)return t.preventDefault(),void(t.shiftKey?this.zoomTo(1):this.fitToContent());if(!t.ctrlKey&&!t.metaKey&&!t.altKey){const e=t.key.toLowerCase();if(["t","r","o","l","f"].includes(e))return t.preventDefault(),void("t"===e?this.insertNode("text"):"f"===e?this.insertNode("frame","frame"):this.insertNode("shape","r"===e?"rectangle":"o"===e?"ellipse":"line"))}const e=this.data.find(t=>t.id===this.selected);if(e&&!e.locked&&!this.readOnly){if("Delete"===t.key||"Backspace"===t.key)return t.preventDefault(),this.remember(this.data),this.data=this.data.filter(t=>t.id!==e.id),this.select(null),void this.emit("delete");if(["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(t.key)){t.preventDefault();const i=t.shiftKey?10:1,s={...e},o=t.target.dataset.handle;this.remember(this.data),"rotate"===o?s.rotation=(e.rotation||0)+("ArrowLeft"===t.key||"ArrowDown"===t.key?-i:i):o?"ArrowLeft"===t.key||"ArrowRight"===t.key?s.width=clamp(e.width+("ArrowRight"===t.key?i:-i),16,8e3):s.height=clamp(e.height+("ArrowDown"===t.key?i:-i),16,8e3):(s.x+="ArrowRight"===t.key?i:"ArrowLeft"===t.key?-i:0,s.y+="ArrowDown"===t.key?i:"ArrowUp"===t.key?-i:0),this.data=this.data.map(t=>t.id===e.id?s:t),this.emit("keyboard")}}},this.onDragOver=t=>{!this.readOnly&&t.dataTransfer?.types.includes("Files")&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",this.surface?.classList.add("designbase-wc-design-canvas__surface--drop"))},this.onDragLeave=t=>{this.surface?.contains(t.relatedTarget)||this.surface?.classList.remove("designbase-wc-design-canvas__surface--drop")},this.onDrop=t=>{t.preventDefault(),this.surface?.classList.remove("designbase-wc-design-canvas__surface--drop"),!this.readOnly&&t.dataTransfer&&this.importImages(Array.from(t.dataTransfer.files),this.point(t))}}static get observedAttributes(){return["nodes","selected-id","min-zoom","max-zoom","readonly","snap-to-grid","grid-size","show-grid","height","max-file-size","toolbar-mode"]}get nodes(){return clone(this.data)}set nodes(t){try{const e="string"==typeof t?JSON.parse(t):t;if(!Array.isArray(e))return;const i=new Set,s=e.filter(t=>t&&"string"==typeof t.id&&t.id&&!i.has(t.id)&&!!i.add(t.id)).slice(0,100).map(t=>this.normalizeNode(t));if(same(this.data,s))return;this.data.length&&!this.gesture&&this.remember(this.data),this.data=s,this.data.some(t=>t.id===this.selected)||(this.selected=null),this.draw()}catch{}}get selectedId(){return this.selected}set selectedId(t){this.selected=this.data.some(e=>e.id===t)?t:null,this.drawSelection()}get viewport(){return{...this.view}}set viewport(t){this.view={x:num(t?.x,0),y:num(t?.y,0),zoom:clamp(num(t?.zoom,1),this.minZoom,this.maxZoom)},this.drawViewport()}get minZoom(){return clamp(Number(this.getAttribute("min-zoom"))||.1,.05,4)}get maxZoom(){return Math.max(this.minZoom,Math.min(8,Number(this.getAttribute("max-zoom"))||4))}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}connectedCallback(){this.generation++,this.ensureStructure(),this.collectSlots(),this.observer=new MutationObserver(()=>{this.collectSlots(),this.draw()}),this.observer.observe(this,{childList:!0}),this.resizeObserver=new ResizeObserver(()=>this.drawViewport()),this.resizeObserver.observe(this.surface),window.addEventListener("keyup",this.onKeyUp),window.addEventListener("blur",this.onBlur),this.draw()}disconnectedCallback(){this.generation++,this.editing=void 0,this.observer?.disconnect(),this.resizeObserver?.disconnect(),window.removeEventListener("keyup",this.onKeyUp),window.removeEventListener("blur",this.onBlur),this.cancelGesture(),this.space=!1,this.pointers.clear(),this.pinch=void 0;for(const t of this.reading)t.abort();this.reading.clear()}attributeChangedCallback(t){"nodes"===t?this.nodes=this.getAttribute("nodes")||"[]":"selected-id"===t?this.selectedId=this.getAttribute("selected-id"):("readonly"===t&&this.cancelGesture(),this.view.zoom=clamp(this.view.zoom,this.minZoom,this.maxZoom),this.draw())}normalizeNode(t){return{...t,type:["frame","image","text","shape","component"].includes(t.type)?t.type:"frame",name:"string"==typeof t.name?t.name:"요소",x:num(t.x,0),y:num(t.y,0),width:clamp(num(t.width,320),16,8e3),height:clamp(num(t.height,240),16,8e3),rotation:num(t.rotation,0),flipX:!0===t.flipX,flipY:!0===t.flipY,opacity:clamp(num(t.opacity,1),0,1),radius:clamp(num(t.radius,0),0,4e3),text:"string"==typeof t.text?t.text.slice(0,1e4):"",fontSize:clamp(num(t.fontSize,24),8,240),fontWeight:clamp(num(t.fontWeight,400),100,900),textColor:t.textColor||"#191919",textAlign:["left","center","right"].includes(t.textAlign||"")?t.textAlign:"left",shape:["rectangle","ellipse","triangle","line"].includes(t.shape||"")?t.shape:"rectangle",component:["button","input","card","badge"].includes(t.component||"")?t.component:"button",stroke:t.stroke||"#191919",strokeWidth:clamp(num(t.strokeWidth,1),0,24)}}ensureStructure(){if(this.surface)return;this.classList.add("designbase-wc-design-canvas"),this.setAttribute("role","region"),this.hasAttribute("aria-label")||this.setAttribute("aria-label","디자인 캔버스"),this.toolbar=document.createElement("db-design-toolbar"),this.toolbar.classList.add("designbase-wc-design-canvas__toolbar"),this.toolbar.setAttribute("aria-label","캔버스 도구"),this.toolbar.setAttribute("size","s"),this.toolbar.addEventListener("db-tool-action",this.toolAction),this.input=document.createElement("input"),this.input.type="file",this.input.multiple=!0,this.input.accept="image/png,image/jpeg,image/webp,image/gif",this.input.hidden=!0,this.input.addEventListener("change",()=>{this.importImages(Array.from(this.input.files||[])),this.input.value=""}),this.surface=document.createElement("div"),this.surface.className="designbase-wc-design-canvas__surface",this.surface.tabIndex=0,this.surface.setAttribute("aria-label","캔버스 작업 영역"),this.surface.setAttribute("aria-describedby",this.id?`${this.id}-help`:""),this.world=document.createElement("div"),this.world.className="designbase-wc-design-canvas__world",this.selection=document.createElement("div"),this.selection.className="designbase-wc-design-canvas__selection";for(const t of["nw","n","ne","e","se","s","sw","w","rotate"]){const e=document.createElement("div");e.dataset.handle=t,e.tabIndex=0,e.setAttribute("role","button"),e.setAttribute("aria-label","rotate"===t?"선택 요소 회전":`선택 요소 크기 조정 ${t}`),e.className="designbase-wc-design-canvas__handle",e.title="rotate"===t?"회전 · Shift: 15° 단위":"크기 조정 · Shift: 비율 유지",this.selection.append(e)}const t=document.createElement("span");t.className="designbase-wc-design-canvas__dimensions",this.selection.append(t),this.world.append(this.selection),this.contextBar=document.createElement("db-context-bar"),this.contextBar.classList.add("designbase-wc-design-canvas__context"),this.contextBar.setAttribute("size","s"),this.contextBar.setAttribute("tone","dark"),this.contextBar.setAttribute("placement","top-start"),this.contextBar.addEventListener("db-tool-action",this.toolAction),this.surface.append(this.world,this.contextBar),this.status=document.createElement("div"),this.status.className="designbase-wc-design-canvas__status",this.status.setAttribute("role","status"),this.status.setAttribute("aria-live","polite"),this.status.textContent="Space + 드래그 이동 · Ctrl/⌘ + 휠 확대 · 이미지 드롭",this.surface.addEventListener("pointerdown",this.onPointerDown),this.surface.addEventListener("pointermove",this.onPointerMove),this.surface.addEventListener("pointerup",this.onPointerUp),this.surface.addEventListener("pointercancel",this.onPointerCancel),this.surface.addEventListener("lostpointercapture",this.onLostCapture),this.surface.addEventListener("wheel",this.onWheel,{passive:!1}),this.surface.addEventListener("keydown",this.onKeyDown),this.surface.addEventListener("dblclick",this.beginTextEdit),this.surface.addEventListener("dragover",this.onDragOver),this.surface.addEventListener("dragleave",this.onDragLeave),this.surface.addEventListener("drop",this.onDrop),this.surface.addEventListener("dragstart",t=>t.preventDefault()),this.append(this.toolbar,this.surface,this.status,this.input)}collectSlots(){for(const t of Array.from(this.children))t instanceof HTMLElement&&t.hasAttribute("slot")&&this.slots.set(t.getAttribute("slot"),t)}draw(){if(this.world&&this.surface){if(this.style.height=this.getAttribute("height")||"560px",this.toolbar){const t="floating"===this.getAttribute("toolbar-mode");this.toolbar.toggleAttribute("movable",t),this.toolbar.classList.toggle("designbase-wc-design-canvas__toolbar--floating",t),t&&this.toolbar.parentElement!==this.surface&&this.surface.append(this.toolbar),t||this.toolbar.parentElement===this||this.insertBefore(this.toolbar,this.surface)}this.surface.classList.toggle("designbase-wc-design-canvas__surface--no-grid","false"===this.getAttribute("show-grid"));for(const[t,e]of this.objectElements)if(!this.data.some(e=>e.id===t)){const i=e.querySelector("[slot]");i instanceof HTMLElement&&this.slots.set(i.slot,i),e.remove(),this.objectElements.delete(t)}for(const t of this.data){let e=this.objectElements.get(t.id);if(e||(e=document.createElement("div"),e.className="designbase-wc-design-canvas__node",e.dataset.nodeId=t.id,e.tabIndex=-1,this.world.insertBefore(e,this.selection),this.objectElements.set(t.id,e)),e.style.zIndex=String(this.data.indexOf(t)),e.dataset.nodeType=t.type,e.setAttribute("aria-label",t.name),e.setAttribute("role","group"),Object.assign(e.style,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.width}px`,height:`${t.height}px`,transform:`rotate(${t.rotation||0}deg) scale(${t.flipX?-1:1}, ${t.flipY?-1:1})`,opacity:String(t.opacity??1),borderRadius:`${t.radius||0}px`,background:t.fill||"var(--db-surface-base)"}),"text"===t.type)this.drawText(e,t);else if("shape"===t.type)this.drawShape(e,t);else if("component"===t.type)this.drawComponent(e,t);else if("image"===t.type){let i=e.querySelector("img");i||(i=document.createElement("img"),i.draggable=!1,e.replaceChildren(i)),i.alt=t.name;const s=t.src||"",o=/^(data:image\/(png|jpe?g|webp|gif);base64,|blob:|https?:\/\/|\/[^/])/i.test(s);o&&i.getAttribute("src")!==s&&(i.src=s),o||i.removeAttribute("src")}else if(t.slot&&this.slots.has(t.slot)){const i=this.slots.get(t.slot);i.parentElement!==e&&e.replaceChildren(i)}else t.slot||e.textContent===t.name||(e.textContent=t.name)}this.drawViewport(),this.drawSelection()}}drawText(t,e){let i=t.querySelector(".designbase-wc-design-canvas__text");i||(i=document.createElement("div"),i.className="designbase-wc-design-canvas__text",t.replaceChildren(i)),t.style.background="transparent",t.style.overflow="visible",i.isContentEditable||i.textContent===e.text||(i.textContent=e.text||""),Object.assign(i.style,{fontSize:`${e.fontSize}px`,fontWeight:String(e.fontWeight),color:e.textColor,textAlign:e.textAlign})}drawShape(t,e){t.style.background="transparent";const i="http://www.w3.org/2000/svg",s=e.shape||"rectangle";if(t.dataset.shape!==s||!t.querySelector("svg")){t.dataset.shape=s;const e=document.createElementNS(i,"svg");e.setAttribute("viewBox","0 0 100 100"),e.setAttribute("preserveAspectRatio","none"),e.setAttribute("aria-hidden","true");const o=document.createElementNS(i,"ellipse"===s?"ellipse":"rectangle"===s?"rect":"line"===s?"line":"polygon");e.append(o),t.replaceChildren(e)}const o=t.querySelector("svg").firstElementChild;"rectangle"===s&&(o.setAttribute("x","1"),o.setAttribute("y","1"),o.setAttribute("width","98"),o.setAttribute("height","98"),o.setAttribute("rx",String((e.radius||0)/e.width*100)),o.setAttribute("ry",String((e.radius||0)/e.height*100))),"ellipse"===s&&(o.setAttribute("cx","50"),o.setAttribute("cy","50"),o.setAttribute("rx","49"),o.setAttribute("ry","49")),"triangle"===s&&o.setAttribute("points","50,1 99,99 1,99"),"line"===s&&(o.setAttribute("x1","0"),o.setAttribute("y1","50"),o.setAttribute("x2","100"),o.setAttribute("y2","50")),o.setAttribute("fill","line"===s?"none":e.fill||"#dce8f5"),o.setAttribute("stroke",e.stroke||"#191919"),o.setAttribute("stroke-width",String(e.strokeWidth??1)),o.setAttribute("vector-effect","non-scaling-stroke")}drawComponent(t,e){const i=e.component||"button";let s=t.querySelector(".designbase-wc-design-canvas__component");if(!s||s.dataset.kind!==i){s=document.createElement("div"),s.className="designbase-wc-design-canvas__component",s.inert=!0,s.dataset.kind=i;const e=document.createElement("input"===i?"db-input":"card"===i?"db-card":"badge"===i?"db-badge":"db-button");if("button"===i&&e.setAttribute("variant","primary"),"card"===i){const t=document.createElement("h3");t.dataset.componentText="";const i=document.createElement("p");i.textContent="내용을 선택하고 나만의 화면으로 구성하세요.",e.append(t,i)}s.append(e),t.replaceChildren(s)}const o=s.firstElementChild;if("input"===i){const t=o.querySelector("input");t&&Object.assign(t.style,{color:e.textColor,fontSize:`${e.fontSize}px`})}if("input"===i)o.setAttribute("placeholder",e.text||"내용을 입력하세요");else if("card"===i){const t=o.querySelector("[data-component-text]");t.textContent=e.text||"새 카드",t.style.fontSize=`${e.fontSize}px`}else o.textContent!==e.text&&(o.textContent=e.text||("badge"===i?"Badge":"Button"));Object.assign(o.style,{width:"100%",height:"100%",boxSizing:"border-box",borderRadius:`${e.radius||0}px`,color:e.textColor,fontSize:`${e.fontSize}px`,background:e.fill||"#ffffff"})}drawViewport(){if(!this.world||!this.surface)return;this.world.style.transform=`translate(${this.surface.clientWidth/2+this.view.x}px, ${this.surface.clientHeight/2+this.view.y}px) scale(${this.view.zoom})`,this.style.setProperty("--db-canvas-inverse-zoom",String(1/this.view.zoom));const t=Math.max(4,Number(this.getAttribute("grid-size"))||24)*this.view.zoom;this.surface.style.backgroundSize=`${t}px ${t}px`,this.surface.style.backgroundPosition=`${this.surface.clientWidth/2+this.view.x}px ${this.surface.clientHeight/2+this.view.y}px`,this.surface.classList.toggle("designbase-wc-design-canvas__surface--pan",this.space||this.hand||"pan"===this.gesture?.kind),this.syncToolbar(),this.positionContext()}drawSelection(){if(!this.selection)return;const t=this.data.find(t=>t.id===this.selected);if(this.selection.hidden=!t,this.syncContext(),this.positionContext(),t){Object.assign(this.selection.style,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.width}px`,height:`${t.height}px`,transform:`rotate(${t.rotation||0}deg)`}),this.selection.classList.toggle("designbase-wc-design-canvas__selection--locked",Boolean(t.locked||this.readOnly)),this.selection.querySelector(".designbase-wc-design-canvas__dimensions").textContent=`${Math.round(t.width)} × ${Math.round(t.height)} · ${Math.round(t.rotation||0)}°`;for(const e of Array.from(this.selection.querySelectorAll("[data-handle]")))e.tabIndex=t.locked||this.readOnly?-1:0,e.setAttribute("aria-disabled",String(!!t.locked||this.readOnly))}}syncToolbar(){if(!this.toolbar)return;const t=Math.round(100*this.view.zoom),e=[{id:"select",label:"선택 도구",icon:"navigation",shortcut:"V",active:!this.hand},{id:"pan",label:"화면 이동",icon:"move",shortcut:"H / Space",active:this.hand},{id:"creation-separator",type:"separator"},{id:"frame",label:"프레임 추가",icon:"file-new",disabled:this.readOnly||this.data.length>=100,menuTrigger:"long-press",value:this.creationTool,options:[{id:"frame",label:"빈 프레임 추가",icon:"file-new"},{id:"note",label:"메모 추가",icon:"documentation"}]},{id:"text",label:"텍스트 추가",icon:"text",shortcut:"T",disabled:this.readOnly||this.data.length>=100},{id:"shape",label:"도형 추가",icon:"shapes",value:this.shapeTool,disabled:this.readOnly||this.data.length>=100,options:[{id:"rectangle",label:"사각형",icon:"shape-rectangle",shortcut:"R"},{id:"ellipse",label:"타원",icon:"shape-ellipse",shortcut:"O"},{id:"triangle",label:"삼각형",icon:"shape-triangle"},{id:"line",label:"선",icon:"shape-line",shortcut:"L"}]},{id:"component",label:"컴포넌트 추가",icon:"package",value:this.componentTool,disabled:this.readOnly||this.data.length>=100,options:[{id:"button",label:"버튼",icon:"package"},{id:"input",label:"텍스트 입력",icon:"documentation"},{id:"card",label:"카드",icon:"file-new"},{id:"badge",label:"배지",icon:"package"}]},{id:"image",label:"이미지 추가",icon:"gallery",disabled:this.readOnly||this.data.length>=100},{id:"history-separator",type:"separator"},{id:"undo",label:"실행 취소",icon:"arrow-back-up",shortcut:"⌘/Ctrl+Z",disabled:!this.past.length||this.readOnly},{id:"redo",label:"다시 실행",icon:"arrow-back-up",shortcut:"⌘/Ctrl+Shift+Z",disabled:!this.future.length||this.readOnly},{id:"zoom-separator",type:"separator"},{id:"zoom-out",label:"축소",icon:"zoom-out",shortcut:"−"},{id:"zoom",label:"확대율",text:`${t}%`,value:String(t),options:[...[25,50,100,200,400].filter(t=>t/100>=this.minZoom&&t/100<=this.maxZoom).map(t=>({id:String(t),label:`${t}%`})),{id:"fit",label:"전체 보기",icon:"expand",shortcut:"0"}]},{id:"zoom-in",label:"확대",icon:"zoom-in",shortcut:"+"},{id:"fit",label:"전체 보기",icon:"expand",shortcut:"0"}];this.toolbar.items=e}syncContext(){if(!this.contextBar)return;const t=this.data.find(t=>t.id===this.selected);if(this.contextBar.hidden=!t,!t)return;const e=this.readOnly||!!t.locked;this.contextBar.items=[...t.slot?[]:[{id:"duplicate",label:"요소 복제",icon:"copy",disabled:e||this.data.length>=100}],{id:"lock",label:t.locked?"잠금 해제":"요소 잠그기",icon:t.locked?"unlock":"lock",active:t.locked,disabled:this.readOnly},{id:"transform-separator",type:"separator"},{id:"rotate",label:"회전",icon:"refresh",disabled:e,options:[{id:"reset",label:"회전 초기화"},{id:"left",label:"왼쪽으로 90° 회전"},{id:"right",label:"오른쪽으로 90° 회전"}]},{id:"flip-x",label:"좌우 반전",icon:"filp-horizontal",active:!!t.flipX,disabled:e},{id:"flip-y",label:"상하 반전",icon:"filp-vertical",active:!!t.flipY,disabled:e},{id:"alignment-separator",type:"separator"},...[["left","화면 왼쪽에 정렬","layout-align-left"],["center","가로 중앙 정렬","layout-align-center"],["right","화면 오른쪽에 정렬","layout-align-right"],["top","화면 위쪽에 정렬","layout-align-top"],["middle","세로 중앙 정렬","layout-align-middle"],["bottom","화면 아래쪽에 정렬","layout-align-bottom"]].map(([t,i,s])=>({id:`align-${t}`,label:i,icon:s,disabled:e})),{id:"layer-separator",type:"separator"},{id:"arrange",label:"레이어 순서",icon:"layer",disabled:e,options:[{id:"front",label:"맨 앞으로 가져오기"},{id:"back",label:"맨 뒤로 보내기"}]},{id:"delete",label:"요소 삭제",icon:"trash",shortcut:"Delete",disabled:e}]}insertNode(t,e){if(this.readOnly||this.data.length>=100)return;this.remember(this.data),"frame"===t&&(this.creationTool=e||this.creationTool),"shape"===t&&(this.shapeTool=e||this.shapeTool),"component"===t&&(this.componentTool=e||this.componentTool);const i="frame"===t&&"note"===this.creationTool;let s=320,o=240,n=i?"새로운 메모":"새 프레임",a="";if(i&&(s=220,o=180),"text"===t&&(s=280,o=100,n="텍스트",a="새로운 아이디어"),"shape"===t&&(s=200,o="line"===this.shapeTool?24:160,n={rectangle:"사각형",ellipse:"타원",triangle:"삼각형",line:"선"}[this.shapeTool]),"component"===t){const t={button:[160,44,"Button"],input:[240,44,"내용을 입력하세요"],card:[280,180,"새 카드"],badge:[100,32,"Badge"]};[s,o,a]=t[this.componentTool]||t.button,n=`${a} 컴포넌트`}const r=this.normalizeNode({id:crypto.randomUUID(),type:t,name:n,x:-this.view.x/this.view.zoom-s/2,y:-this.view.y/this.view.zoom-o/2,width:s,height:o,radius:"component"===t?10:i?12:0,fill:"shape"===t?"#dce8f5":"component"===t&&"button"===this.componentTool?"#191919":i?"#edf2e9":"#ffffff",text:a,fontSize:"component"===t?"card"===this.componentTool?22:14:24,textColor:"component"===t&&"button"===this.componentTool?"#ffffff":"#191919",shape:this.shapeTool,component:this.componentTool});this.data=[...this.data,r],this.select(r.id),this.emit("create")}positionContext(){const t=this.data.find(t=>t.id===this.selected);if(!t||!this.surface||!this.contextBar)return;const e=this.contextBar.offsetWidth||200,i=this.contextBar.offsetHeight||40,s=(t.rotation||0)*Math.PI/180,o=(Math.abs(t.width*Math.sin(s))+Math.abs(t.height*Math.cos(s)))/2*this.view.zoom,n=this.surface.clientWidth/2+this.view.x+(t.x+t.width/2)*this.view.zoom,a=this.surface.clientHeight/2+this.view.y+(t.y+t.height/2)*this.view.zoom,r=a-o-i-44,h=a+o+36,d=r>=12?r:h+i<=this.surface.clientHeight-12?h:12;this.contextBar.style.left=`${clamp(n,e/2+12,Math.max(e/2+12,this.surface.clientWidth-e/2-12))}px`,this.contextBar.style.top=`${clamp(d,12,Math.max(12,this.surface.clientHeight-i-12))}px`}select(t){t!==this.selected&&(this.selected=t,this.drawSelection(),this.dispatchEvent(new CustomEvent("db-selection-change",{detail:{selectedId:t,node:this.data.find(e=>e.id===t)||null},bubbles:!0,composed:!0})))}emit(t){this.draw(),this.dispatchEvent(new CustomEvent("db-nodes-change",{detail:{nodes:this.nodes,selectedId:this.selected,reason:t},bubbles:!0,composed:!0}))}emitViewport(){this.drawViewport(),this.dispatchEvent(new CustomEvent("db-viewport-change",{detail:this.viewport,bubbles:!0,composed:!0}))}remember(t){this.past.push(clone(t)),this.past.length>40&&this.past.shift(),this.future=[]}undo(){!this.readOnly&&this.past.length&&(this.cancelGesture(),this.future.push(this.nodes),this.data=this.past.pop(),this.select(this.data.some(t=>t.id===this.selected)?this.selected:this.data[0]?.id||null),this.emit("undo"))}redo(){!this.readOnly&&this.future.length&&(this.cancelGesture(),this.past.push(this.nodes),this.data=this.future.pop(),this.select(this.data.some(t=>t.id===this.selected)?this.selected:this.data[0]?.id||null),this.emit("redo"))}point(t){const e=this.surface.getBoundingClientRect();return{x:(t.clientX-e.left-this.surface.clientWidth/2-this.view.x)/this.view.zoom,y:(t.clientY-e.top-this.surface.clientHeight/2-this.view.y)/this.view.zoom}}zoomTo(t,e){if(!this.surface)return;const i=this.surface.getBoundingClientRect(),s=e||{x:i.left+i.width/2,y:i.top+i.height/2},o=this.point({clientX:s.x,clientY:s.y});this.view.zoom=clamp(t,this.minZoom,this.maxZoom),this.view.x=s.x-i.left-this.surface.clientWidth/2-o.x*this.view.zoom,this.view.y=s.y-i.top-this.surface.clientHeight/2-o.y*this.view.zoom,this.emitViewport(),this.drawSelection()}fitToContent(){if(!this.surface)return;if(!this.data.length)return this.viewport={x:0,y:0,zoom:1},void this.emitViewport();const t=this.data.flatMap(t=>{const e=(t.rotation||0)*Math.PI/180,i=t.x+t.width/2,s=t.y+t.height/2;return[[-1,-1],[1,-1],[1,1],[-1,1]].map(([o,n])=>({x:i+o*t.width/2*Math.cos(e)-n*t.height/2*Math.sin(e),y:s+o*t.width/2*Math.sin(e)+n*t.height/2*Math.cos(e)}))}),e=Math.min(...t.map(t=>t.x)),i=Math.max(...t.map(t=>t.x)),s=Math.min(...t.map(t=>t.y)),o=Math.max(...t.map(t=>t.y)),n=clamp(Math.min((this.surface.clientWidth-96)/Math.max(16,i-e),(this.surface.clientHeight-96)/Math.max(16,o-s)),this.minZoom,Math.min(1,this.maxZoom));this.view={zoom:n,x:-(e+i)/2*n,y:-(s+o)/2*n},this.emitViewport(),this.drawSelection()}editable(t){return t.composedPath().some(t=>t instanceof HTMLElement&&(t.isContentEditable||/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName)))}cancelGesture(){const t=this.gesture;this.gesture=void 0,t&&"pan"!==t.kind&&(this.data=t.before,this.isConnected&&this.emit("cancel")),t&&this.surface?.hasPointerCapture(t.pointer)&&this.surface.releasePointerCapture(t.pointer)}async importImages(t,e){if(this.readOnly)return;const i=e||{x:-this.view.x/this.view.zoom,y:-this.view.y/this.view.zoom},s=this.generation,o=[];let n=0;const a=Math.max(1,Number(this.getAttribute("max-file-size"))||10485760);for(const e of t.slice(0,12))if(!["image/png","image/jpeg","image/webp","image/gif"].includes(e.type)||e.size>a||this.data.length+o.length>=100)n++;else try{const t=await new Promise((t,i)=>{const s=new FileReader;this.reading.add(s),s.onload=()=>{this.reading.delete(s),t(String(s.result))},s.onerror=s.onabort=()=>{this.reading.delete(s),i(new Error("이미지를 읽지 못했습니다."))},s.readAsDataURL(e)}),n=await new Promise((e,i)=>{const s=new Image;s.onload=()=>e({width:s.naturalWidth,height:s.naturalHeight}),s.onerror=i,s.src=t});if(!this.isConnected||s!==this.generation)return;const a=Math.min(1,480/Math.max(n.width,n.height));o.push({id:crypto.randomUUID(),type:"image",name:e.name,src:t,x:i.x+24*o.length-n.width*a/2,y:i.y+24*o.length-n.height*a/2,width:Math.max(16,n.width*a),height:Math.max(16,n.height*a),rotation:0,opacity:1,radius:0})}catch{n++}this.isConnected&&s===this.generation&&(o.length&&(this.remember(this.data),this.data=[...this.data,...o.map(t=>this.normalizeNode(t))],this.select(o[o.length-1].id),this.emit("import")),this.status&&(this.status.textContent=`${o.length}개 이미지 추가${n||t.length>12?` · ${n+Math.max(0,t.length-12)}개 제외 (PNG/JPG/WebP/GIF, 파일당 ${Math.round(a/1024/1024)}MB 이하)`:""}`))}}customElements.get("db-design-canvas")||customElements.define("db-design-canvas",DbDesignCanvas);export{DbDesignCanvas};
@@ -0,0 +1,60 @@
1
+ import { DesignToolOption } from './db-tool-button.js';
2
+
3
+ interface DesignToolbarItem {
4
+ id: string;
5
+ type?: 'button' | 'separator';
6
+ label?: string;
7
+ icon?: string;
8
+ text?: string;
9
+ shortcut?: string;
10
+ active?: boolean;
11
+ disabled?: boolean;
12
+ options?: DesignToolOption[];
13
+ value?: string;
14
+ menuTrigger?: 'click' | 'long-press';
15
+ }
16
+ /** Icon toolbar. Arrow keys navigate actions; dropdowns and tooltips are portalled. */
17
+ declare class DbDesignToolbar extends HTMLElement {
18
+ static get observedAttributes(): string[];
19
+ private tools;
20
+ private focusId;
21
+ private connected;
22
+ private grip?;
23
+ private boundaryObserver?;
24
+ private dragState?;
25
+ private location;
26
+ get toolbarPosition(): {
27
+ x: number;
28
+ y: number;
29
+ } | string;
30
+ set toolbarPosition(value: {
31
+ x: number;
32
+ y: number;
33
+ } | string);
34
+ get items(): DesignToolbarItem[];
35
+ set items(value: DesignToolbarItem[] | string);
36
+ connectedCallback(): void;
37
+ disconnectedCallback(): void;
38
+ attributeChangedCallback(name: string): void;
39
+ private sync;
40
+ private buttons;
41
+ private rove;
42
+ private focusIn;
43
+ private keyDown;
44
+ private constrainPosition;
45
+ resetPosition(): void;
46
+ private dragStart;
47
+ private dragMove;
48
+ private dragEnd;
49
+ private dragCancel;
50
+ private gripKey;
51
+ closeMenus(): void;
52
+ }
53
+ declare global {
54
+ interface HTMLElementTagNameMap {
55
+ 'db-design-toolbar': DbDesignToolbar;
56
+ }
57
+ }
58
+
59
+ export { DbDesignToolbar };
60
+ export type { DesignToolbarItem };
@@ -0,0 +1 @@
1
+ import{DbToolButton as t}from"./db-tool-button.js";class DbDesignToolbar extends HTMLElement{constructor(){super(...arguments),this.tools=new Map,this.focusId="",this.connected=!1,this.location={x:12,y:12},this.focusIn=t=>{const e=t.target.closest("db-button");e&&(this.focusId=e.dataset.toolId||"",this.rove())},this.keyDown=t=>{if(!t.target.closest("db-tool-button"))return;const e="vertical"===this.getAttribute("orientation"),i=e?"ArrowDown":"ArrowRight";if(![e?"ArrowUp":"ArrowLeft",i,"Home","End"].includes(t.key))return;t.preventDefault();const o=this.buttons(),s=o.indexOf(document.activeElement),n="Home"===t.key?0:"End"===t.key?o.length-1:(s+(t.key===i?1:-1)+o.length)%o.length;o[n]?.focus()},this.dragStart=t=>{if(0!==t.button||!this.parentElement)return;t.preventDefault(),t.stopPropagation(),this.closeMenus();const e=this.parentElement.getBoundingClientRect();this.dragState={pointer:t.pointerId,clientX:t.clientX,clientY:t.clientY,...this.location,scaleX:e.width/Math.max(1,this.parentElement.offsetWidth),scaleY:e.height/Math.max(1,this.parentElement.offsetHeight)},this.grip?.querySelector("db-button")?.focus({preventScroll:!0}),this.setPointerCapture(t.pointerId),this.setAttribute("data-moving","")},this.dragMove=t=>{const e=this.dragState;e&&t.pointerId===e.pointer&&(t.preventDefault(),t.stopPropagation(),this.location={x:e.x+(t.clientX-e.clientX)/e.scaleX,y:e.y+(t.clientY-e.clientY)/e.scaleY},this.constrainPosition(!0))},this.dragEnd=t=>{this.dragState?.pointer===t.pointerId&&(this.dragState=void 0,this.removeAttribute("data-moving"),this.hasPointerCapture(t.pointerId)&&this.releasePointerCapture(t.pointerId),this.constrainPosition(!0))},this.dragCancel=t=>{this.dragState?.pointer===t.pointerId&&this.dragEnd(t)},this.gripKey=t=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home"].includes(t.key))return;if(t.preventDefault(),t.stopPropagation(),"Home"===t.key)return void this.resetPosition();const e=t.shiftKey?20:4;this.location.x+="ArrowRight"===t.key?e:"ArrowLeft"===t.key?-e:0,this.location.y+="ArrowDown"===t.key?e:"ArrowUp"===t.key?-e:0,this.constrainPosition(!0)}}static get observedAttributes(){return["items","size","tone","orientation","placement","movable","toolbar-position"]}get toolbarPosition(){return{...this.location}}set toolbarPosition(t){try{const e="string"==typeof t?JSON.parse(t):t;this.location={x:Number.isFinite(e.x)?e.x:12,y:Number.isFinite(e.y)?e.y:12},this.constrainPosition()}catch{}}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id):[]}catch{return[]}}set items(t){const e="string"==typeof t?t:JSON.stringify(t);e!==this.getAttribute("items")&&this.setAttribute("items",e)}connectedCallback(){this.connected=!0,this.classList.add("designbase-wc-design-toolbar"),this.setAttribute("role","toolbar"),this.hasAttribute("aria-label")||this.setAttribute("aria-label","디자인 도구"),this.addEventListener("keydown",this.keyDown),this.addEventListener("focusin",this.focusIn),this.sync(),this.addEventListener("pointermove",this.dragMove),this.addEventListener("pointerup",this.dragEnd),this.addEventListener("pointercancel",this.dragCancel),this.addEventListener("lostpointercapture",this.dragCancel),this.boundaryObserver=new ResizeObserver(()=>this.constrainPosition()),this.parentElement&&this.boundaryObserver.observe(this.parentElement),this.boundaryObserver.observe(this),this.constrainPosition()}disconnectedCallback(){this.connected=!1,this.dragState=void 0,this.boundaryObserver?.disconnect(),this.removeEventListener("pointermove",this.dragMove),this.removeEventListener("pointerup",this.dragEnd),this.removeEventListener("pointercancel",this.dragCancel),this.removeEventListener("lostpointercapture",this.dragCancel),this.removeEventListener("keydown",this.keyDown),this.removeEventListener("focusin",this.focusIn)}attributeChangedCallback(t){"toolbar-position"===t&&(this.toolbarPosition=this.getAttribute("toolbar-position")||"{}"),this.connected&&this.sync()}sync(){const t=this.items,e=new Set,set=(t,e,i)=>{t.getAttribute(e)!==i&&t.setAttribute(e,i)},i=[];this.hasAttribute("movable")?(this.grip||(this.grip=document.createElement("db-tool-button"),this.grip.setAttribute("tool-id","move-toolbar"),this.grip.setAttribute("label","툴바 이동"),this.grip.setAttribute("shortcut","드래그 / 방향키"),this.grip.setAttribute("icon","grip-vertical"),this.grip.setAttribute("data-toolbar-grip",""),this.grip.addEventListener("db-tool-action",t=>t.stopPropagation()),this.grip.addEventListener("pointerdown",this.dragStart),this.grip.addEventListener("keydown",this.gripKey)),set(this.grip,"tone",this.getAttribute("tone")||"default"),set(this.grip,"size",this.getAttribute("size")||"m"),i.push(this.grip)):this.grip?.remove();for(const o of t){if(e.has(o.id))continue;e.add(o.id);let t=this.tools.get(o.id);const s="separator"===o.type;t&&"DB-TOOL-BUTTON"===t.tagName===s&&(t.remove(),this.tools.delete(o.id),t=void 0),t||(t=s?document.createElement("span"):document.createElement("db-tool-button"),this.tools.set(o.id,t)),s?(t.setAttribute("role","separator"),t.className="designbase-wc-design-toolbar__separator"):(set(t,"tool-id",o.id),set(t,"label",o.label||o.id),set(t,"icon",o.icon||""),void 0!==o.text?set(t,"text",o.text):t.removeAttribute("text"),set(t,"shortcut",o.shortcut||""),set(t,"options",JSON.stringify(o.options||[])),set(t,"value",o.value||""),set(t,"menu-trigger",o.menuTrigger||"click"),set(t,"size",this.getAttribute("size")||"m"),set(t,"tone",this.getAttribute("tone")||"default"),set(t,"placement",this.getAttribute("placement")||"bottom-start"),t.toggleAttribute("toggle","boolean"==typeof o.active),t.toggleAttribute("active",!!o.active),t.toggleAttribute("disabled",!!o.disabled)),i.push(t)}for(const[t,i]of this.tools)e.has(t)||(i.remove(),this.tools.delete(t));i.forEach((t,e)=>{this.children[e]!==t&&this.insertBefore(t,this.children[e]||null)}),this.setAttribute("aria-orientation","vertical"===this.getAttribute("orientation")?"vertical":"horizontal"),this.rove(),this.constrainPosition()}buttons(){return Array.from(this.querySelectorAll(":scope > db-tool-button:not([disabled]) db-button"))}rove(){const t=this.buttons(),e=t.find(t=>t.dataset.toolId===this.focusId)||t[0];t.forEach(t=>t.tabIndex=t===e?0:-1)}constrainPosition(t=!1){if(!this.hasAttribute("movable")||!this.parentElement)return;const e=Math.max(0,this.parentElement.clientWidth-this.offsetWidth),i=Math.max(0,this.parentElement.clientHeight-this.offsetHeight),o=Math.min(8,e/2),s=Math.min(8,i/2);this.location={x:Math.max(o,Math.min(e-o,this.location.x)),y:Math.max(s,Math.min(i-s,this.location.y))},this.style.left=`${this.location.x}px`,this.style.top=`${this.location.y}px`,t&&this.dispatchEvent(new CustomEvent("db-position-change",{detail:this.toolbarPosition,bubbles:!0,composed:!0}))}resetPosition(){this.location={x:12,y:12},this.constrainPosition(!0)}closeMenus(){for(const e of this.tools.values())e instanceof t&&e.closeMenu(!1)}}customElements.get("db-design-toolbar")||customElements.define("db-design-toolbar",DbDesignToolbar);export{DbDesignToolbar};
@@ -0,0 +1,100 @@
1
+ import { DbElement } from '../core/base-element.js';
2
+
3
+ /** Native display pixels (width × height). Geometry references are documented in db-device-mockup.md. */
4
+ declare const DEVICE_MOCKUP_SCREENS: {
5
+ readonly default: readonly [1600, 1000];
6
+ readonly tablet: readonly [3, 4];
7
+ readonly ios: readonly [1206, 2622];
8
+ readonly android: readonly [1080, 2340];
9
+ readonly watch: readonly [416, 496];
10
+ readonly flip: readonly [1080, 2520];
11
+ readonly 'flip-cover': readonly [948, 1048];
12
+ readonly fold: readonly [1968, 2184];
13
+ readonly 'fold-cover': readonly [1080, 2520];
14
+ readonly duo: readonly [14, 10];
15
+ readonly 'duo-cover': readonly [7, 10];
16
+ };
17
+ type DeviceModel = 'default' | 'ios' | 'android' | 'watch' | 'flip' | 'fold' | 'duo';
18
+ /** Physical frames preserve live child content through a slot; src displays a screenshot. */
19
+ declare abstract class DbDeviceMockup extends DbElement {
20
+ protected abstract readonly device: 'browser' | 'tablet' | 'mobile' | 'watch';
21
+ protected readonly model: DeviceModel;
22
+ static get observedAttributes(): string[];
23
+ private readonly root;
24
+ connectedCallback(): void;
25
+ attributeChangedCallback(): void;
26
+ private node;
27
+ private decorative;
28
+ private tools;
29
+ private watchBand;
30
+ private browserChrome;
31
+ private render;
32
+ }
33
+ declare class DbBrowserMockup extends DbDeviceMockup {
34
+ protected readonly device: "browser";
35
+ }
36
+ declare class DbTabletMockup extends DbDeviceMockup {
37
+ protected readonly device: "tablet";
38
+ }
39
+ /** Compatibility alias for the iOS frame. */
40
+ declare class DbMobileMockup extends DbDeviceMockup {
41
+ protected readonly device: "mobile";
42
+ protected readonly model: DeviceModel;
43
+ }
44
+ declare class DbIosMockup extends DbMobileMockup {
45
+ }
46
+ declare class DbAndroidMockup extends DbMobileMockup {
47
+ protected readonly model: DeviceModel;
48
+ }
49
+ declare class DbAppleWatchMockup extends DbDeviceMockup {
50
+ protected readonly device: "watch";
51
+ protected readonly model: DeviceModel;
52
+ }
53
+ declare class DbFlipMockup extends DbMobileMockup {
54
+ protected readonly model: DeviceModel;
55
+ }
56
+ declare class DbFoldMockup extends DbMobileMockup {
57
+ protected readonly model: DeviceModel;
58
+ }
59
+ declare class DbDuoMockup extends DbMobileMockup {
60
+ protected readonly model: DeviceModel;
61
+ }
62
+ declare global {
63
+ interface HTMLElementTagNameMap {
64
+ 'db-browser-mockup': DbBrowserMockup;
65
+ 'db-tablet-mockup': DbTabletMockup;
66
+ 'db-mobile-mockup': DbMobileMockup;
67
+ }
68
+ }
69
+ declare global {
70
+ interface HTMLElementTagNameMap {
71
+ 'db-ios-mockup': DbIosMockup;
72
+ }
73
+ }
74
+ declare global {
75
+ interface HTMLElementTagNameMap {
76
+ 'db-android-mockup': DbAndroidMockup;
77
+ }
78
+ }
79
+ declare global {
80
+ interface HTMLElementTagNameMap {
81
+ 'db-apple-watch-mockup': DbAppleWatchMockup;
82
+ }
83
+ }
84
+ declare global {
85
+ interface HTMLElementTagNameMap {
86
+ 'db-flip-mockup': DbFlipMockup;
87
+ }
88
+ }
89
+ declare global {
90
+ interface HTMLElementTagNameMap {
91
+ 'db-fold-mockup': DbFoldMockup;
92
+ }
93
+ }
94
+ declare global {
95
+ interface HTMLElementTagNameMap {
96
+ 'db-duo-mockup': DbDuoMockup;
97
+ }
98
+ }
99
+
100
+ export { DEVICE_MOCKUP_SCREENS, DbAndroidMockup, DbAppleWatchMockup, DbBrowserMockup, DbDuoMockup, DbFlipMockup, DbFoldMockup, DbIosMockup, DbMobileMockup, DbTabletMockup };
@@ -0,0 +1 @@
1
+ import{DbElement as e}from"../core/base-element.js";import{createDbIcon as t}from"./db-icons.js";import{deviceMockupStyle as o}from"./device-mockup-style.js";import{MOCKUP_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c={default:[1600,1e3],tablet:[3,4],ios:[1206,2622],android:[1080,2340],watch:[416,496],flip:[1080,2520],"flip-cover":[948,1048],fold:[1968,2184],"fold-cover":[1080,2520],duo:[14,10],"duo-cover":[7,10]};class DbDeviceMockup extends e{constructor(){super(...arguments),this.model="default",this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return["src","alt","url","orientation","variant","screen-title","notch","fold-state","cover-src"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}node(e,t,o){const s=document.createElement(e);return s.className=t,void 0!==o&&(s.textContent=o),s}decorative(e){const t=this.node("span",e);return t.setAttribute("aria-hidden","true"),t}tools(e,o){const s=this.decorative(`tools ${o}`);return e.forEach(e=>s.append(t(e,14))),s}watchBand(e){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("class",`watch-band watch-band--${e}`),t.setAttribute("viewBox","0 0 160 100"),t.setAttribute("preserveAspectRatio","none"),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),t.innerHTML=`<defs>\n <linearGradient id="band-${e}" x1="0" y1="0" x2="1" y2="0">\n <stop offset="0" stop-color="#232426"/><stop offset=".12" stop-color="#3c3d40"/>\n <stop offset=".38" stop-color="#343538"/><stop offset=".72" stop-color="#323336"/>\n <stop offset=".91" stop-color="#3b3c3f"/><stop offset="1" stop-color="#242527"/>\n </linearGradient>\n <linearGradient id="band-shade-${e}" x1="0" y1="0" x2="0" y2="1">\n <stop stop-color="#fff" stop-opacity=".04"/><stop offset=".5" stop-color="#fff" stop-opacity="0"/>\n <stop offset="1" stop-color="#000" stop-opacity=".22"/>\n </linearGradient>\n </defs>\n <path d="M28 13 C35 3 125 3 132 13 C139 25 133 57 149 81 L160 100 H0 L11 81 C27 57 21 25 28 13Z" fill="url(#band-${e})"/>\n <path d="M28 13 C35 3 125 3 132 13 C139 25 133 57 149 81 L160 100 H0 L11 81 C27 57 21 25 28 13Z" fill="url(#band-shade-${e})"/>`,t}browserChrome(){const e=this.node("div","chrome"),o=this.node("div","tab-strip"),s=this.decorative("dots");for(let e=0;e<3;e++)s.append(document.createElement("i"));const c=this.node("div","tab");c.setAttribute("aria-hidden","true"),c.append(document.createElement("b"),this.node("span","",this.getAttribute("screen-title")||"Preview"),t("close",11)),o.append(s,c);const i=this.node("div","toolbar"),d=this.node("div","url");return d.append(t("lock",11),this.node("span","",this.getAttribute("url")||"example.com")),i.append(this.tools(["chevron-left","chevron-right","refresh"],"tools--left"),d,this.tools(["share-alt","plus","copy"],"tools--right")),e.append(o,i),e}render(){const e=document.createElement("style");e.textContent=o,this.dataset.device=this.device,this.dataset.model=this.model;const t="flip"===this.model||"fold"===this.model||"duo"===this.model,i=t&&"closed"===this.getAttribute("fold-state");this.dataset.foldState=i?"closed":"open",this.dataset.variant=s.find(e=>e===this.getAttribute("variant"))||"realistic";const d=this.getAttribute("notch"),n="ios"===this.model?"island":["android","flip","fold","duo"].includes(this.model)?"punch":"none";this.dataset.notch="watch"===this.device||"browser"===this.device||i&&"flip"===this.model?"none":"none"===d||"island"===d||"punch"===d?d:n;const r=this.node("div","frame");r.part.add("frame"),"browser"===this.device&&r.append(this.browserChrome());const a=this.node("div","screen");a.part.add("screen");const p="tablet"===this.device?"tablet":i?`${this.model}-cover`:this.model,[l,u]=c[p]||c.default,h="landscape"===this.getAttribute("orientation")&&"watch"!==this.device;a.style.aspectRatio=`var(--db-mockup-ratio, ${h?u:l} / ${h?l:u})`;const b=this.node("div","content");b.part.add("content");const m=i&&this.getAttribute("cover-src")||this.getAttribute("src");if(m){const e=document.createElement("img");e.src=m,e.alt=this.getAttribute("alt")||"",e.loading="lazy",b.append(e)}else{const e=document.createElement("slot");i&&this.querySelector('[slot="cover"]')&&(e.name="cover"),b.append(e)}a.append(b),r.append(a),"browser"!==this.device&&("none"!==this.dataset.notch&&r.append(this.decorative("camera")),t&&!i&&a.append(this.decorative("crease")),"flip"===this.model&&i&&a.append(this.decorative("cover-cameras")),"watch"===this.device&&(r.append(this.watchBand("top"),this.watchBand("bottom"),this.decorative("crown")),a.append(this.decorative("watch-glass"))),"duo"===this.model&&r.append(this.decorative("hinge")),r.append(this.decorative("side side--power"),this.decorative("side side--volume"),this.decorative("side side--action"))),this.root.replaceChildren(e,r)}}class DbBrowserMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="browser"}}class DbTabletMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="tablet"}}class DbMobileMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="mobile",this.model="ios"}}class DbIosMockup extends DbMobileMockup{}class DbAndroidMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="android"}}class DbAppleWatchMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="watch",this.model="watch"}}class DbFlipMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="flip"}}class DbFoldMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="fold"}}class DbDuoMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="duo"}}customElements.get("db-browser-mockup")||customElements.define("db-browser-mockup",DbBrowserMockup),customElements.get("db-tablet-mockup")||customElements.define("db-tablet-mockup",DbTabletMockup),customElements.get("db-mobile-mockup")||customElements.define("db-mobile-mockup",DbMobileMockup),customElements.get("db-ios-mockup")||customElements.define("db-ios-mockup",DbIosMockup),customElements.get("db-android-mockup")||customElements.define("db-android-mockup",DbAndroidMockup),customElements.get("db-apple-watch-mockup")||customElements.define("db-apple-watch-mockup",DbAppleWatchMockup),customElements.get("db-flip-mockup")||customElements.define("db-flip-mockup",DbFlipMockup),customElements.get("db-fold-mockup")||customElements.define("db-fold-mockup",DbFoldMockup),customElements.get("db-duo-mockup")||customElements.define("db-duo-mockup",DbDuoMockup);export{c as DEVICE_MOCKUP_SCREENS,DbAndroidMockup,DbAppleWatchMockup,DbBrowserMockup,DbDuoMockup,DbFlipMockup,DbFoldMockup,DbIosMockup,DbMobileMockup,DbTabletMockup};
@@ -1,6 +1,6 @@
1
1
  import './db-progressbar.js';
2
2
  import './db-button.js';
3
- import { DOWNLOAD_PROGRESS_STATUSES, DOWNLOAD_PROGRESS_POSITIONS } from '@designbasekorea/ui-contracts';
3
+ import { DOWNLOAD_PROGRESS_STATUSES, DOWNLOAD_PROGRESS_POSITIONS } from '../ui-contracts/dist/components.d.js';
4
4
 
5
5
  type DownloadStatus = (typeof DOWNLOAD_PROGRESS_STATUSES)[number];
6
6
  type DownloadPosition = (typeof DOWNLOAD_PROGRESS_POSITIONS)[number];
@@ -1 +1 @@
1
- import{createFocusTrap as t}from"../core/focus-trap.js";import{unlockScroll as e,lockScroll as s}from"../core/scroll-lock.js";import{DRAWER_POSITIONS as i,DRAWER_SIZES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDrawer extends HTMLElement{constructor(){super(...arguments),this.isMounted=!1,this.isActive=!1,this.scrollLocked=!1,this.keyHandler=null}static get observedAttributes(){return["open","title","position","size","show-close-button","close-on-backdrop-click","close-on-escape","animation-duration","show-overlay","overlay-closable","z-index","trap-focus","drawer-id"]}connectedCallback(){this.style.display="contents",this.render(),this.syncOpenState()}disconnectedCallback(){this.clearTimers(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.root=void 0,this.releaseScrollLock()}releaseScrollLock(){this.scrollLocked&&(this.scrollLocked=!1,e())}attributeChangedCallback(t){this.isConnected&&("open"!==t?(this.render(),this.isMounted&&this.syncActiveClasses()):this.syncOpenState())}isOpenRequested(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}clearTimers(){null!=this.enterFrame&&(cancelAnimationFrame(this.enterFrame),this.enterFrame=void 0),this.exitTimer&&(clearTimeout(this.exitTimer),this.exitTimer=void 0)}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"false"!==this.getAttribute("close-on-escape")&&this.close()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}close(){this.setAttribute("open","false"),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}collectChildren(){return Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal"))}syncOpenState(){const e=this.isOpenRequested(),i=Number(this.getAttribute("animation-duration")||300);if(this.clearTimers(),e)return this.render(),this.isMounted=!0,this.isActive=!1,this.syncActiveClasses(),this.root&&!this.root.isConnected&&document.body.append(this.root),this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=void 0,this.isActive=!0,this.syncActiveClasses(),"false"!==this.getAttribute("trap-focus")&&this.container&&(this.focusTrap=t(this.container),this.focusTrap.activate())})}),this.scrollLocked||(s(),this.scrollLocked=!0),void this.attachEscape();this.isActive=!1,this.syncActiveClasses(),this.exitTimer=setTimeout(()=>{this.exitTimer=void 0,this.isMounted=!1,this.syncActiveClasses(),this.root?.remove(),this.releaseScrollLock(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0},i),this.detachEscape()}syncActiveClasses(){this.root&&(this.root.classList.toggle("designbase-wc-drawer--open",this.isActive),this.root.classList.toggle("designbase-wc-drawer--closing",this.isMounted&&!this.isActive),this.overlay?.classList.toggle("designbase-wc-drawer__overlay--open",this.isActive),this.container?.classList.toggle("designbase-wc-drawer__container--open",this.isActive))}render(){const t=i.includes(this.getAttribute("position")||"right")&&this.getAttribute("position")||"right",e=r.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",s=this.getAttribute("title"),o="false"!==this.getAttribute("show-close-button"),a="false"!==this.getAttribute("show-overlay"),n=this.getAttribute("animation-duration")||"300",c=this.getAttribute("z-index")||"1000",l=this.getAttribute("drawer-id")||"drawer",d=this.collectChildren();this.root||(this.root=document.createElement("div"),this.root.setAttribute("data-wc-internal",""),this.overlay=document.createElement("div"),this.overlay.className="designbase-wc-drawer__overlay",this.overlay.setAttribute("aria-hidden","true"),this.overlay.addEventListener("click",t=>{if(t.target!==this.overlay)return;const e="false"!==this.getAttribute("overlay-closable"),s="false"!==this.getAttribute("close-on-backdrop-click");e&&s&&this.close()}),this.container=document.createElement("div"),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${t}`,this.container.setAttribute("role","dialog"),this.container.setAttribute("aria-modal","true"),this.container.tabIndex=-1,this.container.addEventListener("click",t=>t.stopPropagation()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-drawer__content",this.container.append(this.contentEl)),this.root.className=["designbase-wc-drawer",`designbase-wc-drawer--${t}`,`designbase-wc-drawer--${e}`].join(" "),this.root.style.setProperty("--drawer-animation-duration",`${n}ms`),this.root.style.setProperty("--drawer-z-index",c),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${t}`,this.container.id=l,s?this.container.setAttribute("aria-labelledby",`${l}-title`):this.container.removeAttribute("aria-labelledby"),this.contentEl.id=`${l}-content`,this.root.replaceChildren(),a&&this.overlay&&this.root.append(this.overlay);if(Boolean(s)||o){const t=document.createElement("div");if(t.className="designbase-wc-drawer__header",s){const e=document.createElement("h2");e.className="designbase-wc-drawer__title",e.id=`${l}-title`,e.textContent=s,t.append(e)}if(o){const e=document.createElement("db-button");e.className="designbase-wc-drawer__close-button",e.setAttribute("variant","ghost"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon","close"),e.setAttribute("aria-label","닫기"),e.addEventListener("db-click",t=>{t.stopPropagation(),this.close()}),t.append(e)}this.container.replaceChildren(t,this.contentEl)}else this.container.replaceChildren(this.contentEl);this.contentEl.replaceChildren(...d),this.root.append(this.container),this.isMounted&&!this.root.isConnected&&document.body.append(this.root)}}customElements.get("db-drawer")||customElements.define("db-drawer",DbDrawer);export{DbDrawer};
1
+ import{createFocusTrap as t}from"../core/focus-trap.js";import{unlockScroll as e,lockScroll as s}from"../core/scroll-lock.js";import{DRAWER_POSITIONS as i,DRAWER_SIZES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDrawer extends HTMLElement{constructor(){super(...arguments),this.isMounted=!1,this.isActive=!1,this.scrollLocked=!1,this.keyHandler=null}static get observedAttributes(){return["open","title","position","size","show-close-button","close-on-backdrop-click","close-on-escape","animation-duration","show-overlay","overlay-closable","z-index","trap-focus","drawer-id"]}connectedCallback(){this.style.display="contents",this.render(),this.syncOpenState()}disconnectedCallback(){this.clearTimers(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.root=void 0,this.releaseScrollLock()}releaseScrollLock(){this.scrollLocked&&(this.scrollLocked=!1,e())}attributeChangedCallback(t){this.isConnected&&("open"!==t?(this.render(),this.isMounted&&this.syncActiveClasses()):this.syncOpenState())}isOpenRequested(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}clearTimers(){null!=this.enterFrame&&(cancelAnimationFrame(this.enterFrame),this.enterFrame=void 0),this.exitTimer&&(clearTimeout(this.exitTimer),this.exitTimer=void 0)}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"false"!==this.getAttribute("close-on-escape")&&this.close()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}close(){this.setAttribute("open","false"),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}collectChildren(){return[...new Set([...Array.from(this.contentEl?.children||[]),...Array.from(this.children)])].filter(t=>!t.hasAttribute("data-wc-internal"))}syncOpenState(){const e=this.isOpenRequested(),i=Number(this.getAttribute("animation-duration")||300);if(this.clearTimers(),e)return this.render(),this.isMounted=!0,this.isActive=!1,this.syncActiveClasses(),this.root&&!this.root.isConnected&&document.body.append(this.root),this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=void 0,this.isActive=!0,this.syncActiveClasses(),"false"!==this.getAttribute("trap-focus")&&this.container&&(this.focusTrap=t(this.container),this.focusTrap.activate())})}),this.scrollLocked||(s(),this.scrollLocked=!0),void this.attachEscape();this.isActive=!1,this.syncActiveClasses(),this.exitTimer=setTimeout(()=>{this.exitTimer=void 0,this.isMounted=!1,this.syncActiveClasses(),this.root?.remove(),this.releaseScrollLock(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0},i),this.detachEscape()}syncActiveClasses(){this.root&&(this.root.classList.toggle("designbase-wc-drawer--open",this.isActive),this.root.classList.toggle("designbase-wc-drawer--closing",this.isMounted&&!this.isActive),this.overlay?.classList.toggle("designbase-wc-drawer__overlay--open",this.isActive),this.container?.classList.toggle("designbase-wc-drawer__container--open",this.isActive))}render(){const t=i.includes(this.getAttribute("position")||"right")&&this.getAttribute("position")||"right",e=r.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",s=this.getAttribute("title"),o="false"!==this.getAttribute("show-close-button"),n="false"!==this.getAttribute("show-overlay"),a=this.getAttribute("animation-duration")||"300",c=this.getAttribute("z-index")||"1000",l=this.getAttribute("drawer-id")||"drawer",h=this.collectChildren();this.root||(this.root=document.createElement("div"),this.root.setAttribute("data-wc-internal",""),this.overlay=document.createElement("div"),this.overlay.className="designbase-wc-drawer__overlay",this.overlay.setAttribute("aria-hidden","true"),this.overlay.addEventListener("click",t=>{if(t.target!==this.overlay)return;const e="false"!==this.getAttribute("overlay-closable"),s="false"!==this.getAttribute("close-on-backdrop-click");e&&s&&this.close()}),this.container=document.createElement("div"),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${t}`,this.container.setAttribute("role","dialog"),this.container.setAttribute("aria-modal","true"),this.container.tabIndex=-1,this.container.addEventListener("click",t=>t.stopPropagation()),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-drawer__content",this.container.append(this.contentEl)),this.root.className=["designbase-wc-drawer",`designbase-wc-drawer--${t}`,`designbase-wc-drawer--${e}`].join(" "),this.root.style.setProperty("--drawer-animation-duration",`${a}ms`),this.root.style.setProperty("--drawer-z-index",c),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${t}`,this.container.id=l,s?this.container.setAttribute("aria-labelledby",`${l}-title`):this.container.removeAttribute("aria-labelledby"),this.contentEl.id=`${l}-content`,n&&this.overlay?this.overlay.parentElement!==this.root&&this.root.prepend(this.overlay):this.overlay?.remove(),this.container.querySelector(":scope > .designbase-wc-drawer__header")?.remove();if(Boolean(s)||o){const t=document.createElement("div");if(t.className="designbase-wc-drawer__header",s){const e=document.createElement("h2");e.className="designbase-wc-drawer__title",e.id=`${l}-title`,e.textContent=s,t.append(e)}if(o){const e=document.createElement("db-button");e.className="designbase-wc-drawer__close-button",e.setAttribute("variant","ghost"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon","close"),e.setAttribute("aria-label","닫기"),e.addEventListener("db-click",t=>{t.stopPropagation(),this.close()}),t.append(e)}this.container.insertBefore(t,this.contentEl)}const d=Array.from(this.contentEl.children);(d.length!==h.length||d.some((t,e)=>t!==h[e]))&&this.contentEl.replaceChildren(...h),this.container.parentElement!==this.root&&this.root.append(this.container),this.isMounted&&!this.root.isConnected&&document.body.append(this.root)}}customElements.get("db-drawer")||customElements.define("db-drawer",DbDrawer);export{DbDrawer};
@@ -13,6 +13,8 @@ declare class DbDropdown extends HTMLElement {
13
13
  private focusedIndex;
14
14
  private onTriggerActivate;
15
15
  private lastTriggerSignature;
16
+ get showChevron(): boolean;
17
+ set showChevron(value: boolean);
16
18
  get parsedItems(): DbDropdownItem[];
17
19
  get options(): string[] | string;
18
20
  set options(value: string[] | string);
@@ -1 +1 @@
1
- import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";import{DROPDOWN_SIZES as i,DROPDOWN_PLACEMENTS as r,DROPDOWN_TRIGGER_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(("Enter"===e.key||" "===e.key||"ArrowDown"===e.key)&&!this.open)return e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render();"Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,this.render())},this.handleDocumentKeyDown=e=>{if(!this.open)return;if("Escape"===e.key)return e.preventDefault(),this.open=!1,this.render(),void this.triggerWrap?.querySelector("[aria-haspopup]")?.focus();const t=this.enabledItems();if(!t.length)return;const i=t.findIndex(e=>this.parsedItems.indexOf(e)===this.focusedIndex);switch(e.key){case"ArrowDown":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i+1)%t.length]));break;case"ArrowUp":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i-1+t.length)%t.length]));break;case"Home":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[0]));break;case"End":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[t.length-1]));break;case"Enter":case" ":{e.preventDefault();const t=this.parsedItems[this.focusedIndex];!t||t.divider||t.disabled||this.selectItem(t);break}}},this.handleDocumentMouseDown=e=>{this.open&&(this.contains(e.target)||(this.open=!1,this.render()))}}static get observedAttributes(){return["options","items","placeholder","label","value","size","placement","full-width","disabled","open","trigger-variant","trigger-icon","icon-only"]}get parsedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return(this.getAttribute("options")||"").split(",").map(e=>e.trim()).filter(Boolean).map((e,t)=>({id:`option-${t}`,label:e}))}get options(){return this.parsedItems.map(e=>e.label||e.id)}set options(e){this.setAttribute("options",Array.isArray(e)?e.join(","):e)}get items(){return this.parsedItems}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value")}get open(){return this.hasAttribute("open")}set open(e){const t=this.open;this.toggleAttribute("open",e),t!==e&&this.dispatchEvent(new CustomEvent("db-open",{detail:{open:e},bubbles:!0,composed:!0}))}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get placement(){return this.getAttribute("placement")||"bottom-left"}set placement(e){this.setAttribute("placement",e)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(e){e?this.setAttribute("placeholder",e):this.removeAttribute("placeholder")}get label(){return this.getAttribute("label")||""}set label(e){e?this.setAttribute("label",e):this.removeAttribute("label")}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(e){this.toggleAttribute("full-width",e)}connectedCallback(){requestAnimationFrame(()=>this.render()),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.unbindTrigger()}attributeChangedCallback(e){this.isConnected&&("open"!==e||this.open||(this.focusedIndex=-1),this.render())}resolvedSize(){return i.includes(this.size)?this.size:"m"}resolvedPlacement(){return r.includes(this.placement)?this.placement:"bottom-left"}menuItemIconSize(){const e=this.resolvedSize();return"s"===e?14:"l"===e?18:16}triggerLabel(){return this.label?this.label:this.placeholder?this.placeholder:this.value?this.value:"메뉴"}enabledItems(){return this.parsedItems.filter(e=>!e.disabled&&!e.divider)}collectTriggerChildren(){const isInternalNode=e=>e.hasAttribute("data-wc-internal")||e===this.triggerWrap||e===this.menu||e===this.defaultTrigger,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>!isInternalNode(e))}hasCustomTrigger(){return this.collectTriggerChildren().length>0}bindTrigger(){this.triggerWrap&&(this.unbindTrigger(),this.onTriggerActivate=e=>{this.disabled||(e.preventDefault(),e.stopPropagation(),this.toggleOpen())},this.triggerWrap.addEventListener("click",this.onTriggerActivate),this.triggerWrap.addEventListener("keydown",this.handleTriggerKeyDown))}unbindTrigger(){this.triggerWrap&&this.onTriggerActivate&&this.triggerWrap.removeEventListener("click",this.onTriggerActivate),this.triggerWrap&&this.triggerWrap.removeEventListener("keydown",this.handleTriggerKeyDown),this.onTriggerActivate=null}toggleOpen(){this.disabled||(this.open=!this.open,this.open&&requestAnimationFrame(()=>this.focusItem(0)),this.render())}triggerSignature(){return[this.resolvedSize(),this.getAttribute("trigger-variant")||"tertiary",this.hasAttribute("icon-only")?"1":"0",this.getAttribute("trigger-icon")||"",this.fullWidth?"1":"0"].join("|")}renderDefaultTrigger(){const t=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=s.includes(i)?i:"tertiary",n=this.hasAttribute("icon-only"),a=this.getAttribute("trigger-icon"),o=document.createElement("db-button");if(o.setAttribute("type","button"),o.setAttribute("variant",r),o.setAttribute("size",t),o.className="designbase-wc-dropdown__trigger",o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&o.setAttribute("full-width",""),n)o.setAttribute("icon-only",""),o.setAttribute("start-icon",a&&e(a)?a:"edit"),o.removeAttribute("end-icon");else{o.removeAttribute("icon-only"),a&&e(a)?o.setAttribute("start-icon",a):o.removeAttribute("start-icon");const t=document.createElement("span");t.className="designbase-wc-dropdown__trigger-label",t.textContent=this.triggerLabel(),o.append(t),o.setAttribute("end-icon","chevron-down")}return o}syncDefaultTriggerState(e){e.setAttribute("aria-expanded",String(this.open)),e.setAttribute("aria-label",this.triggerLabel()),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.disabled?e.setAttribute("disabled",""):e.removeAttribute("disabled");const t=e.querySelector(".designbase-wc-dropdown__trigger-label");t&&(t.textContent=this.triggerLabel())}ensureStructure(){this.triggerWrap||(this.triggerWrap=document.createElement("div"),this.triggerWrap.className="designbase-wc-dropdown__trigger-wrap",this.triggerWrap.setAttribute("data-wc-internal","")),this.menu||(this.menu=document.createElement("div"),this.menu.className="designbase-wc-dropdown__menu",this.menu.setAttribute("data-wc-internal",""),this.menu.setAttribute("role","menu"));const e=this.triggerWrap,t=this.menu;e&&t&&(this.contains(e)||this.append(e),e.contains(t)||e.append(t),Array.from(this.children).forEach(i=>{i===e||i.hasAttribute("data-wc-internal")||e.insertBefore(i,t)}))}renderTrigger(){const e=this.triggerWrap,t=this.menu;if(!e||!t)return;const i=this.collectTriggerChildren();if(i.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),i.forEach(i=>{i.setAttribute("aria-haspopup","menu"),i.setAttribute("aria-expanded",String(this.open)),i.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),e.insertBefore(i,t)})}else{Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature||(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),e.insertBefore(this.defaultTrigger,t)),this.defaultTrigger&&this.syncDefaultTriggerState(this.defaultTrigger)}this.bindTrigger()}renderMenu(){const e=this.resolvedPlacement();this.menu.className=`designbase-wc-dropdown__menu designbase-wc-dropdown__menu--${e}${this.open?" designbase-wc-dropdown__menu--open":""}`,this.menu.setAttribute("aria-hidden",String(!this.open)),this.menu.setAttribute("aria-label",this.triggerLabel()),this.menu.replaceChildren();const i=this.menuItemIconSize();this.parsedItems.forEach((e,r)=>{if(e.divider){const e=document.createElement("div");return e.className="designbase-wc-dropdown__divider",e.setAttribute("role","separator"),void this.menu?.append(e)}e.id||e.label||String(r);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),a=this.focusedIndex===r,o=document.createElement("button");if(o.type="button",o.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",a&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),o.setAttribute("role","menuitem"),o.disabled=n,o.tabIndex=a?0:-1,o.dataset.index=String(r),e.icon){const r=t(e.icon,i);r.classList.add("designbase-wc-dropdown__item-icon"),o.append(r)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,o.append(d),o.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(o)})}render(){const e=this.resolvedSize();this.className=["designbase-wc-dropdown",`designbase-wc-dropdown--${e}`,this.open&&"designbase-wc-dropdown--open",this.fullWidth&&"designbase-wc-dropdown--full-width",this.disabled&&"designbase-wc-dropdown--disabled"].filter(Boolean).join(" "),this.ensureStructure(),this.renderTrigger(),this.renderMenu()}selectItem(e){e.disabled||e.divider||(this.open=!1,this.focusedIndex=-1,this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.label||e.id,id:e.id,item:e},bubbles:!0,composed:!0})),this.render(),this.triggerWrap?.querySelector("[aria-haspopup]")?.focus())}focusItem(e){const t=this.enabledItems();if(!t.length)return;const i=t[Math.max(0,Math.min(e,t.length-1))],r=this.parsedItems.indexOf(i);this.focusedIndex=r;Array.from(this.menu?.querySelectorAll(".designbase-wc-dropdown__item")||[]).forEach(e=>{const t=Number(e.dataset.index)===r;e.classList.toggle("designbase-wc-dropdown__item--focused",t),e.tabIndex=t?0:-1,t&&e.focus()})}}customElements.get("db-dropdown")||customElements.define("db-dropdown",DbDropdown);export{DbDropdown};
1
+ import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";import{DROPDOWN_SIZES as i,DROPDOWN_PLACEMENTS as r,DROPDOWN_TRIGGER_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(!this.menu?.contains(e.target))return"Enter"!==e.key&&" "!==e.key&&"ArrowDown"!==e.key||this.open?void("Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,this.render())):(e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render())},this.handleDocumentKeyDown=e=>{if(!this.open)return;if("Escape"===e.key)return e.preventDefault(),this.open=!1,this.render(),void this.triggerWrap?.querySelector("[aria-haspopup]")?.focus();if(this.menu?.querySelector(':scope > [slot="content"]'))return;const t=this.enabledItems();if(!t.length)return;const i=t.findIndex(e=>this.parsedItems.indexOf(e)===this.focusedIndex);switch(e.key){case"ArrowDown":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i+1)%t.length]));break;case"ArrowUp":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i-1+t.length)%t.length]));break;case"Home":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[0]));break;case"End":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[t.length-1]));break;case"Enter":case" ":{e.preventDefault();const t=this.parsedItems[this.focusedIndex];!t||t.divider||t.disabled||this.selectItem(t);break}}},this.handleDocumentMouseDown=e=>{this.open&&(this.contains(e.target)||(this.open=!1,this.render()))}}static get observedAttributes(){return["options","items","placeholder","label","value","size","placement","full-width","disabled","open","trigger-variant","trigger-icon","icon-only","show-chevron"]}get showChevron(){return"false"!==this.getAttribute("show-chevron")}set showChevron(e){this.setAttribute("show-chevron",String(e))}get parsedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return(this.getAttribute("options")||"").split(",").map(e=>e.trim()).filter(Boolean).map((e,t)=>({id:`option-${t}`,label:e}))}get options(){return this.parsedItems.map(e=>e.label||e.id)}set options(e){this.setAttribute("options",Array.isArray(e)?e.join(","):e)}get items(){return this.parsedItems}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value")}get open(){return this.hasAttribute("open")}set open(e){const t=this.open;this.toggleAttribute("open",e),t!==e&&this.dispatchEvent(new CustomEvent("db-open",{detail:{open:e},bubbles:!0,composed:!0}))}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get placement(){return this.getAttribute("placement")||"bottom-left"}set placement(e){this.setAttribute("placement",e)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(e){e?this.setAttribute("placeholder",e):this.removeAttribute("placeholder")}get label(){return this.getAttribute("label")||""}set label(e){e?this.setAttribute("label",e):this.removeAttribute("label")}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(e){this.toggleAttribute("full-width",e)}connectedCallback(){requestAnimationFrame(()=>this.render()),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.unbindTrigger()}attributeChangedCallback(e){this.isConnected&&("open"!==e||this.open||(this.focusedIndex=-1),this.render())}resolvedSize(){return i.includes(this.size)?this.size:"m"}resolvedPlacement(){return r.includes(this.placement)?this.placement:"bottom-left"}menuItemIconSize(){const e=this.resolvedSize();return"s"===e?14:"l"===e?18:16}triggerLabel(){return this.label?this.label:this.placeholder?this.placeholder:this.value?this.value:"메뉴"}enabledItems(){return this.parsedItems.filter(e=>!e.disabled&&!e.divider)}collectTriggerChildren(){const isInternalNode=e=>"content"===e.getAttribute("slot")||e.hasAttribute("data-wc-internal")||e===this.triggerWrap||e===this.menu||e===this.defaultTrigger,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>!isInternalNode(e))}hasCustomTrigger(){return this.collectTriggerChildren().length>0}bindTrigger(){this.triggerWrap&&(this.unbindTrigger(),this.onTriggerActivate=e=>{this.disabled||this.menu?.contains(e.target)||(e.preventDefault(),e.stopPropagation(),this.toggleOpen())},this.triggerWrap.addEventListener("click",this.onTriggerActivate),this.triggerWrap.addEventListener("keydown",this.handleTriggerKeyDown))}unbindTrigger(){this.triggerWrap&&this.onTriggerActivate&&this.triggerWrap.removeEventListener("click",this.onTriggerActivate),this.triggerWrap&&this.triggerWrap.removeEventListener("keydown",this.handleTriggerKeyDown),this.onTriggerActivate=null}toggleOpen(){this.disabled||(this.open=!this.open,this.open&&requestAnimationFrame(()=>this.focusItem(0)),this.render())}triggerSignature(){return[this.resolvedSize(),this.getAttribute("trigger-variant")||"tertiary",this.hasAttribute("icon-only")?"1":"0",this.getAttribute("trigger-icon")||"",this.fullWidth?"1":"0",this.showChevron?"1":"0"].join("|")}renderDefaultTrigger(){const t=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=s.includes(i)?i:"tertiary",n=this.hasAttribute("icon-only"),o=this.getAttribute("trigger-icon"),a=document.createElement("db-button");if(a.setAttribute("type","button"),a.setAttribute("variant",r),a.setAttribute("size",t),a.className="designbase-wc-dropdown__trigger",a.setAttribute("aria-haspopup","menu"),a.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&a.setAttribute("full-width",""),n)a.setAttribute("icon-only",""),a.setAttribute("start-icon",o&&e(o)?o:"edit"),a.removeAttribute("end-icon");else{a.removeAttribute("icon-only"),o&&e(o)?a.setAttribute("start-icon",o):a.removeAttribute("start-icon");const t=document.createElement("span");t.className="designbase-wc-dropdown__trigger-label",t.textContent=this.triggerLabel(),a.append(t),this.showChevron&&a.setAttribute("end-icon","chevron-down")}return a}syncDefaultTriggerState(e){e.setAttribute("aria-expanded",String(this.open)),e.setAttribute("aria-label",this.triggerLabel()),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.disabled?e.setAttribute("disabled",""):e.removeAttribute("disabled");const t=e.querySelector(".designbase-wc-dropdown__trigger-label");t&&(t.textContent=this.triggerLabel())}ensureStructure(){this.triggerWrap||(this.triggerWrap=document.createElement("div"),this.triggerWrap.className="designbase-wc-dropdown__trigger-wrap",this.triggerWrap.setAttribute("data-wc-internal","")),this.menu||(this.menu=document.createElement("div"),this.menu.className="designbase-wc-dropdown__menu",this.menu.setAttribute("data-wc-internal",""),this.menu.setAttribute("role","menu"));const e=this.triggerWrap,t=this.menu;e&&t&&(this.contains(e)||this.append(e),e.contains(t)||e.append(t),Array.from(this.children).forEach(i=>{i===e||i.hasAttribute("data-wc-internal")||("content"===i.getAttribute("slot")?t.append(i):e.insertBefore(i,t))}))}renderTrigger(){const e=this.triggerWrap,t=this.menu;if(!e||!t)return;const i=this.collectTriggerChildren();if(i.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),i.forEach(i=>{i.setAttribute("aria-haspopup","menu"),i.setAttribute("aria-expanded",String(this.open)),i.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),e.insertBefore(i,t)})}else{Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature||(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),e.insertBefore(this.defaultTrigger,t)),this.defaultTrigger&&this.syncDefaultTriggerState(this.defaultTrigger)}this.bindTrigger()}renderMenu(){const e=this.resolvedPlacement();this.menu.className=`designbase-wc-dropdown__menu designbase-wc-dropdown__menu--${e}${this.open?" designbase-wc-dropdown__menu--open":""}`,this.menu.setAttribute("aria-hidden",String(!this.open)),this.menu.setAttribute("aria-label",this.triggerLabel());const i=this.menu.querySelector(':scope > [slot="content"]');if(this.menu.setAttribute("role",i?"dialog":"menu"),i)return this.menu.inert=!this.open,this.menu.setAttribute("aria-modal","false"),this.menu.classList.add("designbase-wc-dropdown__menu--custom"),void this.triggerWrap?.querySelector("[aria-haspopup]")?.setAttribute("aria-haspopup","dialog");this.menu.inert=!1,this.menu.removeAttribute("aria-modal"),this.menu.replaceChildren();const r=this.menuItemIconSize();this.parsedItems.forEach((e,i)=>{if(e.divider){const e=document.createElement("div");return e.className="designbase-wc-dropdown__divider",e.setAttribute("role","separator"),void this.menu?.append(e)}e.id||e.label||String(i);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),o=this.focusedIndex===i,a=document.createElement("button");if(a.type="button",a.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",o&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.disabled=n,a.tabIndex=o?0:-1,a.dataset.index=String(i),e.icon){const i=t(e.icon,r);i.classList.add("designbase-wc-dropdown__item-icon"),a.append(i)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,a.append(d),a.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(a)})}render(){const e=this.resolvedSize();this.className=["designbase-wc-dropdown",`designbase-wc-dropdown--${e}`,this.open&&"designbase-wc-dropdown--open",this.fullWidth&&"designbase-wc-dropdown--full-width",this.disabled&&"designbase-wc-dropdown--disabled"].filter(Boolean).join(" "),this.ensureStructure(),this.renderTrigger(),this.renderMenu()}selectItem(e){e.disabled||e.divider||(this.open=!1,this.focusedIndex=-1,this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.label||e.id,id:e.id,item:e},bubbles:!0,composed:!0})),this.render(),this.triggerWrap?.querySelector("[aria-haspopup]")?.focus())}focusItem(e){if(this.menu?.querySelector(':scope > [slot="content"]'))return void this.menu.querySelector('input:not([disabled]), button:not([disabled]), [tabindex="0"]')?.focus();const t=this.enabledItems();if(!t.length)return;const i=t[Math.max(0,Math.min(e,t.length-1))],r=this.parsedItems.indexOf(i);this.focusedIndex=r;Array.from(this.menu?.querySelectorAll(".designbase-wc-dropdown__item")||[]).forEach(e=>{const t=Number(e.dataset.index)===r;e.classList.toggle("designbase-wc-dropdown__item--focused",t),e.tabIndex=t?0:-1,t&&e.focus()})}}customElements.get("db-dropdown")||customElements.define("db-dropdown",DbDropdown);export{DbDropdown};
@@ -1,7 +1,7 @@
1
1
  import './db-button.js';
2
2
  import './db-input.js';
3
3
  import './db-otp-input.js';
4
- import { EMAIL_VERIFY_SIZES } from '@designbasekorea/ui-contracts';
4
+ import { EMAIL_VERIFY_SIZES } from '../ui-contracts/dist/components.d.js';
5
5
 
6
6
  /**
7
7
  * ui-wc — db-email-verify (수동 작성, 자동 동기화 대상 아님)
@@ -1,3 +1,12 @@
1
+ type FileStatus = 'pending' | 'uploading' | 'success' | 'error';
2
+ type UploadFile = {
3
+ file: File;
4
+ id: string;
5
+ status: FileStatus;
6
+ progress: number;
7
+ error?: string;
8
+ uploadedAt?: Date;
9
+ };
1
10
  declare class DbFileUploader extends HTMLElement {
2
11
  static get observedAttributes(): string[];
3
12
  private dropzone?;
@@ -25,3 +34,4 @@ declare global {
25
34
  }
26
35
 
27
36
  export { DbFileUploader };
37
+ export type { FileStatus, UploadFile };
@@ -0,0 +1,34 @@
1
+ declare const FILTER_BAR_SIZES: readonly ["s", "m", "l"];
2
+ declare const FILTER_BAR_VARIANTS: readonly ["plain", "outlined", "filled"];
3
+ declare const FILTER_BAR_ALIGNS: readonly ["start", "end"];
4
+ type FilterBarSize = (typeof FILTER_BAR_SIZES)[number];
5
+ type FilterBarVariant = (typeof FILTER_BAR_VARIANTS)[number];
6
+ type FilterBarAlign = (typeof FILTER_BAR_ALIGNS)[number];
7
+ /**
8
+ * Search/filter composition. Direct children use search, filters, summary and
9
+ * actions slots. No rendering or reparenting: field values, focus, overlays and
10
+ * framework listeners remain owned by the controls supplied by the consumer.
11
+ *
12
+ * This is a labelled group, not an ARIA toolbar: fields keep normal Tab order.
13
+ */
14
+ declare class DbFilterBar extends HTMLElement {
15
+ static get observedAttributes(): string[];
16
+ private decoration;
17
+ get padding(): boolean;
18
+ set padding(value: boolean);
19
+ get border(): boolean;
20
+ set border(value: boolean);
21
+ get background(): boolean;
22
+ set background(value: boolean);
23
+ connectedCallback(): void;
24
+ attributeChangedCallback(): void;
25
+ private syncHostClasses;
26
+ }
27
+ declare global {
28
+ interface HTMLElementTagNameMap {
29
+ 'db-filter-bar': DbFilterBar;
30
+ }
31
+ }
32
+
33
+ export { DbFilterBar };
34
+ export type { FilterBarAlign, FilterBarSize, FilterBarVariant };
@@ -0,0 +1 @@
1
+ import{coerceToContract as t,SIZE_SML as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";const i=e,r=["plain","outlined","filled"],s=["start","end"];class DbFilterBar extends HTMLElement{static get observedAttributes(){return["size","variant","align","padding","border","background"]}decoration(e){const i=this.getAttribute(e);if(null!=i)return"false"!==i;const s=t(this.getAttribute("variant"),r,"plain");return"background"===e?"filled"===s:"plain"!==s}get padding(){return this.decoration("padding")}set padding(t){this.setAttribute("padding",String(t))}get border(){return this.decoration("border")}set border(t){this.setAttribute("border",String(t))}get background(){return this.decoration("background")}set background(t){this.setAttribute("background",String(t))}connectedCallback(){this.hasAttribute("role")||this.setAttribute("role","group"),this.hasAttribute("aria-label")||this.hasAttribute("aria-labelledby")||this.setAttribute("aria-label","Filters"),this.syncHostClasses()}attributeChangedCallback(){this.syncHostClasses()}syncHostClasses(){const e=[...this.classList].filter(t=>!t.startsWith("designbase-wc-filter-bar")),a=t(this.getAttribute("size"),i,"m"),n=t(this.getAttribute("variant"),r,"plain"),b=t(this.getAttribute("align"),s,"start");this.className=[...e,"designbase-wc-filter-bar",`designbase-wc-filter-bar--${a}`,`designbase-wc-filter-bar--${n}`,`designbase-wc-filter-bar--${b}`,...["padding","border","background"].filter(t=>this.decoration(t)).map(t=>`designbase-wc-filter-bar--${t}`)].join(" ")}}customElements.get("db-filter-bar")||customElements.define("db-filter-bar",DbFilterBar);export{DbFilterBar};