@iyulab/chat-components 0.4.0 → 0.5.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 (237) hide show
  1. package/CHANGELOG.md +124 -21
  2. package/README.md +133 -16
  3. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
  5. package/dist/_virtual/_glob-assets_raw/intent-prompt.md.1907474e.js +4 -0
  6. package/dist/_virtual/_glob-assets_raw/view-prompt.md.e0dbcffe.js +4 -0
  7. package/dist/components/blocks/UCodeBlock.d.ts +24 -2
  8. package/dist/components/blocks/UCodeBlock.js +65 -2
  9. package/dist/components/blocks/UCodeBlock.styles.js +4 -4
  10. package/dist/components/blocks/UFileBlock.d.ts +33 -0
  11. package/dist/components/blocks/UFileBlock.js +154 -0
  12. package/dist/components/blocks/{UFilesBlock.styles.js → UFileBlock.styles.js} +12 -90
  13. package/dist/components/blocks/UJsonBlock.d.ts +44 -2
  14. package/dist/components/blocks/UJsonBlock.js +128 -3
  15. package/dist/components/blocks/UJsonBlock.styles.js +4 -4
  16. package/dist/components/blocks/UMarkedBlock.d.ts +44 -2
  17. package/dist/components/blocks/UMarkedBlock.js +154 -4
  18. package/dist/components/blocks/UMarkedBlock.styles.js +4 -4
  19. package/dist/components/blocks/URefBlock.d.ts +16 -2
  20. package/dist/components/blocks/URefBlock.js +58 -3
  21. package/dist/components/blocks/URefBlock.styles.js +4 -4
  22. package/dist/components/blocks/UTableBlock.d.ts +47 -2
  23. package/dist/components/blocks/UTableBlock.js +197 -4
  24. package/dist/components/blocks/UTableBlock.styles.js +4 -5
  25. package/dist/components/blocks/UTextBlock.d.ts +36 -2
  26. package/dist/components/blocks/UTextBlock.js +94 -4
  27. package/dist/components/blocks/UTextBlock.styles.js +4 -4
  28. package/dist/components/blocks/UThinkBlock.d.ts +30 -2
  29. package/dist/components/blocks/UThinkBlock.js +86 -4
  30. package/dist/components/blocks/UThinkBlock.styles.js +4 -4
  31. package/dist/components/blocks/UToolBlock.d.ts +19 -2
  32. package/dist/components/blocks/UToolBlock.js +68 -3
  33. package/dist/components/blocks/UToolBlock.styles.js +4 -4
  34. package/dist/components/buttons/UAttachButton.d.ts +21 -2
  35. package/dist/components/buttons/UAttachButton.js +61 -3
  36. package/dist/components/buttons/UAttachButton.styles.js +4 -4
  37. package/dist/components/buttons/UCopyButton.d.ts +19 -2
  38. package/dist/components/buttons/UCopyButton.js +57 -3
  39. package/dist/components/buttons/UCopyButton.styles.js +4 -4
  40. package/dist/components/buttons/UVoteButton.d.ts +14 -3
  41. package/dist/components/buttons/UVoteButton.js +62 -3
  42. package/dist/components/buttons/UVoteButton.styles.js +4 -4
  43. package/dist/components/{actions/UQuestionAction.component.d.ts → intents/UQuestionIntent.d.ts} +6 -2
  44. package/dist/components/intents/UQuestionIntent.js +41 -0
  45. package/dist/components/{actions/UQuestionAction.styles.js → intents/UQuestionIntent.styles.js} +4 -6
  46. package/dist/components/message/UMessage.d.ts +18 -2
  47. package/dist/components/message/UMessage.js +47 -2
  48. package/dist/components/message/UMessage.styles.js +4 -4
  49. package/dist/components/prompt/UPrompt.d.ts +32 -2
  50. package/dist/components/prompt/UPrompt.js +118 -2
  51. package/dist/components/prompt/UPrompt.styles.js +15 -5
  52. package/dist/components/references/URefCard.d.ts +30 -2
  53. package/dist/components/references/URefCard.js +97 -2
  54. package/dist/components/references/URefCard.styles.js +4 -4
  55. package/dist/components/references/URefCardGroup.d.ts +25 -2
  56. package/dist/components/references/URefCardGroup.js +69 -4
  57. package/dist/components/references/URefCardGroup.styles.js +4 -4
  58. package/dist/components/references/URefTag.d.ts +12 -2
  59. package/dist/components/references/URefTag.js +37 -2
  60. package/dist/components/references/URefTag.styles.js +4 -4
  61. package/dist/components/{widgets/UChartWidget.component.d.ts → views/UChartView.d.ts} +7 -4
  62. package/dist/components/views/UChartView.js +167 -0
  63. package/dist/components/{widgets/UChartWidget.styles.js → views/UChartView.styles.js} +4 -4
  64. package/dist/components/{widgets/UImagesWidget.component.d.ts → views/UImagesView.d.ts} +7 -4
  65. package/dist/components/views/UImagesView.js +144 -0
  66. package/dist/components/{widgets/UImagesWidget.styles.js → views/UImagesView.styles.js} +6 -5
  67. package/dist/components/{widgets/UMapWidget.component.d.ts → views/UMapView.d.ts} +7 -3
  68. package/dist/components/views/UMapView.js +45 -0
  69. package/dist/components/{widgets/UMapWidget.styles.js → views/UMapView.styles.js} +4 -4
  70. package/dist/components/{widgets/UVideoWidget.component.d.ts → views/UVideoView.d.ts} +7 -3
  71. package/dist/components/views/UVideoView.js +81 -0
  72. package/dist/components/{widgets/UVideoWidget.styles.js → views/UVideoView.styles.js} +4 -4
  73. package/dist/components/{widgets/UWidget.component.d.ts → views/UView.d.ts} +8 -5
  74. package/dist/components/views/UView.js +113 -0
  75. package/dist/components/{widgets/UWidget.styles.js → views/UView.styles.js} +4 -4
  76. package/dist/events/AttachEvent.d.ts +9 -0
  77. package/dist/events/ChoiceEvent.d.ts +9 -0
  78. package/dist/events/SendEvent.d.ts +7 -0
  79. package/dist/events/StopEvent.d.ts +7 -0
  80. package/dist/index.d.ts +13 -16
  81. package/dist/index.js +28 -56
  82. package/dist/react/UAttachButton.d.ts +11 -0
  83. package/dist/react/UAttachButton.js +12 -0
  84. package/dist/react/UChartView.d.ts +9 -0
  85. package/dist/react/UChartView.js +10 -0
  86. package/dist/react/UCodeBlock.d.ts +9 -0
  87. package/dist/react/UCodeBlock.js +10 -0
  88. package/dist/react/UCopyButton.d.ts +9 -0
  89. package/dist/react/UCopyButton.js +10 -0
  90. package/dist/react/UFileBlock.d.ts +11 -0
  91. package/dist/react/UFileBlock.js +12 -0
  92. package/dist/react/UImagesView.d.ts +9 -0
  93. package/dist/react/UImagesView.js +10 -0
  94. package/dist/react/UJsonBlock.d.ts +9 -0
  95. package/dist/react/UJsonBlock.js +10 -0
  96. package/dist/react/UMapView.d.ts +9 -0
  97. package/dist/react/UMapView.js +10 -0
  98. package/dist/react/UMarkedBlock.d.ts +9 -0
  99. package/dist/react/UMarkedBlock.js +10 -0
  100. package/dist/react/UMessage.d.ts +9 -0
  101. package/dist/react/UMessage.js +10 -0
  102. package/dist/react/UPrompt.d.ts +13 -0
  103. package/dist/react/UPrompt.js +13 -0
  104. package/dist/react/UQuestionIntent.d.ts +11 -0
  105. package/dist/react/UQuestionIntent.js +12 -0
  106. package/dist/react/URefBlock.d.ts +9 -0
  107. package/dist/react/URefBlock.js +10 -0
  108. package/dist/react/URefCard.d.ts +9 -0
  109. package/dist/react/URefCard.js +10 -0
  110. package/dist/react/URefCardGroup.d.ts +9 -0
  111. package/dist/react/URefCardGroup.js +10 -0
  112. package/dist/react/URefTag.d.ts +9 -0
  113. package/dist/react/URefTag.js +10 -0
  114. package/dist/react/UTableBlock.d.ts +9 -0
  115. package/dist/react/UTableBlock.js +10 -0
  116. package/dist/react/UTextBlock.d.ts +9 -0
  117. package/dist/react/UTextBlock.js +10 -0
  118. package/dist/react/UThinkBlock.d.ts +9 -0
  119. package/dist/react/UThinkBlock.js +10 -0
  120. package/dist/react/UToolBlock.d.ts +9 -0
  121. package/dist/react/UToolBlock.js +10 -0
  122. package/dist/react/UVideoView.d.ts +9 -0
  123. package/dist/react/UVideoView.js +10 -0
  124. package/dist/react/UView.d.ts +9 -0
  125. package/dist/react/UView.js +10 -0
  126. package/dist/react/UVoteButton.d.ts +9 -0
  127. package/dist/react/UVoteButton.js +10 -0
  128. package/dist/react/index.d.ts +23 -0
  129. package/dist/react/index.js +23 -0
  130. package/dist/types/BlockItem.d.ts +21 -32
  131. package/dist/types/Intents.d.ts +26 -0
  132. package/dist/types/Intents.js +30 -0
  133. package/dist/types/{Widgets.d.ts → Views.d.ts} +8 -8
  134. package/dist/types/Views.js +150 -0
  135. package/dist/utilities/IntentPromptBuilder.d.ts +40 -0
  136. package/dist/utilities/IntentPromptBuilder.js +95 -0
  137. package/dist/utilities/ViewPromptBuilder.d.ts +28 -0
  138. package/dist/utilities/ViewPromptBuilder.js +76 -0
  139. package/dist/utilities/dom-agent/DOMAgent.d.ts +74 -0
  140. package/dist/utilities/dom-agent/DOMController.d.ts +78 -0
  141. package/dist/utilities/dom-agent/DOMPromptBuilder.d.ts +54 -0
  142. package/dist/utilities/dom-agent/DOMScanner.d.ts +83 -0
  143. package/dist/utilities/dom-agent/index.d.ts +9 -0
  144. package/dist/utilities/dom-agent/types.d.ts +209 -0
  145. package/package.json +32 -16
  146. package/dist/assets/action-prompt.md.js +0 -3
  147. package/dist/assets/widget-prompt.md.js +0 -3
  148. package/dist/components/actions/UQuestionAction.component.js +0 -58
  149. package/dist/components/actions/UQuestionAction.d.ts +0 -7
  150. package/dist/components/actions/UQuestionAction.js +0 -5
  151. package/dist/components/blocks/UCodeBlock.component.d.ts +0 -25
  152. package/dist/components/blocks/UCodeBlock.component.js +0 -88
  153. package/dist/components/blocks/UFilesBlock.component.d.ts +0 -22
  154. package/dist/components/blocks/UFilesBlock.component.js +0 -192
  155. package/dist/components/blocks/UFilesBlock.d.ts +0 -7
  156. package/dist/components/blocks/UFilesBlock.js +0 -5
  157. package/dist/components/blocks/UJsonBlock.component.d.ts +0 -45
  158. package/dist/components/blocks/UJsonBlock.component.js +0 -140
  159. package/dist/components/blocks/UMarkedBlock.component.d.ts +0 -40
  160. package/dist/components/blocks/UMarkedBlock.component.js +0 -159
  161. package/dist/components/blocks/URefBlock.component.d.ts +0 -17
  162. package/dist/components/blocks/URefBlock.component.js +0 -73
  163. package/dist/components/blocks/UTableBlock.component.d.ts +0 -49
  164. package/dist/components/blocks/UTableBlock.component.js +0 -228
  165. package/dist/components/blocks/UTextBlock.component.d.ts +0 -37
  166. package/dist/components/blocks/UTextBlock.component.js +0 -123
  167. package/dist/components/blocks/UThinkBlock.component.d.ts +0 -23
  168. package/dist/components/blocks/UThinkBlock.component.js +0 -90
  169. package/dist/components/blocks/UToolBlock.component.d.ts +0 -20
  170. package/dist/components/blocks/UToolBlock.component.js +0 -80
  171. package/dist/components/buttons/UAttachButton.component.d.ts +0 -22
  172. package/dist/components/buttons/UAttachButton.component.js +0 -89
  173. package/dist/components/buttons/UCopyButton.component.d.ts +0 -20
  174. package/dist/components/buttons/UCopyButton.component.js +0 -81
  175. package/dist/components/buttons/UReportButton.component.d.ts +0 -9
  176. package/dist/components/buttons/UReportButton.component.js +0 -36
  177. package/dist/components/buttons/UReportButton.d.ts +0 -7
  178. package/dist/components/buttons/UReportButton.js +0 -5
  179. package/dist/components/buttons/UReportButton.styles.js +0 -14
  180. package/dist/components/buttons/URetryButton.component.d.ts +0 -11
  181. package/dist/components/buttons/URetryButton.component.js +0 -53
  182. package/dist/components/buttons/URetryButton.d.ts +0 -7
  183. package/dist/components/buttons/URetryButton.js +0 -5
  184. package/dist/components/buttons/URetryButton.styles.js +0 -26
  185. package/dist/components/buttons/UShareButton.component.d.ts +0 -9
  186. package/dist/components/buttons/UShareButton.component.js +0 -36
  187. package/dist/components/buttons/UShareButton.d.ts +0 -7
  188. package/dist/components/buttons/UShareButton.js +0 -5
  189. package/dist/components/buttons/UShareButton.styles.js +0 -14
  190. package/dist/components/buttons/UVoteButton.component.d.ts +0 -15
  191. package/dist/components/buttons/UVoteButton.component.js +0 -73
  192. package/dist/components/message/UMessage.component.d.ts +0 -19
  193. package/dist/components/message/UMessage.component.js +0 -56
  194. package/dist/components/prompt/UPrompt.component.d.ts +0 -25
  195. package/dist/components/prompt/UPrompt.component.js +0 -113
  196. package/dist/components/references/URefCard.component.d.ts +0 -27
  197. package/dist/components/references/URefCard.component.js +0 -109
  198. package/dist/components/references/URefCardGroup.component.d.ts +0 -26
  199. package/dist/components/references/URefCardGroup.component.js +0 -88
  200. package/dist/components/references/URefTag.component.d.ts +0 -13
  201. package/dist/components/references/URefTag.component.js +0 -54
  202. package/dist/components/widgets/UChartWidget.component.js +0 -180
  203. package/dist/components/widgets/UChartWidget.d.ts +0 -7
  204. package/dist/components/widgets/UChartWidget.js +0 -5
  205. package/dist/components/widgets/UImagesWidget.component.js +0 -164
  206. package/dist/components/widgets/UImagesWidget.d.ts +0 -7
  207. package/dist/components/widgets/UImagesWidget.js +0 -5
  208. package/dist/components/widgets/UMapWidget.component.js +0 -65
  209. package/dist/components/widgets/UMapWidget.d.ts +0 -7
  210. package/dist/components/widgets/UMapWidget.js +0 -5
  211. package/dist/components/widgets/UMapWidget.styles.d.ts +0 -1
  212. package/dist/components/widgets/UVideoWidget.component.js +0 -106
  213. package/dist/components/widgets/UVideoWidget.d.ts +0 -7
  214. package/dist/components/widgets/UVideoWidget.js +0 -5
  215. package/dist/components/widgets/UVideoWidget.styles.d.ts +0 -1
  216. package/dist/components/widgets/UWidget.component.js +0 -140
  217. package/dist/components/widgets/UWidget.d.ts +0 -7
  218. package/dist/components/widgets/UWidget.js +0 -5
  219. package/dist/components/widgets/UWidget.styles.d.ts +0 -1
  220. package/dist/events/UCancelEvent.d.ts +0 -6
  221. package/dist/events/USubmitEvent.d.ts +0 -6
  222. package/dist/types/Actions.d.ts +0 -24
  223. package/dist/types/Actions.js +0 -34
  224. package/dist/types/Widgets.js +0 -115
  225. package/dist/utilities/ActionPromptBuilder.d.ts +0 -40
  226. package/dist/utilities/ActionPromptBuilder.js +0 -93
  227. package/dist/utilities/WidgetPromptBuilder.d.ts +0 -28
  228. package/dist/utilities/WidgetPromptBuilder.js +0 -87
  229. package/dist/utilities/converters.d.ts +0 -9
  230. package/dist/utilities/converters.js +0 -19
  231. /package/dist/components/{actions/UQuestionAction.styles.d.ts → blocks/UFileBlock.styles.d.ts} +0 -0
  232. /package/dist/components/{blocks/UFilesBlock.styles.d.ts → intents/UQuestionIntent.styles.d.ts} +0 -0
  233. /package/dist/components/{buttons/UReportButton.styles.d.ts → views/UChartView.styles.d.ts} +0 -0
  234. /package/dist/components/{buttons/URetryButton.styles.d.ts → views/UImagesView.styles.d.ts} +0 -0
  235. /package/dist/components/{buttons/UShareButton.styles.d.ts → views/UMapView.styles.d.ts} +0 -0
  236. /package/dist/components/{widgets/UChartWidget.styles.d.ts → views/UVideoView.styles.d.ts} +0 -0
  237. /package/dist/components/{widgets/UImagesWidget.styles.d.ts → views/UView.styles.d.ts} +0 -0
