@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.
- package/dist/chunks/lottie-35a9b0f5.js +1 -0
- package/dist/esm/components/animation-background/canvas-controller.js +1 -121
- package/dist/esm/components/animation-background/controls.js +1 -180
- package/dist/esm/components/animation-background/graphite-controller.js +1 -196
- package/dist/esm/components/animation-background/graphite-presets.js +1 -42
- package/dist/esm/components/animation-background/graphite-shader.js +1 -111
- package/dist/esm/components/animation-background/layers.js +1 -369
- package/dist/esm/components/animation-background/lumina-presets.js +1 -53
- package/dist/esm/components/animation-background/lumina-shaders.js +1 -181
- package/dist/esm/components/animation-background/lumina-utils.js +1 -60
- package/dist/esm/components/animation-background/particle-defaults.js +1 -36
- package/dist/esm/components/animation-background/renderers.js +1 -167
- package/dist/esm/components/animation-background/shader-controller.js +1 -154
- package/dist/esm/components/color-picker-utils.js +1 -134
- package/dist/esm/components/date-picker-utils.js +1 -140
- package/dist/esm/components/db-accordion.js +1 -304
- package/dist/esm/components/db-ad-banner.js +1 -455
- package/dist/esm/components/db-ai-chat-list.d.ts +43 -0
- package/dist/esm/components/db-ai-chat-list.js +1 -0
- package/dist/esm/components/db-ai-chat.d.ts +159 -0
- package/dist/esm/components/db-ai-chat.js +1 -0
- package/dist/esm/components/db-alert.js +1 -149
- package/dist/esm/components/db-animation-background.js +1 -486
- package/dist/esm/components/db-animation-text.js +1 -601
- package/dist/esm/components/db-app-badge.js +1 -88
- package/dist/esm/components/db-audio-player.js +1 -752
- package/dist/esm/components/db-avatar.js +1 -188
- package/dist/esm/components/db-backdrop.js +1 -139
- package/dist/esm/components/db-badge.js +1 -91
- package/dist/esm/components/db-banner.js +1 -188
- package/dist/esm/components/db-bottom-navigation.js +1 -146
- package/dist/esm/components/db-bottom-sheet.js +1 -481
- package/dist/esm/components/db-breadcrumbs.js +1 -329
- package/dist/esm/components/db-button.js +1 -316
- package/dist/esm/components/db-calendar.js +1 -675
- package/dist/esm/components/db-card.js +1 -265
- package/dist/esm/components/db-carousel.js +1 -264
- package/dist/esm/components/db-chat-composer.d.ts +134 -0
- package/dist/esm/components/db-chat-composer.js +1 -0
- package/dist/esm/components/db-chat-list.d.ts +47 -0
- package/dist/esm/components/db-chat-list.js +1 -0
- package/dist/esm/components/db-chat-message.d.ts +39 -0
- package/dist/esm/components/db-chat-message.js +1 -0
- package/dist/esm/components/db-chat-orb.d.ts +99 -0
- package/dist/esm/components/db-chat-orb.js +1 -0
- package/dist/esm/components/db-chat-room.d.ts +71 -0
- package/dist/esm/components/db-chat-room.js +1 -0
- package/dist/esm/components/db-chat-suggestions.d.ts +44 -0
- package/dist/esm/components/db-chat-suggestions.js +1 -0
- package/dist/esm/components/db-chat-typing.d.ts +22 -0
- package/dist/esm/components/db-chat-typing.js +1 -0
- package/dist/esm/components/db-chat-welcome.d.ts +32 -0
- package/dist/esm/components/db-chat-welcome.js +1 -0
- package/dist/esm/components/db-chat-widget.d.ts +146 -0
- package/dist/esm/components/db-chat-widget.js +1 -0
- package/dist/esm/components/db-checkbox.js +1 -202
- package/dist/esm/components/db-chip.js +1 -104
- package/dist/esm/components/db-code-block.js +1 -304
- package/dist/esm/components/db-color-picker.js +1 -746
- package/dist/esm/components/db-confirm.js +1 -191
- package/dist/esm/components/db-container.js +1 -39
- package/dist/esm/components/db-context-menu.js +1 -265
- package/dist/esm/components/db-countdown.js +1 -146
- package/dist/esm/components/db-cursor-follower.js +1 -173
- package/dist/esm/components/db-date-picker.js +1 -837
- package/dist/esm/components/db-divider.js +1 -66
- package/dist/esm/components/db-download-progress.d.ts +89 -0
- package/dist/esm/components/db-download-progress.js +1 -0
- package/dist/esm/components/db-drawer.js +1 -245
- package/dist/esm/components/db-dropdown.js +1 -493
- package/dist/esm/components/db-dropzone.js +1 -266
- package/dist/esm/components/db-email-verify.d.ts +64 -0
- package/dist/esm/components/db-email-verify.js +1 -0
- package/dist/esm/components/db-empty-state.js +1 -97
- package/dist/esm/components/db-file-uploader.js +1 -256
- package/dist/esm/components/db-floating-action-button.js +1 -139
- package/dist/esm/components/db-footer.js +1 -385
- package/dist/esm/components/db-form.js +1 -566
- package/dist/esm/components/db-gantt.js +1 -882
- package/dist/esm/components/db-gradient.js +1 -133
- package/dist/esm/components/db-grid-background.js +1 -909
- package/dist/esm/components/db-grid.js +1 -73
- package/dist/esm/components/db-icons.d.ts +3 -0
- package/dist/esm/components/db-icons.js +1 -82
- package/dist/esm/components/db-image-list.js +1 -214
- package/dist/esm/components/db-image-placeholder.js +1 -96
- package/dist/esm/components/db-image.js +1 -289
- package/dist/esm/components/db-indicator.js +1 -517
- package/dist/esm/components/db-input.js +1 -420
- package/dist/esm/components/db-kanban.js +1 -538
- package/dist/esm/components/db-label.js +1 -66
- package/dist/esm/components/db-lightbox.js +1 -372
- package/dist/esm/components/db-list.js +1 -340
- package/dist/esm/components/db-logo-svg.js +1 -72
- package/dist/esm/components/db-logo.js +1 -106
- package/dist/esm/components/db-lottie.js +1 -109
- package/dist/esm/components/db-markdown-editor.js +1 -458
- package/dist/esm/components/db-marquee.js +1 -402
- package/dist/esm/components/db-masonry.js +1 -94
- package/dist/esm/components/db-menu-item.js +1 -211
- package/dist/esm/components/db-modal.js +1 -522
- package/dist/esm/components/db-navbar.js +1 -680
- package/dist/esm/components/db-onboarding-modal.js +1 -322
- package/dist/esm/components/db-otp-input.d.ts +53 -0
- package/dist/esm/components/db-otp-input.js +1 -0
- package/dist/esm/components/db-page-header.js +1 -312
- package/dist/esm/components/db-pagination.js +1 -271
- package/dist/esm/components/db-phone-verify.d.ts +63 -0
- package/dist/esm/components/db-phone-verify.js +1 -0
- package/dist/esm/components/db-popover.js +1 -580
- package/dist/esm/components/db-progress-step.js +1 -166
- package/dist/esm/components/db-progress.js +1 -171
- package/dist/esm/components/db-progressbar.js +1 -72
- package/dist/esm/components/db-radio.js +1 -172
- package/dist/esm/components/db-random-gradient.js +1 -121
- package/dist/esm/components/db-range-slider.js +1 -811
- package/dist/esm/components/db-rating.js +1 -325
- package/dist/esm/components/db-reorder.js +1 -286
- package/dist/esm/components/db-resizable-panels.js +1 -282
- package/dist/esm/components/db-scroll-area.js +1 -126
- package/dist/esm/components/db-search-bar.js +1 -668
- package/dist/esm/components/db-section-app-download.js +1 -101
- package/dist/esm/components/db-section-contact.js +1 -102
- package/dist/esm/components/db-section-cta.js +1 -150
- package/dist/esm/components/db-section-faq.js +1 -120
- package/dist/esm/components/db-section-feature-grid.js +1 -137
- package/dist/esm/components/db-section-feature.js +1 -179
- package/dist/esm/components/db-section-hero.js +1 -243
- package/dist/esm/components/db-section-logo-cloud.js +1 -138
- package/dist/esm/components/db-section-pricing.js +1 -166
- package/dist/esm/components/db-section-stats.js +1 -129
- package/dist/esm/components/db-section-testimonials.js +1 -252
- package/dist/esm/components/db-section.js +1 -385
- package/dist/esm/components/db-segment-control.js +1 -231
- package/dist/esm/components/db-select.js +1 -571
- package/dist/esm/components/db-share-icons.js +1 -40
- package/dist/esm/components/db-share.js +1 -489
- package/dist/esm/components/db-sidebar.d.ts +20 -0
- package/dist/esm/components/db-sidebar.js +1 -1068
- package/dist/esm/components/db-skeleton.js +1 -94
- package/dist/esm/components/db-spinner.js +1 -102
- package/dist/esm/components/db-split-view.js +1 -297
- package/dist/esm/components/db-stack.js +1 -46
- package/dist/esm/components/db-stat.js +1 -218
- package/dist/esm/components/db-stepper.js +1 -398
- package/dist/esm/components/db-table.js +1 -412
- package/dist/esm/components/db-tabs.js +1 -335
- package/dist/esm/components/db-testimonial.d.ts +2 -0
- package/dist/esm/components/db-testimonial.js +1 -162
- package/dist/esm/components/db-textarea.js +1 -233
- package/dist/esm/components/db-time-picker.js +1 -523
- package/dist/esm/components/db-timeline.js +1 -174
- package/dist/esm/components/db-toast.js +1 -158
- package/dist/esm/components/db-toggle.js +1 -162
- package/dist/esm/components/db-toolbar.js +1 -94
- package/dist/esm/components/db-tooltip.js +1 -440
- package/dist/esm/components/db-top-banner.js +1 -121
- package/dist/esm/components/db-tutorial.js +1 -324
- package/dist/esm/components/db-two-factor.d.ts +71 -0
- package/dist/esm/components/db-two-factor.js +1 -0
- package/dist/esm/components/db-video-player.js +1 -503
- package/dist/esm/components/db-youtube-player.js +1 -194
- package/dist/esm/components/highlight-code.js +1 -65
- package/dist/esm/components/input-validation.js +1 -50
- package/dist/esm/components/marketing-block-host-utils.js +1 -9
- package/dist/esm/components/number-scrub.js +1 -117
- package/dist/esm/components/random-gradient-palettes.js +1 -67
- package/dist/esm/components/section-block-header-utils.js +1 -48
- package/dist/esm/helpers/confirm.js +1 -52
- package/dist/esm/helpers/toast.js +1 -73
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +1 -111
- package/dist/esm/node_modules/prismjs/components/prism-bash.js +1 -235
- package/dist/esm/node_modules/prismjs/components/prism-clike.js +1 -31
- package/dist/esm/node_modules/prismjs/components/prism-css.js +1 -64
- package/dist/esm/node_modules/prismjs/components/prism-javascript.js +1 -172
- package/dist/esm/node_modules/prismjs/components/prism-json.js +1 -27
- package/dist/esm/node_modules/prismjs/components/prism-jsx.js +1 -143
- package/dist/esm/node_modules/prismjs/components/prism-markup.js +1 -186
- package/dist/esm/node_modules/prismjs/components/prism-scss.js +1 -81
- package/dist/esm/node_modules/prismjs/components/prism-tsx.js +1 -15
- package/dist/esm/node_modules/prismjs/components/prism-typescript.js +1 -60
- package/dist/index.cjs +1 -55414
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1125 -2
- package/dist/index.esm.js +1 -38284
- package/dist/react/chunks/lottie-14e7addb.js +1 -0
- package/dist/react/index.cjs +1 -56503
- package/dist/react/index.d.ts +1637 -21
- package/dist/react/index.esm.js +1 -39373
- package/package.json +2 -2
- package/dist/chunks/lottie-e273b936.js +0 -17032
- 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
|
|
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};
|