@designbasekorea/ui-wc 0.5.6 → 0.6.1

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 (193) hide show
  1. package/dist/chunks/lottie-35a9b0f5.js +1 -0
  2. package/dist/esm/components/animation-background/canvas-controller.js +1 -121
  3. package/dist/esm/components/animation-background/controls.js +1 -180
  4. package/dist/esm/components/animation-background/graphite-controller.js +1 -196
  5. package/dist/esm/components/animation-background/graphite-presets.js +1 -42
  6. package/dist/esm/components/animation-background/graphite-shader.js +1 -111
  7. package/dist/esm/components/animation-background/layers.js +1 -369
  8. package/dist/esm/components/animation-background/lumina-presets.js +1 -53
  9. package/dist/esm/components/animation-background/lumina-shaders.js +1 -181
  10. package/dist/esm/components/animation-background/lumina-utils.js +1 -60
  11. package/dist/esm/components/animation-background/particle-defaults.js +1 -36
  12. package/dist/esm/components/animation-background/renderers.js +1 -167
  13. package/dist/esm/components/animation-background/shader-controller.js +1 -154
  14. package/dist/esm/components/color-picker-utils.js +1 -134
  15. package/dist/esm/components/date-picker-utils.js +1 -140
  16. package/dist/esm/components/db-accordion.js +1 -304
  17. package/dist/esm/components/db-ad-banner.js +1 -455
  18. package/dist/esm/components/db-ai-chat-list.d.ts +43 -0
  19. package/dist/esm/components/db-ai-chat-list.js +1 -0
  20. package/dist/esm/components/db-ai-chat.d.ts +159 -0
  21. package/dist/esm/components/db-ai-chat.js +1 -0
  22. package/dist/esm/components/db-alert.js +1 -149
  23. package/dist/esm/components/db-animation-background.js +1 -486
  24. package/dist/esm/components/db-animation-text.js +1 -601
  25. package/dist/esm/components/db-app-badge.js +1 -88
  26. package/dist/esm/components/db-audio-player.js +1 -752
  27. package/dist/esm/components/db-avatar.js +1 -188
  28. package/dist/esm/components/db-backdrop.js +1 -139
  29. package/dist/esm/components/db-badge.js +1 -91
  30. package/dist/esm/components/db-banner.js +1 -188
  31. package/dist/esm/components/db-bottom-navigation.js +1 -146
  32. package/dist/esm/components/db-bottom-sheet.js +1 -481
  33. package/dist/esm/components/db-breadcrumbs.js +1 -329
  34. package/dist/esm/components/db-button.js +1 -316
  35. package/dist/esm/components/db-calendar.js +1 -675
  36. package/dist/esm/components/db-card.js +1 -265
  37. package/dist/esm/components/db-carousel.js +1 -264
  38. package/dist/esm/components/db-chat-composer.d.ts +134 -0
  39. package/dist/esm/components/db-chat-composer.js +1 -0
  40. package/dist/esm/components/db-chat-list.d.ts +47 -0
  41. package/dist/esm/components/db-chat-list.js +1 -0
  42. package/dist/esm/components/db-chat-message.d.ts +39 -0
  43. package/dist/esm/components/db-chat-message.js +1 -0
  44. package/dist/esm/components/db-chat-orb.d.ts +99 -0
  45. package/dist/esm/components/db-chat-orb.js +1 -0
  46. package/dist/esm/components/db-chat-room.d.ts +71 -0
  47. package/dist/esm/components/db-chat-room.js +1 -0
  48. package/dist/esm/components/db-chat-suggestions.d.ts +44 -0
  49. package/dist/esm/components/db-chat-suggestions.js +1 -0
  50. package/dist/esm/components/db-chat-typing.d.ts +22 -0
  51. package/dist/esm/components/db-chat-typing.js +1 -0
  52. package/dist/esm/components/db-chat-welcome.d.ts +32 -0
  53. package/dist/esm/components/db-chat-welcome.js +1 -0
  54. package/dist/esm/components/db-chat-widget.d.ts +146 -0
  55. package/dist/esm/components/db-chat-widget.js +1 -0
  56. package/dist/esm/components/db-checkbox.js +1 -202
  57. package/dist/esm/components/db-chip.js +1 -104
  58. package/dist/esm/components/db-code-block.js +1 -304
  59. package/dist/esm/components/db-color-picker.js +1 -746
  60. package/dist/esm/components/db-confirm.js +1 -191
  61. package/dist/esm/components/db-container.js +1 -39
  62. package/dist/esm/components/db-context-menu.js +1 -265
  63. package/dist/esm/components/db-countdown.js +1 -146
  64. package/dist/esm/components/db-cursor-follower.js +1 -173
  65. package/dist/esm/components/db-date-picker.js +1 -837
  66. package/dist/esm/components/db-divider.js +1 -66
  67. package/dist/esm/components/db-download-progress.d.ts +89 -0
  68. package/dist/esm/components/db-download-progress.js +1 -0
  69. package/dist/esm/components/db-drawer.js +1 -245
  70. package/dist/esm/components/db-dropdown.js +1 -493
  71. package/dist/esm/components/db-dropzone.js +1 -266
  72. package/dist/esm/components/db-email-verify.d.ts +64 -0
  73. package/dist/esm/components/db-email-verify.js +1 -0
  74. package/dist/esm/components/db-empty-state.js +1 -97
  75. package/dist/esm/components/db-file-uploader.js +1 -256
  76. package/dist/esm/components/db-floating-action-button.js +1 -139
  77. package/dist/esm/components/db-footer.js +1 -385
  78. package/dist/esm/components/db-form.js +1 -566
  79. package/dist/esm/components/db-gantt.js +1 -882
  80. package/dist/esm/components/db-gradient.js +1 -133
  81. package/dist/esm/components/db-grid-background.js +1 -909
  82. package/dist/esm/components/db-grid.js +1 -73
  83. package/dist/esm/components/db-icons.d.ts +3 -0
  84. package/dist/esm/components/db-icons.js +1 -82
  85. package/dist/esm/components/db-image-list.js +1 -214
  86. package/dist/esm/components/db-image-placeholder.js +1 -96
  87. package/dist/esm/components/db-image.js +1 -289
  88. package/dist/esm/components/db-indicator.js +1 -517
  89. package/dist/esm/components/db-input.js +1 -420
  90. package/dist/esm/components/db-kanban.js +1 -538
  91. package/dist/esm/components/db-label.js +1 -66
  92. package/dist/esm/components/db-lightbox.js +1 -372
  93. package/dist/esm/components/db-list.js +1 -340
  94. package/dist/esm/components/db-logo-svg.js +1 -72
  95. package/dist/esm/components/db-logo.js +1 -106
  96. package/dist/esm/components/db-lottie.js +1 -109
  97. package/dist/esm/components/db-markdown-editor.js +1 -458
  98. package/dist/esm/components/db-marquee.js +1 -402
  99. package/dist/esm/components/db-masonry.js +1 -94
  100. package/dist/esm/components/db-menu-item.js +1 -211
  101. package/dist/esm/components/db-modal.js +1 -522
  102. package/dist/esm/components/db-navbar.js +1 -680
  103. package/dist/esm/components/db-onboarding-modal.js +1 -322
  104. package/dist/esm/components/db-otp-input.d.ts +53 -0
  105. package/dist/esm/components/db-otp-input.js +1 -0
  106. package/dist/esm/components/db-page-header.js +1 -312
  107. package/dist/esm/components/db-pagination.js +1 -271
  108. package/dist/esm/components/db-phone-verify.d.ts +63 -0
  109. package/dist/esm/components/db-phone-verify.js +1 -0
  110. package/dist/esm/components/db-popover.js +1 -580
  111. package/dist/esm/components/db-progress-step.js +1 -166
  112. package/dist/esm/components/db-progress.js +1 -171
  113. package/dist/esm/components/db-progressbar.js +1 -72
  114. package/dist/esm/components/db-radio.js +1 -172
  115. package/dist/esm/components/db-random-gradient.js +1 -121
  116. package/dist/esm/components/db-range-slider.js +1 -811
  117. package/dist/esm/components/db-rating.js +1 -325
  118. package/dist/esm/components/db-reorder.js +1 -286
  119. package/dist/esm/components/db-resizable-panels.js +1 -282
  120. package/dist/esm/components/db-scroll-area.js +1 -126
  121. package/dist/esm/components/db-search-bar.js +1 -668
  122. package/dist/esm/components/db-section-app-download.js +1 -101
  123. package/dist/esm/components/db-section-contact.js +1 -102
  124. package/dist/esm/components/db-section-cta.js +1 -150
  125. package/dist/esm/components/db-section-faq.js +1 -120
  126. package/dist/esm/components/db-section-feature-grid.js +1 -137
  127. package/dist/esm/components/db-section-feature.js +1 -179
  128. package/dist/esm/components/db-section-hero.js +1 -243
  129. package/dist/esm/components/db-section-logo-cloud.js +1 -138
  130. package/dist/esm/components/db-section-pricing.js +1 -166
  131. package/dist/esm/components/db-section-stats.js +1 -129
  132. package/dist/esm/components/db-section-testimonials.js +1 -252
  133. package/dist/esm/components/db-section.js +1 -385
  134. package/dist/esm/components/db-segment-control.js +1 -231
  135. package/dist/esm/components/db-select.js +1 -571
  136. package/dist/esm/components/db-share-icons.js +1 -40
  137. package/dist/esm/components/db-share.js +1 -489
  138. package/dist/esm/components/db-sidebar.d.ts +20 -0
  139. package/dist/esm/components/db-sidebar.js +1 -1068
  140. package/dist/esm/components/db-skeleton.js +1 -94
  141. package/dist/esm/components/db-spinner.js +1 -102
  142. package/dist/esm/components/db-split-view.js +1 -297
  143. package/dist/esm/components/db-stack.js +1 -46
  144. package/dist/esm/components/db-stat.js +1 -218
  145. package/dist/esm/components/db-stepper.js +1 -398
  146. package/dist/esm/components/db-table.js +1 -412
  147. package/dist/esm/components/db-tabs.js +1 -335
  148. package/dist/esm/components/db-testimonial.d.ts +2 -0
  149. package/dist/esm/components/db-testimonial.js +1 -162
  150. package/dist/esm/components/db-textarea.js +1 -233
  151. package/dist/esm/components/db-time-picker.js +1 -523
  152. package/dist/esm/components/db-timeline.js +1 -174
  153. package/dist/esm/components/db-toast.js +1 -158
  154. package/dist/esm/components/db-toggle.js +1 -162
  155. package/dist/esm/components/db-toolbar.js +1 -94
  156. package/dist/esm/components/db-tooltip.js +1 -440
  157. package/dist/esm/components/db-top-banner.js +1 -121
  158. package/dist/esm/components/db-tutorial.js +1 -324
  159. package/dist/esm/components/db-two-factor.d.ts +71 -0
  160. package/dist/esm/components/db-two-factor.js +1 -0
  161. package/dist/esm/components/db-video-player.js +1 -503
  162. package/dist/esm/components/db-youtube-player.js +1 -194
  163. package/dist/esm/components/highlight-code.js +1 -65
  164. package/dist/esm/components/input-validation.js +1 -50
  165. package/dist/esm/components/marketing-block-host-utils.js +1 -9
  166. package/dist/esm/components/number-scrub.js +1 -117
  167. package/dist/esm/components/random-gradient-palettes.js +1 -67
  168. package/dist/esm/components/section-block-header-utils.js +1 -48
  169. package/dist/esm/helpers/confirm.js +1 -52
  170. package/dist/esm/helpers/toast.js +1 -73
  171. package/dist/esm/index.d.ts +16 -0
  172. package/dist/esm/index.js +1 -111
  173. package/dist/esm/node_modules/prismjs/components/prism-bash.js +1 -235
  174. package/dist/esm/node_modules/prismjs/components/prism-clike.js +1 -31
  175. package/dist/esm/node_modules/prismjs/components/prism-css.js +1 -64
  176. package/dist/esm/node_modules/prismjs/components/prism-javascript.js +1 -172
  177. package/dist/esm/node_modules/prismjs/components/prism-json.js +1 -27
  178. package/dist/esm/node_modules/prismjs/components/prism-jsx.js +1 -143
  179. package/dist/esm/node_modules/prismjs/components/prism-markup.js +1 -186
  180. package/dist/esm/node_modules/prismjs/components/prism-scss.js +1 -81
  181. package/dist/esm/node_modules/prismjs/components/prism-tsx.js +1 -15
  182. package/dist/esm/node_modules/prismjs/components/prism-typescript.js +1 -60
  183. package/dist/index.cjs +1 -55414
  184. package/dist/index.css +1 -1
  185. package/dist/index.d.ts +1125 -2
  186. package/dist/index.esm.js +1 -38284
  187. package/dist/react/chunks/lottie-14e7addb.js +1 -0
  188. package/dist/react/index.cjs +1 -56503
  189. package/dist/react/index.d.ts +1637 -21
  190. package/dist/react/index.esm.js +1 -39373
  191. package/package.json +2 -2
  192. package/dist/chunks/lottie-e273b936.js +0 -17032
  193. package/dist/react/chunks/lottie-72a4c6d4.js +0 -17032