@@ -1,5 +1,155 @@
1
- import { UMarkedBlock } from './UMarkedBlock.component.js';
2
-
3
- UMarkedBlock.define("u-marked-block");
4
-
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js";
3
+ import "./UCodeBlock.js";
4
+ import "../references/URefTag.js";
5
+ import { URefCard } from "../references/URefCard.js";
6
+ import "../references/URefCardGroup.js";
7
+ import { UTableBlock } from "./UTableBlock.js";
8
+ import { UView } from "../views/UView.js";
9
+ import { styles } from "./UMarkedBlock.styles.js";
10
+ import { nothing } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
13
+ import { UElement } from "@iyulab/components/dist/components/UElement.js";
14
+ import { Marked, Parser } from "marked";
15
+ import markedKatex from "marked-katex-extension";
16
+ import { escapeHtmlText, stripZeroWidth } from "@iyulab/components/dist/utilities/sanitizers.js";
17
+ import { buildElementHTML } from "@iyulab/components/dist/utilities/elements.js";
18
+ //#region src/components/blocks/UMarkedBlock.ts
19
+ var UMarkedBlock = class UMarkedBlock extends UElement {
20
+ constructor(..._args) {
21
+ super(..._args);
22
+ this.parser = new Marked({
23
+ pedantic: false,
24
+ gfm: true,
25
+ breaks: true,
26
+ silent: true,
27
+ renderer: {
28
+ code: (token) => this.renderCode(token),
29
+ table: (token) => this.renderTable(token)
30
+ }
31
+ }).use(markedKatex({ output: "mathml" }));
32
+ this.placeholder = new HtmlPlaceholder();
33
+ this.queued = false;
34
+ }
35
+ static {
36
+ this.styles = [super.styles, styles];
37
+ }
38
+ disconnectedCallback() {
39
+ clearTimeout(this.timer);
40
+ super.disconnectedCallback();
41
+ }
42
+ shouldUpdate(_changedProperties) {
43
+ if (this.queued) return false;
44
+ return true;
45
+ }
46
+ willUpdate(changedProperties) {
47
+ super.willUpdate(changedProperties);
48
+ if (changedProperties.has("value")) {
49
+ if (this.queued) return;
50
+ this.queued = true;
51
+ this.timer = window.setTimeout(() => {
52
+ this.queued = false;
53
+ this.requestUpdate();
54
+ }, 80);
55
+ }
56
+ }
57
+ render() {
58
+ let value = this.value;
59
+ if (!value) return nothing;
60
+ this.placeholder.reset();
61
+ value = stripZeroWidth(value);
62
+ if (this.refs?.length) value = this.insertRefs(value, this.refs);
63
+ let html = this.parser.parse(value, { async: false });
64
+ return unsafeHTML(this.placeholder.restore(html));
65
+ }
66
+ /**
67
+ * 코드블록은 별도의 컴포넌트로 렌더링 합니다.
68
+ */
69
+ renderCode(token) {
70
+ const lang = token.lang ?? "plaintext";
71
+ const trimmed = token.raw.trimEnd();
72
+ const isClosed = trimmed.endsWith("```") || trimmed.endsWith("~~~");
73
+ if (lang === "view-json") return UView.buildHTML(token.text, { loading: !isClosed });
74
+ if (lang === "intent-json") return "";
75
+ const safeText = this.removeRefs(token.text);
76
+ return buildElementHTML("u-code-block", {
77
+ lang,
78
+ loading: !isClosed
79
+ }, safeText);
80
+ }
81
+ /**
82
+ * 테이블은 JSON 데이터로 변환하여 별도의 컴포넌트로 렌더링합니다.
83
+ * 셀 내부의 인라인 마크다운(볼드, 코드, br 등)도 HTML로 변환합니다.
84
+ */
85
+ renderTable(token) {
86
+ const headers = token.header.map((h) => ({
87
+ text: h.tokens ? Parser.parseInline(h.tokens) : h.text,
88
+ align: h.align
89
+ }));
90
+ const rows = token.rows.map((row) => row.map((cell) => ({
91
+ text: cell.tokens ? Parser.parseInline(cell.tokens) : cell.text,
92
+ align: cell.align
93
+ })));
94
+ return UTableBlock.buildHTML({
95
+ headers,
96
+ rows
97
+ });
98
+ }
99
+ /**
100
+ * 인용/출처 참조객체가 있을때 ref 태그 HTML을 this.placeholder에 보관하고
101
+ * 마크다운 문자열의 해당 위치에 주석 플레이스홀더를 삽입합니다.
102
+ */
103
+ insertRefs(value, refs) {
104
+ const sorted = [...refs].sort((a, b) => b.endIndex - a.endIndex);
105
+ for (const ref of sorted) {
106
+ const sources = ref.sources ?? [];
107
+ const label = escapeHtmlText(ref.label ?? `[${refs.indexOf(ref) + 1}]`);
108
+ const link = sources.at(0)?.url;
109
+ let tooltip = "";
110
+ if (sources.length > 0) tooltip = buildElementHTML("u-ref-card-group", { slot: "tooltip" }, sources.map((s) => URefCard.buildHTML(s)).join(""));
111
+ const html = buildElementHTML("u-ref-tag", { href: link }, label + tooltip);
112
+ const key = this.placeholder.store(html);
113
+ value = value.slice(0, ref.endIndex) + key + value.slice(ref.endIndex);
114
+ }
115
+ return value;
116
+ }
117
+ /**
118
+ * 코드블록 내부의 <!--ref:idx--> 플레이스홀더와 그 외 refs 태그를 모두 제거하여 HTML이 코드로 렌더링되도록 합니다.
119
+ */
120
+ removeRefs(value) {
121
+ value = value.replace(/<u-ref-tag\b[^>]*>[\s\S]*?<\/u-ref-tag>/gi, "");
122
+ value = value.replace(/<!--ref:\d+-->/g, "");
123
+ return value;
124
+ }
125
+ };
126
+ __decorate([property({ type: String }), __decorateMetadata("design:type", String)], UMarkedBlock.prototype, "value", void 0);
127
+ __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)], UMarkedBlock.prototype, "refs", void 0);
128
+ UMarkedBlock = __decorate([customElement("u-marked-block")], UMarkedBlock);
129
+ /**
130
+ * Marked 파싱 중 HTML이 GFM에 의해 오염되는 것을 방지하기 위해
131
+ * HTML을 주석 플레이스홀더로 치환하고, 나중에 원래 HTML로 복원하는 유틸입니다.
132
+ */
133
+ var HtmlPlaceholder = class {
134
+ constructor() {
135
+ this.map = {};
136
+ this.idx = 0;
137
+ }
138
+ reset() {
139
+ this.map = {};
140
+ this.idx = 0;
141
+ }
142
+ /** html을 저장하고 대응하는 플레이스홀더 키를 반환합니다. */
143
+ store(html) {
144
+ const key = `<!--ref:${this.idx++}-->`;
145
+ this.map[key] = html;
146
+ return key;
147
+ }
148
+ /** html 안의 등록된 모든 플레이스홀더를 원래 HTML로 복원합니다. */
149
+ restore(html) {
150
+ if (this.idx === 0) return html;
151
+ return html.replace(/<!--ref:\d+-->/g, (key) => this.map[key] ?? "");
152
+ }
153
+ };
154
+ //#endregion
5
155
  export { UMarkedBlock };
@@ -1,6 +1,6 @@
1
- import { css } from 'lit';
2
-
3
- const styles = css`
1
+ import { css } from "lit";
2
+ //#region src/components/blocks/UMarkedBlock.styles.ts
3
+ var styles = css`
4
4
  /* github-markdown styles */
5
5
  :host {
6
6
  --fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
@@ -575,5 +575,5 @@ const styles = css`
575
575
  margin: 0 -1.6em .25em .2em;
576
576
  }
577
577
  `;
578
-
578
+ //#endregion
579
579
  export { styles };
@@ -1,7 +1,21 @@
1
- import { URefBlock } from './URefBlock.component.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
+ import { ReferenceSource } from '../../types/References.js';
3
+ /**
4
+ * 레퍼런스 정보를 블록 형태로 표시하는 컴포넌트입니다.
5
+ * 단일 또는 다중 레퍼런스 카드를 그리드 레이아웃으로 표시합니다.
6
+ */
7
+ export declare class URefBlock extends UElement {
8
+ static styles: import('lit').CSSResultGroup[];
9
+ /** 접힘 상태 @default: true */
10
+ collapsed: boolean;
11
+ /** 블록 제목 */
12
+ title: string;
13
+ /** 출처 목록 */
14
+ sources?: ReferenceSource[];
15
+ render(): import('lit-html').TemplateResult<1>;
16
+ }
2
17
  declare global {
3
18
  interface HTMLElementTagNameMap {
4
19
  "u-ref-block": URefBlock;
5
20
  }
6
21
  }
7
- export { URefBlock };
@@ -1,5 +1,60 @@
1
- import { URefBlock } from './URefBlock.component.js';
2
-
3
- URefBlock.define("u-ref-block");
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js";
3
+ import "../references/URefCard.js";
4
+ import { styles } from "./URefBlock.styles.js";
5
+ import { html } from "lit";
6
+ import { customElement, property } from "lit/decorators.js";
7
+ import { UElement } from "@iyulab/components/dist/components/UElement.js";
8
+ import { repeat } from "lit/directives/repeat.js";
9
+ //#region src/components/blocks/URefBlock.ts
10
+ var URefBlock = class URefBlock extends UElement {
11
+ constructor(..._args) {
12
+ super(..._args);
13
+ this.collapsed = true;
14
+ this.title = "";
15
+ }
16
+ static {
17
+ this.styles = [super.styles, styles];
18
+ }
19
+ render() {
20
+ return html`
21
+ <button class="header" @click=${() => this.collapsed = !this.collapsed}>
22
+ <u-icon
23
+ ?collapsed=${this.collapsed}
24
+ lib="internal"
25
+ name="chevron-down"
26
+ ></u-icon>
27
+ <div class="title">
28
+ ${this.title || "References"}
29
+ </div>
30
+ <div style="flex: 1;"></div>
31
+ <div class="count">
32
+ ${this.sources ? this.sources.length : 0}
33
+ </div>
34
+ </button>
4
35
 
36
+ <div class="body" ?collapsed=${this.collapsed}>
37
+ ${repeat(this.sources || [], (_, idx) => idx, (source) => {
38
+ return html`
39
+ <u-ref-card
40
+ .type=${source.type}
41
+ .url=${source.url}
42
+ .title=${source.title || ""}
43
+ .snippet=${source.snippet || ""}
44
+ .tags=${source.tags}
45
+ ></u-ref-card>
46
+ `;
47
+ })}
48
+ </div>
49
+ `;
50
+ }
51
+ };
52
+ __decorate([property({
53
+ type: Boolean,
54
+ reflect: true
55
+ }), __decorateMetadata("design:type", Boolean)], URefBlock.prototype, "collapsed", void 0);
56
+ __decorate([property({ type: String }), __decorateMetadata("design:type", String)], URefBlock.prototype, "title", void 0);
57
+ __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)], URefBlock.prototype, "sources", void 0);
58
+ URefBlock = __decorate([customElement("u-ref-block")], URefBlock);
59
+ //#endregion
5
60
  export { URefBlock };