@@ -0,0 +1,159 @@
1
+ import './db-chat-welcome.js';
2
+ import { DbChatSuggestion } from './db-chat-suggestions.js';
3
+ import './db-chat-message.js';
4
+ import './db-chat-typing.js';
5
+ import { DbChatTool, DbChatAttachOption, DbChatComposer } from './db-chat-composer.js';
6
+
7
+ interface DbArtifactOptions {
8
+ /** 패널 헤더 제목 */
9
+ title?: string;
10
+ /** 헤더 부제(선택) */
11
+ subtitle?: string;
12
+ /** 본문 HTML (setArtifactContent 로 요소를 직접 넣을 수도 있음) */
13
+ html?: string;
14
+ /** 인라인 카드와 동기화할 id (toggle 용) */
15
+ id?: string;
16
+ }
17
+ /** 채팅 스레드 안에 노출되는 결과물(아티팩트) 카드 */
18
+ interface DbChatArtifactRef {
19
+ id?: string;
20
+ title: string;
21
+ subtitle?: string;
22
+ icon?: string;
23
+ html?: string;
24
+ }
25
+ interface DbChatMessageData {
26
+ id?: string;
27
+ role?: 'user' | 'assistant' | 'system';
28
+ /** 평문 본문 */
29
+ text?: string;
30
+ /** HTML 본문 (text 대신) */
31
+ html?: string;
32
+ name?: string;
33
+ time?: string;
34
+ avatarSrc?: string;
35
+ avatarInitials?: string;
36
+ /** 말풍선 액션 (예: 'copy,regenerate,like,dislike') */
37
+ actions?: string;
38
+ status?: 'sending' | 'error';
39
+ variant?: 'bubble' | 'plain';
40
+ /** 스레드 인라인 결과물 카드 — 클릭 시 우측 아티팩트 패널 토글 */
41
+ artifact?: DbChatArtifactRef;
42
+ }
43
+ /**
44
+ * 전체 대화형 AI 채팅 화면. 시작 전(빈 상태)과 대화 중을 하나로 통합한 최상위 컴포넌트로,
45
+ * 채팅 프리미티브(`db-chat-welcome` · `db-chat-suggestions` · `db-chat-message`
46
+ * · `db-chat-typing` · `db-chat-composer`)를 조합합니다.
47
+ *
48
+ * - 메시지가 없으면 히어로(인사말 + 추천)를 중앙에 보여주고,
49
+ * - 메시지가 생기면 스크롤 스레드로 전환하며, 컴포저는 항상 하단에 고정됩니다.
50
+ *
51
+ * @fires db-send - 전송 (detail: { value, attachments })
52
+ * @fires db-stop - 생성 중지
53
+ * @fires db-tool-toggle - 툴 토글 (detail: { id, active })
54
+ * @fires db-attach - 첨부 종류 선택 (detail: { type })
55
+ * @fires db-attach-files - 파일 선택 (detail: { type, files })
56
+ * @fires db-voice - 음성 입력
57
+ * @fires db-suggestion-select - 추천 선택 (detail: { id, title, value })
58
+ * @fires db-message-action - 말풍선 액션 (detail: { action, text })
59
+ *
60
+ * @example
61
+ * const chat = document.querySelector('db-chat');
62
+ * chat.suggestions = [{ title:'카피 작성', icon:'edit' }];
63
+ * chat.tools = [{ id:'reason', label:'Reasoning', icon:'bulb' }];
64
+ * chat.addEventListener('db-send', (e) => {
65
+ * chat.addMessage({ role:'user', text: e.detail.value });
66
+ * chat.setTyping(true);
67
+ * });
68
+ */
69
+ declare class DbAiChat extends HTMLElement {
70
+ static get observedAttributes(): string[];
71
+ private built;
72
+ private typing;
73
+ private _messages;
74
+ private _suggestions;
75
+ private _tools;
76
+ private _attachOptions;
77
+ private mainEl;
78
+ private scrollEl;
79
+ private dockEl;
80
+ private composer;
81
+ private threadEl;
82
+ private artifactEl;
83
+ private artifactTitleEl;
84
+ private artifactSubtitleEl;
85
+ private artifactBodyEl;
86
+ private activeArtifactId;
87
+ private artifactSeq;
88
+ set messages(v: DbChatMessageData[]);
89
+ get messages(): DbChatMessageData[];
90
+ set suggestions(v: DbChatSuggestion[]);
91
+ get suggestions(): DbChatSuggestion[];
92
+ set tools(v: DbChatTool[]);
93
+ get tools(): DbChatTool[];
94
+ set attachOptions(v: DbChatAttachOption[]);
95
+ get attachOptions(): DbChatAttachOption[];
96
+ connectedCallback(): void;
97
+ attributeChangedCallback(name: string): void;
98
+ private build;
99
+ private buildArtifact;
100
+ private sync;
101
+ private syncArtifact;
102
+ private syncComposerToggles;
103
+ private renderContent;
104
+ private renderHero;
105
+ private renderThread;
106
+ private buildMessage;
107
+ private ensureArtifactId;
108
+ private buildArtifactCard;
109
+ private syncArtifactCardStates;
110
+ private toggleArtifactFromCard;
111
+ private buildTyping;
112
+ private renderDock;
113
+ private onSend;
114
+ private onSuggestionSelect;
115
+ private relay;
116
+ private scrollToEnd;
117
+ /** 메시지를 추가하고 스레드로 전환/스크롤. 추가된 메시지 id 반환 */
118
+ addMessage(msg: DbChatMessageData): string;
119
+ /** 특정 메시지 본문/속성 갱신 */
120
+ updateMessage(id: string, patch: Partial<DbChatMessageData>): void;
121
+ /** 스트리밍용: 마지막(또는 지정) 메시지 본문에 청크 이어붙이기 */
122
+ appendToMessage(id: string, chunk: string): void;
123
+ /** 전체 메시지 교체 */
124
+ setMessages(list: DbChatMessageData[]): void;
125
+ /** 대화를 비우고 히어로(빈 상태)로 복귀 */
126
+ clear(): void;
127
+ /** 생각 중(…) 표시 토글 */
128
+ setTyping(on: boolean): void;
129
+ /** 전송 중(정지 버튼) 상태 — 컴포저에 위임 */
130
+ setStreaming(on: boolean): void;
131
+ /** 입력창 포커스 */
132
+ focusInput(): void;
133
+ /** 컴포저 인스턴스 접근 */
134
+ getComposer(): DbChatComposer;
135
+ get artifactOpen(): boolean;
136
+ set artifactOpen(v: boolean);
137
+ /**
138
+ * 우측 아티팩트 패널을 엽니다(내용 지정 시 함께 세팅).
139
+ * 열리면 채팅 본문이 좌측으로 밀립니다.
140
+ * `id` 를 넘기면 스레드 인라인 카드 활성 상태가 동기화됩니다.
141
+ */
142
+ openArtifact(opts?: DbArtifactOptions): void;
143
+ /** 아티팩트 패널을 닫습니다. */
144
+ closeArtifact(): void;
145
+ /** 아티팩트 열림/닫힘 토글. */
146
+ toggleArtifact(): void;
147
+ /** 아티팩트 본문 요소(커스텀 콘텐츠를 직접 마운트할 때). */
148
+ getArtifactBody(): HTMLElement;
149
+ /** 아티팩트 본문을 요소로 교체합니다. */
150
+ setArtifactContent(node: Node): void;
151
+ }
152
+ declare global {
153
+ interface HTMLElementTagNameMap {
154
+ 'db-ai-chat': DbAiChat;
155
+ }
156
+ }
157
+
158
+ export { DbAiChat };
159
+ export type { DbArtifactOptions, DbChatArtifactRef, DbChatMessageData };
@@ -0,0 +1 @@
1
+ import"./db-chat-welcome.js";import"./db-chat-suggestions.js";import"./db-chat-message.js";import"./db-chat-typing.js";import"./db-chat-composer.js";import{createDbIcon as t,isDbIconName as e}from"./db-icons.js";const i="designbase-wc-ai-chat";let s=0;function el(t,e,i){const s=document.createElement(t);return e&&(s.className=e),null!=i&&(s.textContent=i),s}class DbAiChat extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.typing=!1,this._messages=[],this._suggestions=[],this._tools=[],this._attachOptions=null,this.threadEl=null,this.activeArtifactId=null,this.artifactSeq=0,this.onSend=t=>{t.stopPropagation();const e=t.detail;this.dispatchEvent(new CustomEvent("db-send",{detail:e,bubbles:!0,composed:!0}))},this.onSuggestionSelect=t=>{t.stopPropagation();const e=t.detail,i=new CustomEvent("db-suggestion-select",{detail:e,bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(i)&&(this.composer.value=e.value,this.composer.focusInput())}}static get observedAttributes(){return["greeting","title","highlight","subtitle","placeholder","orb-variant","suggestions-layout","suggestions-columns","disclaimer","voice","attach","max-width","artifact-open","artifact-title"]}set messages(t){this._messages=Array.isArray(t)?t.map(t=>({id:`m${s+=1}`,...t})):[],this.built&&this.renderContent()}get messages(){return this._messages}set suggestions(t){this._suggestions=Array.isArray(t)?t:[],this.built&&0===this._messages.length&&this.renderContent()}get suggestions(){return this._suggestions}set tools(t){this._tools=Array.isArray(t)?t:[],this.built&&(this.composer.tools=this._tools)}get tools(){return this._tools}set attachOptions(t){this._attachOptions=Array.isArray(t)?t:null,this.built&&this._attachOptions&&(this.composer.attachOptions=this._attachOptions)}get attachOptions(){return this._attachOptions??this.composer?.attachOptions??[]}connectedCallback(){this.built||this.build(),this.sync()}attributeChangedCallback(t){this.built&&("placeholder"!==t?"voice"!==t&&"attach"!==t?"disclaimer"!==t?"artifact-open"!==t?"artifact-title"!==t?this.sync():this.artifactTitleEl.textContent=this.getAttribute("artifact-title")||"":this.syncArtifact(!0):this.renderDock():this.syncComposerToggles():this.composer.setAttribute("placeholder",this.getAttribute("placeholder")||""))}build(){this.built=!0,this.classList.add(i),this.replaceChildren(),this.mainEl=el("div",`${i}__main`),this.scrollEl=el("div",`${i}__scroll`),this.dockEl=el("div",`${i}__dock`),this.composer=document.createElement("db-chat-composer"),this.composer.className=`${i}__composer`,this.composer.addEventListener("db-send",this.onSend),this.composer.addEventListener("db-stop",t=>this.relay(t,"db-stop")),this.composer.addEventListener("db-tool-toggle",t=>this.relay(t,"db-tool-toggle")),this.composer.addEventListener("db-attach",t=>this.relay(t,"db-attach")),this.composer.addEventListener("db-attach-files",t=>this.relay(t,"db-attach-files")),this.composer.addEventListener("db-voice",t=>this.relay(t,"db-voice")),this.mainEl.append(this.scrollEl,this.dockEl),this.buildArtifact(),this.append(this.mainEl,this.artifactEl)}buildArtifact(){this.artifactEl=el("aside",`${i}__artifact`),this.artifactEl.setAttribute("aria-hidden","true");const e=el("div",`${i}__artifact-panel`),s=el("div",`${i}__artifact-header`),a=el("div",`${i}__artifact-titles`);this.artifactTitleEl=el("div",`${i}__artifact-title`),this.artifactSubtitleEl=el("div",`${i}__artifact-subtitle`),this.artifactSubtitleEl.hidden=!0,a.append(this.artifactTitleEl,this.artifactSubtitleEl);const r=el("button",`${i}__artifact-close`);r.type="button",r.setAttribute("aria-label","아티팩트 닫기"),r.append(t("close",18)),r.addEventListener("click",()=>this.closeArtifact()),s.append(a,r),this.artifactBodyEl=el("div",`${i}__artifact-body`),e.append(s,this.artifactBodyEl),this.artifactEl.append(e)}sync(){const t=this.getAttribute("max-width")||"100%";this.style.setProperty("--dbchat-max",t),this.syncComposerToggles(),this.composer.setAttribute("placeholder",this.getAttribute("placeholder")||"무엇이든 물어보세요…"),this._tools.length&&(this.composer.tools=this._tools),this._attachOptions&&(this.composer.attachOptions=this._attachOptions);const e=this.getAttribute("artifact-title");null!=e&&(this.artifactTitleEl.textContent=e),this.renderContent(),this.renderDock(),this.syncArtifact(!1)}syncArtifact(t){const e=this.hasAttribute("artifact-open");this.classList.toggle(`${i}--artifact-open`,e),this.artifactEl.setAttribute("aria-hidden",String(!e)),this.artifactEl.toggleAttribute("inert",!e),e||(this.activeArtifactId=null),this.syncArtifactCardStates(),t&&this.dispatchEvent(new CustomEvent(e?"db-artifact-open":"db-artifact-close",{detail:e?{id:this.activeArtifactId}:{id:null},bubbles:!0,composed:!0}))}syncComposerToggles(){this.composer.toggleAttribute("voice",this.hasAttribute("voice")),this.composer.toggleAttribute("attach","false"!==this.getAttribute("attach"))}renderContent(){this.scrollEl.replaceChildren(),this.threadEl=null;const t=0===this._messages.length;this.classList.toggle(`${i}--empty`,t),t?this.renderHero():this.renderThread()}renderHero(){const t=el("div",`${i}__hero`),e=document.createElement("db-chat-welcome");if(e.className=`${i}__welcome`,this.getAttribute("greeting")&&e.setAttribute("greeting",this.getAttribute("greeting")),e.setAttribute("title",this.getAttribute("title")||"무엇을 도와드릴까요?"),this.getAttribute("highlight")&&e.setAttribute("highlight",this.getAttribute("highlight")),this.getAttribute("subtitle")&&e.setAttribute("subtitle",this.getAttribute("subtitle")),e.setAttribute("orb-variant",this.getAttribute("orb-variant")||"aurora"),e.setAttribute("align","center"),t.append(e),this._suggestions.length){const e=document.createElement("db-chat-suggestions");e.className=`${i}__suggestions`,e.setAttribute("layout",this.getAttribute("suggestions-layout")||"card"),e.setAttribute("columns",this.getAttribute("suggestions-columns")||"3"),e.items=this._suggestions,e.addEventListener("db-select",this.onSuggestionSelect),t.append(e)}this.scrollEl.append(t)}renderThread(){const t=el("div",`${i}__thread`);this._messages.forEach(e=>t.append(this.buildMessage(e))),this.threadEl=t,this.scrollEl.append(t),this.typing&&t.append(this.buildTyping()),requestAnimationFrame(()=>this.scrollToEnd())}buildMessage(t){const e=el("div",`${i}__turn`);e.dataset.id=t.id||"";const s=el("db-chat-message");return s.dataset.id=t.id||"",s.setAttribute("role",t.role||"assistant"),t.name&&s.setAttribute("name",t.name),t.time&&s.setAttribute("timestamp",t.time),t.avatarSrc&&s.setAttribute("avatar-src",t.avatarSrc),t.avatarInitials&&s.setAttribute("avatar-initials",t.avatarInitials),t.actions&&s.setAttribute("actions",t.actions),t.status&&s.setAttribute("status",t.status),t.variant&&s.setAttribute("variant",t.variant),null!=t.html?s.innerHTML=t.html:s.textContent=t.text||"",s.addEventListener("db-action",t=>this.relay(t,"db-message-action")),e.append(s),t.artifact&&(this.ensureArtifactId(t.artifact),e.append(this.buildArtifactCard(t.artifact))),e}ensureArtifactId(t){return t.id||(t.id=`art-${this.artifactSeq+=1}`),t.id}buildArtifactCard(s){const a=this.ensureArtifactId(s),r=el("button",`${i}__artifact-card`);r.type="button",r.dataset.artifactId=a,r.setAttribute("aria-pressed","false"),r.setAttribute("aria-label",`${s.title} 아티팩트 열기`);const n=el("span",`${i}__artifact-card-icon`),c=s.icon&&e(s.icon)?s.icon:"code";n.append(t(c,18));const l=el("div",`${i}__artifact-card-meta`);l.append(el("div",`${i}__artifact-card-title`,s.title)),s.subtitle&&l.append(el("div",`${i}__artifact-card-subtitle`,s.subtitle));const o=el("span",`${i}__artifact-card-chevron`);return o.append(t("chevron-right",16)),r.append(n,l,o),r.addEventListener("click",()=>this.toggleArtifactFromCard(s)),r}syncArtifactCardStates(){this.querySelectorAll(`.${i}__artifact-card`).forEach(t=>{const e=t,s=this.artifactOpen&&e.dataset.artifactId===this.activeArtifactId;e.classList.toggle(`${i}__artifact-card--active`,s),e.setAttribute("aria-pressed",String(s))})}toggleArtifactFromCard(t){const e=this.ensureArtifactId(t);this.artifactOpen&&this.activeArtifactId===e?this.closeArtifact():this.openArtifact({id:e,title:t.title,subtitle:t.subtitle,html:t.html})}buildTyping(){const t=el("db-chat-typing",`${i}__typing`),e=this.getAttribute("title")||"AI";return t.setAttribute("name",this.getAttribute("agent-name")||e),t.setAttribute("label","생각 중…"),t.setAttribute("avatar-initials","AI"),t}renderDock(){this.dockEl.replaceChildren(),this.dockEl.append(this.composer);const t=this.getAttribute("disclaimer");t&&this.dockEl.append(el("p",`${i}__disclaimer`,t))}relay(t,e){t.stopPropagation(),this.dispatchEvent(new CustomEvent(e,{detail:t.detail,bubbles:!0,composed:!0}))}scrollToEnd(){this.scrollEl.scrollTop=this.scrollEl.scrollHeight}addMessage(t){const e={id:`m${s+=1}`,...t},i=0===this._messages.length;if(this._messages.push(e),i||!this.threadEl)this.renderContent();else{const t=this.threadEl.querySelector("db-chat-typing"),i=this.buildMessage(e);t?this.threadEl.insertBefore(i,t):this.threadEl.append(i),requestAnimationFrame(()=>this.scrollToEnd())}return e.id}updateMessage(t,e){const s=this._messages.find(e=>e.id===t);if(!s)return;Object.assign(s,e);const a=this.threadEl?.querySelector(`db-chat-message[data-id="${t}"]`);if(!a)return;const r=a.querySelector(".designbase-wc-chat-message__content");if(!r||null==e.html&&null==e.text||(null!=e.html?r.innerHTML=e.html:r.textContent=e.text||""),e.status&&a.setAttribute("status",e.status),void 0!==e.artifact){const t=a.closest(`.${i}__turn`)||a.parentElement;t?.querySelector(`.${i}__artifact-card`)?.remove(),e.artifact&&t&&(this.ensureArtifactId(e.artifact),t.append(this.buildArtifactCard(e.artifact)),this.syncArtifactCardStates())}requestAnimationFrame(()=>this.scrollToEnd())}appendToMessage(t,e){const i=this._messages.find(e=>e.id===t);if(!i)return;i.text=(i.text||"")+e;const s=this.threadEl?.querySelector(`db-chat-message[data-id="${t}"]`),a=s?.querySelector(".designbase-wc-chat-message__content");a&&(a.textContent=i.text),requestAnimationFrame(()=>this.scrollToEnd())}setMessages(t){this.messages=t}clear(){this._messages=[],this.typing=!1,this.closeArtifact(),this.built&&this.renderContent()}setTyping(t){if(this.typing=Boolean(t),!this.built||!this.threadEl)return;const e=this.threadEl.querySelector("db-chat-typing");this.typing&&!e?(this.threadEl.append(this.buildTyping()),requestAnimationFrame(()=>this.scrollToEnd())):!this.typing&&e&&e.remove()}setStreaming(t){this.composer?.setStreaming(Boolean(t))}focusInput(){this.composer?.focusInput()}getComposer(){return this.composer}get artifactOpen(){return this.hasAttribute("artifact-open")}set artifactOpen(t){this.toggleAttribute("artifact-open",t)}openArtifact(t={}){null!=t.title&&(this.artifactTitleEl.textContent=t.title),null!=t.subtitle&&(this.artifactSubtitleEl.textContent=t.subtitle,this.artifactSubtitleEl.hidden=!t.subtitle),null!=t.html&&(this.artifactBodyEl.innerHTML=t.html),null!=t.id&&(this.activeArtifactId=t.id);const e=this.artifactOpen;this.artifactOpen=!0,e&&this.syncArtifactCardStates()}closeArtifact(){this.activeArtifactId=null;const t=this.artifactOpen;this.artifactOpen=!1,t||this.syncArtifactCardStates()}toggleArtifact(){this.artifactOpen?this.closeArtifact():this.artifactOpen=!0}getArtifactBody(){return this.artifactBodyEl}setArtifactContent(t){this.artifactBodyEl.replaceChildren(t)}}customElements.get("db-ai-chat")||customElements.define("db-ai-chat",DbAiChat);export{DbAiChat};
@@ -1,149 +1 @@
1
- import './db-button.js';
2
- import { createDbIcon } from './db-icons.js';
3
-
4
- const CLASS = 'designbase-wc-alert';
5
- class DbAlert extends HTMLElement {
6
- static get observedAttributes() {
7
- return [
8
- 'title',
9
- 'message',
10
- 'variant',
11
- 'size',
12
- 'show-icon',
13
- 'closable',
14
- 'action-label',
15
- 'action-variant',
16
- 'action-buttons',
17
- ];
18
- }
19
- connectedCallback() {
20
- this.render();
21
- }
22
- attributeChangedCallback() {
23
- this.render();
24
- }
25
- getIconName(variant) {
26
- if (variant === 'success')
27
- return 'circle-checked';
28
- if (variant === 'warning')
29
- return 'warning-filled';
30
- if (variant === 'danger')
31
- return 'error-filled';
32
- return 'info-filled';
33
- }
34
- parseActionButtons() {
35
- const raw = this.getAttribute('action-buttons');
36
- if (!raw)
37
- return [];
38
- try {
39
- const parsed = JSON.parse(raw);
40
- return Array.isArray(parsed) ? parsed : [];
41
- }
42
- catch {
43
- return [];
44
- }
45
- }
46
- render() {
47
- const variant = this.getAttribute('variant') || 'default';
48
- const size = this.getAttribute('size') || 'm';
49
- const showIcon = this.getAttribute('show-icon') !== 'false';
50
- const closable = this.getAttribute('closable') !== 'false';
51
- const title = this.getAttribute('title')?.trim() || '';
52
- const messageAttr = this.getAttribute('message')?.trim() || '';
53
- const actionLabel = this.getAttribute('action-label');
54
- const actionVariant = this.getAttribute('action-variant') || 'tertiary';
55
- const actionButtons = this.parseActionButtons();
56
- const hasMessage = Boolean(messageAttr);
57
- const hasTitle = Boolean(title);
58
- const isSingleLine = (hasTitle && !hasMessage) || (!hasTitle && hasMessage);
59
- const actions = actionButtons.length > 0
60
- ? actionButtons
61
- : actionLabel
62
- ? [{ label: actionLabel, variant: actionVariant }]
63
- : [];
64
- this.className = [
65
- CLASS,
66
- `${CLASS}--${variant}`,
67
- `${CLASS}--${size}`,
68
- showIcon && `${CLASS}--with-icon`,
69
- closable && `${CLASS}--closable`,
70
- isSingleLine && `${CLASS}--text-single`,
71
- actions.length > 0 && `${CLASS}--has-actions`,
72
- ]
73
- .filter(Boolean)
74
- .join(' ');
75
- this.setAttribute('role', 'alert');
76
- this.setAttribute('aria-live', 'polite');
77
- this.querySelector(`.${CLASS}__content`)?.remove();
78
- this.querySelector(`.${CLASS}__actions`)?.remove();
79
- Array.from(this.childNodes).forEach((node) => {
80
- if (node.nodeType === Node.TEXT_NODE) {
81
- node.remove();
82
- }
83
- });
84
- const content = document.createElement('div');
85
- content.className = `${CLASS}__content`;
86
- if (showIcon) {
87
- const icon = document.createElement('div');
88
- icon.className = `${CLASS}__icon`;
89
- icon.append(createDbIcon(this.getIconName(variant), size === 's' ? 16 : size === 'l' ? 24 : 20));
90
- content.append(icon);
91
- }
92
- const body = document.createElement('div');
93
- body.className = `${CLASS}__body`;
94
- if (hasTitle) {
95
- const heading = document.createElement('div');
96
- heading.className = `${CLASS}__title`;
97
- heading.textContent = title;
98
- body.append(heading);
99
- }
100
- if (hasMessage) {
101
- const text = document.createElement('div');
102
- text.className = `${CLASS}__message`;
103
- text.textContent = messageAttr;
104
- body.append(text);
105
- }
106
- content.append(body);
107
- if (actions.length > 0) {
108
- const actionsEl = document.createElement('div');
109
- actionsEl.className = `${CLASS}__actions`;
110
- const buttonsWrap = document.createElement('div');
111
- buttonsWrap.className = `${CLASS}__action-buttons`;
112
- actions.forEach((action, index) => {
113
- const button = document.createElement('db-button');
114
- button.setAttribute('variant', action.variant || 'tertiary');
115
- button.setAttribute('size', action.size || size);
116
- button.textContent = action.label;
117
- if (action.disabled)
118
- button.setAttribute('disabled', '');
119
- button.addEventListener('db-click', () => {
120
- this.dispatchEvent(new CustomEvent('db-action', {
121
- bubbles: true,
122
- composed: true,
123
- detail: { index, label: action.label },
124
- }));
125
- });
126
- buttonsWrap.append(button);
127
- });
128
- actionsEl.append(buttonsWrap);
129
- content.append(actionsEl);
130
- }
131
- if (closable) {
132
- const close = document.createElement('button');
133
- close.type = 'button';
134
- close.className = `${CLASS}__close`;
135
- close.setAttribute('aria-label', '알림 닫기');
136
- close.append(createDbIcon('close', 20));
137
- close.addEventListener('click', () => {
138
- this.hidden = true;
139
- this.dispatchEvent(new CustomEvent('db-close', { bubbles: true, composed: true }));
140
- });
141
- content.append(close);
142
- }
143
- this.replaceChildren(content);
144
- }
145
- }
146
- if (!customElements.get('db-alert'))
147
- customElements.define('db-alert', DbAlert);
148
-
149
- export { DbAlert };
1
+ import"./db-button.js";import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-alert";class DbAlert extends HTMLElement{static get observedAttributes(){return["title","message","variant","size","show-icon","closable","action-label","action-variant","action-buttons"]}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}getIconName(t){return"success"===t?"circle-checked":"warning"===t?"warning-filled":"danger"===t?"error-filled":"info-filled"}parseActionButtons(){const t=this.getAttribute("action-buttons");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}render(){const n=this.getAttribute("variant")||"default",s=this.getAttribute("size")||"m",a="false"!==this.getAttribute("show-icon"),i="false"!==this.getAttribute("closable"),r=this.getAttribute("title")?.trim()||"",o=this.getAttribute("message")?.trim()||"",c=this.getAttribute("action-label"),l=this.getAttribute("action-variant")||"tertiary",d=this.parseActionButtons(),b=Boolean(o),m=Boolean(r),u=m&&!b||!m&&b,h=d.length>0?d:c?[{label:c,variant:l}]:[];this.className=[e,`${e}--${n}`,`${e}--${s}`,a&&`${e}--with-icon`,i&&`${e}--closable`,u&&`${e}--text-single`,h.length>0&&`${e}--has-actions`].filter(Boolean).join(" "),this.setAttribute("role","alert"),this.setAttribute("aria-live","polite"),this.querySelector(`.${e}__content`)?.remove(),this.querySelector(`.${e}__actions`)?.remove(),Array.from(this.childNodes).forEach(t=>{t.nodeType===Node.TEXT_NODE&&t.remove()});const p=document.createElement("div");if(p.className=`${e}__content`,a){const a=document.createElement("div");a.className=`${e}__icon`,a.append(t(this.getIconName(n),"s"===s?16:"l"===s?24:20)),p.append(a)}const g=document.createElement("div");if(g.className=`${e}__body`,m){const t=document.createElement("div");t.className=`${e}__title`,t.textContent=r,g.append(t)}if(b){const t=document.createElement("div");t.className=`${e}__message`,t.textContent=o,g.append(t)}if(p.append(g),h.length>0){const t=document.createElement("div");t.className=`${e}__actions`;const n=document.createElement("div");n.className=`${e}__action-buttons`,h.forEach((t,e)=>{const a=document.createElement("db-button");a.setAttribute("variant",t.variant||"tertiary"),a.setAttribute("size",t.size||s),a.textContent=t.label,t.disabled&&a.setAttribute("disabled",""),a.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-action",{bubbles:!0,composed:!0,detail:{index:e,label:t.label}}))}),n.append(a)}),t.append(n),p.append(t)}if(i){const n=document.createElement("button");n.type="button",n.className=`${e}__close`,n.setAttribute("aria-label","알림 닫기"),n.append(t("close",20)),n.addEventListener("click",()=>{this.hidden=!0,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}),p.append(n)}this.replaceChildren(p)}}customElements.get("db-alert")||customElements.define("db-alert",DbAlert);export{DbAlert};