@@ -1,6 +1,6 @@
1
- import { css } from 'lit';
2
-
3
- const styles = css`
1
+ import { css } from "lit";
2
+ //#region src/components/blocks/URefBlock.styles.ts
3
+ var styles = css`
4
4
  :host {
5
5
  display: flex;
6
6
  flex-direction: column;
@@ -71,5 +71,5 @@ const styles = css`
71
71
  width: 100%;
72
72
  }
73
73
  `;
74
-
74
+ //#endregion
75
75
  export { styles };
@@ -1,7 +1,52 @@
1
- import { UTableBlock } from './UTableBlock.component.js';
1
+ import { UDataElement } from '@iyulab/components/dist/components/UDataElement.js';
2
+ /** 테이블 셀 데이터 타입 */
3
+ export interface TableCell {
4
+ /** 셀에 표시할 텍스트 내용 */
5
+ text: string;
6
+ /** 셀 내용의 정렬 방식. 기본값은 "left" */
7
+ align: "left" | "center" | "right" | null;
8
+ }
9
+ /** 테이블 정렬 상태 */
10
+ export interface SortState {
11
+ /** 현재 정렬 기준이 되는 컬럼 인덱스. -1이면 정렬 안 된 상태 */
12
+ index: number;
13
+ /** 정렬 방향. "asc"는 오름차순, "desc"는 내림차순 */
14
+ dir: "asc" | "desc";
15
+ }
16
+ /**
17
+ * 마크다운 테이블 데이터를 렌더링하는 컴포넌트입니다.
18
+ * 컬럼 정렬, CSV 다운로드 기능을 지원합니다.
19
+ * light DOM 내 `<script type="application/json">` 에서 데이터를 자동으로 읽어냅니다.
20
+ */
21
+ export declare class UTableBlock extends UDataElement {
22
+ static styles: (import('lit').CSSResult | import('lit').CSSResultGroup[])[];
23
+ /** 테이블 헤더 목록. 각 헤더는 { text, align } 형식입니다. */
24
+ headers: TableCell[];
25
+ /** 테이블 행 목록. 각 행은 셀 배열입니다. */
26
+ rows: TableCell[][];
27
+ private loading;
28
+ private sort;
29
+ private search;
30
+ private searchCache?;
31
+ private searchTimer;
32
+ render(): import('lit-html').TemplateResult<1>;
33
+ /**
34
+ * 하이라이트 렌더링: search 기준으로 매칭되는 부분을 <mark>로 감쌉니다.
35
+ * 내부적으로 안전하게 escape한 뒤 매칭을 위해 RegExp를 사용합니다.
36
+ */
37
+ private renderHighlightedText;
38
+ /**
39
+ * 현재 검색어와 정렬 상태에 따라 필터링 및 정렬된 행 목록을 반환합니다.
40
+ */
41
+ private getFilteredSortedRows;
42
+ private handleSearchInput;
43
+ private handleSortColumn;
44
+ private handleDownloadCSV;
45
+ private handleDownloadXLS;
46
+ private triggerDownload;
47
+ }
2
48
  declare global {
3
49
  interface HTMLElementTagNameMap {
4
50
  "u-table-block": UTableBlock;
5
51
  }
6
52
  }
7
- export { UTableBlock };
@@ -1,5 +1,198 @@
1
- import { UTableBlock } from './UTableBlock.component.js';
2
-
3
- UTableBlock.define("u-table-block");
4
-
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js";
3
+ import { styles } from "./UTableBlock.styles.js";
4
+ import { html } from "lit";
5
+ import { customElement, property, state } from "lit/decorators.js";
6
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
7
+ import "@iyulab/components/dist/components/icon/UIcon.js";
8
+ import "@iyulab/components/dist/components/button/UButton.js";
9
+ import { UDataElement } from "@iyulab/components/dist/components/UDataElement.js";
10
+ import { repeat } from "lit/directives/repeat.js";
11
+ import "@iyulab/components/dist/components/skeleton/USkeleton.js";
12
+ //#region src/components/blocks/UTableBlock.ts
13
+ var UTableBlock = class UTableBlock extends UDataElement {
14
+ constructor(..._args) {
15
+ super(..._args);
16
+ this.headers = [];
17
+ this.rows = [];
18
+ this.loading = false;
19
+ this.sort = {
20
+ index: -1,
21
+ dir: "asc"
22
+ };
23
+ this.search = "";
24
+ this.searchTimer = null;
25
+ }
26
+ static {
27
+ this.styles = [super.styles, styles];
28
+ }
29
+ render() {
30
+ const rows = this.getFilteredSortedRows();
31
+ return html`
32
+ <div class="toolbar">
33
+ <div class="toolbar-left">
34
+ <u-input
35
+ class="toolbar-search"
36
+ type="search"
37
+ placeholder="Search..."
38
+ .value=${this.search}
39
+ @input=${this.handleSearchInput}
40
+ >
41
+ <u-icon slot="prefix" lib="internal" name="search"></u-icon>
42
+ </u-input>
43
+ <span class="toolbar-count">
44
+ ${rows.length} / ${this.rows.length} Rows
45
+ </span>
46
+ </div>
47
+ <div class="toolbar-right">
48
+ <u-button @click=${this.handleDownloadXLS} title="Excel Download">
49
+ XLS
50
+ <u-icon slot="suffix" lib="bootstrap" name="download"></u-icon>
51
+ </u-button>
52
+ <u-button @click=${this.handleDownloadCSV} title="CSV Download">
53
+ CSV
54
+ <u-icon slot="suffix" lib="bootstrap" name="download"></u-icon>
55
+ </u-button>
56
+ </div>
57
+ </div>
58
+ <div class="table-wrapper" scrollable>
59
+ <table>
60
+ <thead ?hidden=${!this.headers.length}>
61
+ <tr>
62
+ ${repeat(this.headers, (_, i) => i, (h, i) => {
63
+ const isActive = this.sort.index === i;
64
+ return html`
65
+ <th
66
+ ?active=${isActive}
67
+ align=${h.align ?? "left"}
68
+ @click=${() => this.handleSortColumn(i)}
69
+ >
70
+ ${unsafeHTML(h.text)}
71
+ <u-icon
72
+ class="sort-icon"
73
+ lib="bootstrap"
74
+ name=${isActive ? this.sort.dir === "asc" ? "sort-alpha-up" : "sort-alpha-down" : "arrow-down-up"}
75
+ ></u-icon>
76
+ </th>
77
+ `;
78
+ })}
79
+ </tr>
80
+ </thead>
81
+ <tbody>
82
+ ${this.loading ? html`
83
+ <tr>
84
+ <td colspan=${this.headers.length || 1}>
85
+ <u-skeleton width="80%" height="1.2em"></u-skeleton>
86
+ <u-skeleton width="60%" height="1.2em"></u-skeleton>
87
+ <u-skeleton width="70%" height="1.2em"></u-skeleton>
88
+ <u-skeleton width="50%" height="1.2em"></u-skeleton>
89
+ </td>
90
+ </tr>
91
+ ` : repeat(rows, (_, i) => i, (row) => html`
92
+ <tr>
93
+ ${repeat(row, (_, j) => j, (cell) => html`
94
+ <td align=${cell.align ?? "left"}>
95
+ ${unsafeHTML(this.renderHighlightedText(cell.text))}
96
+ </td>
97
+ `)}
98
+ </tr>
99
+ `)}
100
+ </tbody>
101
+ </table>
102
+ </div>
103
+ `;
104
+ }
105
+ /**
106
+ * 하이라이트 렌더링: search 기준으로 매칭되는 부분을 <mark>로 감쌉니다.
107
+ * 내부적으로 안전하게 escape한 뒤 매칭을 위해 RegExp를 사용합니다.
108
+ */
109
+ renderHighlightedText(text) {
110
+ const q = this.search.trim();
111
+ if (!q) return text;
112
+ const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
113
+ const re = new RegExp(`(${escaped})`, "gi");
114
+ const parts = String(text).split(re);
115
+ if (parts.length === 1) return text;
116
+ return parts.map((p, idx) => idx % 2 === 1 ? `<mark>${p}</mark>` : p).join("");
117
+ }
118
+ /**
119
+ * 현재 검색어와 정렬 상태에 따라 필터링 및 정렬된 행 목록을 반환합니다.
120
+ */
121
+ getFilteredSortedRows() {
122
+ let rows = this.rows;
123
+ const q = this.search.trim();
124
+ if (q) {
125
+ const qLower = q.toLowerCase();
126
+ rows = rows.filter((row) => row.some((cell) => cell.text.toLowerCase().includes(qLower)));
127
+ }
128
+ const { index, dir } = this.sort;
129
+ if (index < 0) return rows;
130
+ return [...rows].sort((a, b) => {
131
+ const av = a[index]?.text ?? "";
132
+ const bv = b[index]?.text ?? "";
133
+ const an = Number(av);
134
+ const bn = Number(bv);
135
+ const cmp = !isNaN(an) && !isNaN(bn) ? an - bn : av.localeCompare(bv, void 0, { sensitivity: "base" });
136
+ return dir === "asc" ? cmp : -cmp;
137
+ });
138
+ }
139
+ handleSearchInput(e) {
140
+ this.searchCache = e.target.value || "";
141
+ if (this.searchTimer !== null) window.clearTimeout(this.searchTimer);
142
+ this.loading = true;
143
+ this.searchTimer = window.setTimeout(() => {
144
+ this.search = this.searchCache || "";
145
+ this.loading = false;
146
+ this.searchTimer = null;
147
+ }, 250);
148
+ }
149
+ handleSortColumn(index) {
150
+ if (this.sort.index === index) this.sort = {
151
+ ...this.sort,
152
+ dir: this.sort.dir === "asc" ? "desc" : "asc"
153
+ };
154
+ else this.sort = {
155
+ index,
156
+ dir: "asc"
157
+ };
158
+ }
159
+ handleDownloadCSV() {
160
+ const escCsv = (v) => v.includes(",") || v.includes("\"") || v.includes("\n") ? `"${v.replace(/"/g, "\"\"")}"` : v;
161
+ const lines = [this.headers.map((h) => escCsv(h.text)).join(","), ...this.rows.map((row) => row.map((cell) => escCsv(cell.text)).join(","))];
162
+ const blob = new Blob([lines.join("\n")], { type: "text/csv;charset=utf-8;" });
163
+ this.triggerDownload(`table-${Date.now()}.csv`, blob);
164
+ }
165
+ handleDownloadXLS() {
166
+ const escXml = (v) => v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
167
+ const cell = (v) => `<Cell><Data ss:Type="String">${escXml(v)}</Data></Cell>`;
168
+ const row = (cells) => `<Row>${cells.map(cell).join("")}</Row>`;
169
+ const xml = [
170
+ `<?xml version="1.0" encoding="UTF-8"?>`,
171
+ `<?mso-application progid="Excel.Sheet"?>`,
172
+ `<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"`,
173
+ ` xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">`,
174
+ `<Worksheet ss:Name="Sheet1"><Table>`,
175
+ row(this.headers.map((h) => h.text)),
176
+ ...this.rows.map((r) => row(r.map((c) => c.text))),
177
+ `</Table></Worksheet></Workbook>`
178
+ ].join("\n");
179
+ const blob = new Blob([xml], { type: "application/vnd.ms-excel;charset=utf-8;" });
180
+ this.triggerDownload(`table-${Date.now()}.xls`, blob);
181
+ }
182
+ triggerDownload(filename, blob) {
183
+ const url = URL.createObjectURL(blob);
184
+ const a = document.createElement("a");
185
+ a.href = url;
186
+ a.download = filename;
187
+ a.click();
188
+ URL.revokeObjectURL(url);
189
+ }
190
+ };
191
+ __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)], UTableBlock.prototype, "headers", void 0);
192
+ __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)], UTableBlock.prototype, "rows", void 0);
193
+ __decorate([state(), __decorateMetadata("design:type", Boolean)], UTableBlock.prototype, "loading", void 0);
194
+ __decorate([state(), __decorateMetadata("design:type", Object)], UTableBlock.prototype, "sort", void 0);
195
+ __decorate([state(), __decorateMetadata("design:type", String)], UTableBlock.prototype, "search", void 0);
196
+ UTableBlock = __decorate([customElement("u-table-block")], UTableBlock);
197
+ //#endregion
5
198
  export { UTableBlock };
@@ -1,6 +1,6 @@
1
- import { css } from 'lit';
2
-
3
- const styles = css`
1
+ import { css } from "lit";
2
+ //#region src/components/blocks/UTableBlock.styles.ts
3
+ var styles = css`
4
4
  :host {
5
5
  display: block;
6
6
  width: 100%;
@@ -66,7 +66,6 @@ const styles = css`
66
66
 
67
67
  thead {
68
68
  position: sticky;
69
- z-index: 10;
70
69
  top: 0;
71
70
  }
72
71
 
@@ -130,5 +129,5 @@ const styles = css`
130
129
  text-align: right;
131
130
  }
132
131
  `;
133
-
132
+ //#endregion
134
133
  export { styles };
@@ -1,7 +1,41 @@
1
- import { UTextBlock } from './UTextBlock.component.js';
1
+ import { PropertyValues } from 'lit';
2
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
+ /**
4
+ * 텍스트를 표시하거나 편집할 수 있는 블록 컴포넌트입니다.
5
+ */
6
+ export declare class UTextBlock extends UElement {
7
+ static styles: import('lit').CSSResultGroup[];
8
+ /** 편집 가능 여부 */
9
+ editable: boolean;
10
+ /** 스펠체크 여부 */
11
+ spellcheck: boolean;
12
+ /** 플레이스홀더 텍스트 */
13
+ placeholder?: string;
14
+ /** 최소 행 수, 기본값은 1 */
15
+ minRows: number;
16
+ /** 최대 행 수 */
17
+ maxRows?: number;
18
+ /** 텍스트 블록의 내용 */
19
+ value?: string;
20
+ textareaEl: HTMLTextAreaElement;
21
+ preEl: HTMLPreElement;
22
+ protected updated(changedProperties: PropertyValues): void;
23
+ render(): import('lit-html').TemplateResult<1>;
24
+ /**
25
+ * textarea에 포커스를 줍니다.
26
+ */
27
+ focus(options?: FocusOptions): void;
28
+ /**
29
+ * 텍스트 입력시 value를 업데이트하고 이벤트를 재전파합니다.
30
+ */
31
+ private updateValueFrom;
32
+ /**
33
+ * pre 엘리먼트에 주입될 값을 정규화합니다.
34
+ */
35
+ private normalizeValue;
36
+ }
2
37
  declare global {
3
38
  interface HTMLElementTagNameMap {
4
39
  "u-text-block": UTextBlock;
5
40
  }
6
41
  }
7
- export { UTextBlock };