@iyulab/chat-components 0.1.1 → 0.2.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 (109) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/components/blocks/UCodeBlock.component.d.ts +7 -8
  3. package/dist/components/blocks/UCodeBlock.component.js +32 -21
  4. package/dist/components/blocks/UCodeBlock.styles.js +7 -6
  5. package/dist/components/{json-viewer/UJsonViewer.component.d.ts → blocks/UJsonBlock.component.d.ts} +5 -4
  6. package/dist/components/{json-viewer/UJsonViewer.component.js → blocks/UJsonBlock.component.js} +20 -17
  7. package/dist/components/blocks/UJsonBlock.d.ts +7 -0
  8. package/dist/components/blocks/UJsonBlock.js +5 -0
  9. package/dist/components/blocks/UMarkedBlock.component.d.ts +30 -9
  10. package/dist/components/blocks/UMarkedBlock.component.js +75 -26
  11. package/dist/components/blocks/UMarkedBlock.styles.js +288 -949
  12. package/dist/components/blocks/UThinkBlock.component.d.ts +3 -8
  13. package/dist/components/blocks/UThinkBlock.component.js +28 -22
  14. package/dist/components/blocks/UThinkBlock.styles.js +35 -54
  15. package/dist/components/blocks/UToolBlock.component.d.ts +13 -9
  16. package/dist/components/blocks/UToolBlock.component.js +30 -76
  17. package/dist/components/blocks/UToolBlock.styles.js +21 -62
  18. package/dist/components/buttons/UAttachButton.component.d.ts +3 -5
  19. package/dist/components/buttons/UAttachButton.component.js +30 -19
  20. package/dist/components/buttons/UAttachButton.styles.js +5 -12
  21. package/dist/components/buttons/UCopyButton.component.d.ts +3 -8
  22. package/dist/components/buttons/UCopyButton.component.js +29 -53
  23. package/dist/components/buttons/UCopyButton.styles.js +8 -37
  24. package/dist/components/buttons/UReportButton.component.d.ts +9 -0
  25. package/dist/components/buttons/UReportButton.component.js +36 -0
  26. package/dist/components/buttons/UReportButton.d.ts +7 -0
  27. package/dist/components/buttons/UReportButton.js +5 -0
  28. package/dist/components/buttons/UReportButton.styles.js +14 -0
  29. package/dist/components/buttons/URetryButton.component.d.ts +11 -0
  30. package/dist/components/buttons/URetryButton.component.js +53 -0
  31. package/dist/components/buttons/URetryButton.d.ts +7 -0
  32. package/dist/components/buttons/URetryButton.js +5 -0
  33. package/dist/components/buttons/URetryButton.styles.js +26 -0
  34. package/dist/components/buttons/UShareButton.component.d.ts +9 -0
  35. package/dist/components/buttons/UShareButton.component.js +36 -0
  36. package/dist/components/buttons/UShareButton.d.ts +7 -0
  37. package/dist/components/buttons/UShareButton.js +5 -0
  38. package/dist/components/buttons/UShareButton.styles.d.ts +1 -0
  39. package/dist/components/buttons/UShareButton.styles.js +14 -0
  40. package/dist/components/buttons/UVoteButton.component.d.ts +15 -0
  41. package/dist/components/buttons/UVoteButton.component.js +70 -0
  42. package/dist/components/buttons/UVoteButton.d.ts +8 -0
  43. package/dist/components/buttons/UVoteButton.js +5 -0
  44. package/dist/components/buttons/UVoteButton.styles.d.ts +1 -0
  45. package/dist/components/buttons/UVoteButton.styles.js +19 -0
  46. package/dist/components/loaders/UDotLoader.component.d.ts +9 -0
  47. package/dist/components/loaders/UDotLoader.component.js +23 -0
  48. package/dist/components/loaders/UDotLoader.d.ts +7 -0
  49. package/dist/components/loaders/UDotLoader.js +5 -0
  50. package/dist/components/loaders/UDotLoader.styles.d.ts +1 -0
  51. package/dist/components/loaders/UDotLoader.styles.js +50 -0
  52. package/dist/components/message/UMessage.component.d.ts +12 -6
  53. package/dist/components/message/UMessage.component.js +39 -59
  54. package/dist/components/message/UMessage.d.ts +0 -1
  55. package/dist/components/message/UMessage.styles.js +30 -49
  56. package/dist/components/prompt/UPrompt.component.d.ts +25 -0
  57. package/dist/components/prompt/UPrompt.component.js +113 -0
  58. package/dist/components/prompt/UPrompt.d.ts +7 -0
  59. package/dist/components/prompt/UPrompt.js +5 -0
  60. package/dist/components/prompt/UPrompt.styles.d.ts +1 -0
  61. package/dist/components/prompt/UPrompt.styles.js +42 -0
  62. package/dist/components/references/URefCard.component.d.ts +22 -0
  63. package/dist/components/references/URefCard.component.js +96 -0
  64. package/dist/components/references/URefCard.d.ts +7 -0
  65. package/dist/components/references/URefCard.js +5 -0
  66. package/dist/components/references/URefCard.styles.d.ts +1 -0
  67. package/dist/components/references/URefCard.styles.js +103 -0
  68. package/dist/components/references/URefCardGroup.component.d.ts +25 -0
  69. package/dist/components/references/URefCardGroup.component.js +88 -0
  70. package/dist/components/references/URefCardGroup.d.ts +7 -0
  71. package/dist/components/references/URefCardGroup.js +5 -0
  72. package/dist/components/references/URefCardGroup.styles.d.ts +1 -0
  73. package/dist/components/references/URefCardGroup.styles.js +69 -0
  74. package/dist/components/references/URefTag.component.d.ts +11 -0
  75. package/dist/components/{buttons/USendButton.component.js → references/URefTag.component.js} +17 -14
  76. package/dist/components/references/URefTag.d.ts +7 -0
  77. package/dist/components/references/URefTag.js +5 -0
  78. package/dist/components/references/URefTag.styles.d.ts +1 -0
  79. package/dist/components/references/URefTag.styles.js +51 -0
  80. package/dist/events/UCancelEvent.d.ts +6 -0
  81. package/dist/index.d.ts +15 -5
  82. package/dist/index.js +20 -6
  83. package/dist/types/BlockItem.d.ts +36 -0
  84. package/dist/types/BlockReference.d.ts +32 -0
  85. package/dist/types/JsonNode.d.ts +20 -0
  86. package/dist/utilities/converters.d.ts +9 -0
  87. package/dist/utilities/converters.js +19 -0
  88. package/package.json +9 -10
  89. package/dist/components/buttons/USendButton.component.d.ts +0 -13
  90. package/dist/components/buttons/USendButton.d.ts +0 -7
  91. package/dist/components/buttons/USendButton.js +0 -5
  92. package/dist/components/buttons/USendButton.styles.js +0 -23
  93. package/dist/components/buttons/UThinkButton.component.d.ts +0 -19
  94. package/dist/components/buttons/UThinkButton.component.js +0 -73
  95. package/dist/components/buttons/UThinkButton.d.ts +0 -7
  96. package/dist/components/buttons/UThinkButton.js +0 -5
  97. package/dist/components/buttons/UThinkButton.styles.js +0 -72
  98. package/dist/components/json-viewer/UJsonViewer.d.ts +0 -7
  99. package/dist/components/json-viewer/UJsonViewer.js +0 -5
  100. package/dist/components/json-viewer/UJsonViewer.lib.d.ts +0 -16
  101. package/dist/components/json-viewer/UJsonViewer.lib.js +0 -28
  102. package/dist/components/message/UMessage.types.d.ts +0 -21
  103. package/dist/events/UStopEvent.d.ts +0 -6
  104. package/dist/internals/date-helpers.d.ts +0 -8
  105. package/dist/internals/date-helpers.js +0 -27
  106. /package/dist/components/{buttons/USendButton.styles.d.ts → blocks/UJsonBlock.styles.d.ts} +0 -0
  107. /package/dist/components/{json-viewer/UJsonViewer.styles.js → blocks/UJsonBlock.styles.js} +0 -0
  108. /package/dist/components/buttons/{UThinkButton.styles.d.ts → UReportButton.styles.d.ts} +0 -0
  109. /package/dist/components/{json-viewer/UJsonViewer.styles.d.ts → buttons/URetryButton.styles.d.ts} +0 -0
@@ -0,0 +1,50 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ svg {
5
+ width: 1em;
6
+ height: 1em;
7
+ fill: currentColor;
8
+ display: inline-block;
9
+ vertical-align: middle;
10
+ }
11
+
12
+ circle {
13
+ animation: bounce 1.05s infinite;
14
+ transform-box: fill-box;
15
+ transform-origin: center;
16
+ }
17
+
18
+ circle.d1 {
19
+ animation-delay: 0.1s;
20
+ }
21
+
22
+ circle.d2 {
23
+ animation-delay: 0.2s;
24
+ }
25
+
26
+ @media (prefers-reduced-motion: reduce) {
27
+ circle {
28
+ animation: none;
29
+ transform: none;
30
+ }
31
+ }
32
+
33
+ @keyframes bounce {
34
+ 0%,57.14% {
35
+ animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
36
+ transform: translateY(0);
37
+ }
38
+
39
+ 28.57% {
40
+ animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
41
+ transform: translateY(-6px);
42
+ }
43
+
44
+ 100% {
45
+ transform: translateY(0);
46
+ }
47
+ }
48
+ `;
49
+
50
+ export { styles };
@@ -1,13 +1,19 @@
1
1
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
- import { BlockItem } from './UMessage.types.js';
2
+ import { BlockItem } from '../../types/BlockItem';
3
+ /** 메시지 variant 타입 */
4
+ export type MessageVariant = 'default' | 'bubble';
5
+ /** 메시지 위치 타입 */
6
+ export type MessagePosition = 'left' | 'right';
7
+ /**
8
+ * 채팅 메시지 컴포넌트입니다.
9
+ * 다양한 유형의 블록 아이템과 인용 출처를 렌더링할 수 있습니다.
10
+ */
3
11
  export declare class UMessage extends BaseElement {
4
12
  static styles: import('lit').CSSResultGroup[];
5
13
  static dependencies: Record<string, typeof BaseElement>;
14
+ variant: MessageVariant;
15
+ position: MessagePosition;
16
+ loading: boolean;
6
17
  items?: BlockItem[];
7
- timestamp?: string;
8
18
  render(): import('lit-html').TemplateResult<1>;
9
- /**
10
- * 텍스트 및 마크다운 블록의 내용을 모아서 하나의 문자열로 반환합니다.
11
- */
12
- private getTextValue;
13
19
  }
@@ -2,12 +2,11 @@ import { nothing, html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { repeat } from 'lit/directives/repeat.js';
4
4
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
5
- import { UCopyButton } from '../buttons/UCopyButton.component.js';
6
5
  import { UTextBlock } from '../blocks/UTextBlock.component.js';
7
6
  import { UMarkedBlock } from '../blocks/UMarkedBlock.component.js';
8
7
  import { UThinkBlock } from '../blocks/UThinkBlock.component.js';
9
8
  import { UToolBlock } from '../blocks/UToolBlock.component.js';
10
- import { format } from '../../internals/date-helpers.js';
9
+ import { UDotLoader } from '../loaders/UDotLoader.component.js';
11
10
  import { styles } from './UMessage.styles.js';
12
11
 
13
12
  var __defProp = Object.defineProperty;
@@ -22,18 +21,9 @@ var __decorateClass = (decorators, target, key, kind) => {
22
21
  class UMessage extends BaseElement {
23
22
  constructor() {
24
23
  super(...arguments);
25
- /**
26
- * 텍스트 및 마크다운 블록의 내용을 모아서 하나의 문자열로 반환합니다.
27
- */
28
- this.getTextValue = (items) => {
29
- if (!items) return "";
30
- return items.reduce((acc, item) => {
31
- if (item.type === "text" || item.type === "markdown") {
32
- return acc ? acc + "\n" + (item.value || "") : item.value || "";
33
- }
34
- return acc;
35
- }, "");
36
- };
24
+ this.variant = "default";
25
+ this.position = "left";
26
+ this.loading = false;
37
27
  }
38
28
  static {
39
29
  this.styles = [super.styles, styles];
@@ -44,61 +34,51 @@ class UMessage extends BaseElement {
44
34
  "u-marked-block": UMarkedBlock,
45
35
  "u-think-block": UThinkBlock,
46
36
  "u-tool-block": UToolBlock,
47
- "u-copy-button": UCopyButton
37
+ "u-dot-loader": UDotLoader
48
38
  };
49
39
  }
50
40
  render() {
51
41
  return html`
52
- <div class="container">
53
- <div class="header" part="header">
54
- <slot name="header"></slot>
55
- </div>
56
- <div class="body" part="body">
57
- ${this.items && this.items.length > 0 ? repeat(this.items, (_, idx) => idx, (item, idx) => {
58
- return item.type === "text" ? html`
59
- <u-text-block
60
- .value=${item.value}
61
- ></u-text-block>` : item.type === "markdown" ? html`
62
- <u-marked-block
63
- .value=${item.value}
64
- ></u-marked-block>` : item.type === "thinking" ? html`
65
- <u-think-block
66
- ?loading=${this.items?.length === (idx || 0) + 1}
67
- .value=${item.value}
68
- ></u-think-block>` : item.type === "tool" ? html`
69
- <u-tool-block
70
- .index=${idx}
71
- .status=${item.status}
72
- .name=${item.name}
73
- .input=${item.input}
74
- .output=${item.output}
75
- ></u-tool-block>` : nothing;
76
- }) : html`
77
- <svg class="loader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
78
- <circle class="dot" cx="4" cy="12" r="3"/>
79
- <circle class="dot d1" cx="12" cy="12" r="3"/>
80
- <circle class="dot d2" cx="20" cy="12" r="3"/>
81
- </svg>`}
82
- </div>
83
- <div class="footer" part="footer">
84
- <u-copy-button
85
- .value=${this.getTextValue(this.items)}
86
- ></u-copy-button>
87
- <slot name="footer"></slot>
88
- <div style="flex:1;"></div>
89
- <div class="timestamp">
90
- ${format(this.timestamp)}
91
- </div>
92
- </div>
42
+ <slot name="header"></slot>
43
+
44
+ <div class="body" part="body" variant=${this.variant} position=${this.position}>
45
+ ${repeat(this.items || [], (_, idx) => idx, (item, idx) => item.type === "text" ? html`
46
+ <u-text-block
47
+ .value=${item.value}
48
+ ></u-text-block>` : item.type === "markdown" ? html`
49
+ <u-marked-block
50
+ .value=${item.value}
51
+ .refs=${item.refs}
52
+ ></u-marked-block>` : item.type === "thinking" ? html`
53
+ <u-think-block
54
+ .value=${item.value}
55
+ ></u-think-block>` : item.type === "tool" ? html`
56
+ <u-tool-block
57
+ index=${idx}
58
+ .heading=${item.title}
59
+ .input=${item.input}
60
+ .output=${item.output}
61
+ ></u-tool-block>` : nothing)}
62
+ <u-dot-loader
63
+ ?hidden=${!this.loading}
64
+ ></u-dot-loader>
93
65
  </div>
66
+
67
+ <slot name="footer" ?hidden=${this.loading}></slot>
94
68
  `;
95
69
  }
96
70
  }
71
+ __decorateClass([
72
+ property({ type: String, reflect: true })
73
+ ], UMessage.prototype, "variant");
74
+ __decorateClass([
75
+ property({ type: String, reflect: true })
76
+ ], UMessage.prototype, "position");
77
+ __decorateClass([
78
+ property({ type: Boolean, reflect: true })
79
+ ], UMessage.prototype, "loading");
97
80
  __decorateClass([
98
81
  property({ type: Array })
99
82
  ], UMessage.prototype, "items");
100
- __decorateClass([
101
- property({ type: String })
102
- ], UMessage.prototype, "timestamp");
103
83
 
104
84
  export { UMessage };
@@ -5,4 +5,3 @@ declare global {
5
5
  }
6
6
  }
7
7
  export { UMessage };
8
- export type * from './UMessage.types';
@@ -2,70 +2,51 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
- display: block;
6
- font-family: 'Roboto', sans-serif;
7
- font-size: 14px;
8
- line-height: 1.5;
9
- }
10
-
11
- .container {
12
5
  display: flex;
13
6
  flex-direction: column;
14
7
  }
15
-
16
- .header {
17
- display: flex;
18
- flex-direction: row;
19
- align-items: center;
8
+ :host([variant="default"]) {
9
+ width: 100%;
10
+ }
11
+ :host([variant="bubble"]) {
12
+ width: auto;
13
+ min-width: 40px;
14
+ max-width: 80%;
15
+ }
16
+ :host([position="left"]) {
17
+ align-self: flex-start;
18
+ align-items: flex-start;
19
+ }
20
+ :host([position="right"]) {
21
+ align-self: flex-end;
22
+ align-items: flex-end;
20
23
  }
21
24
 
22
25
  .body {
26
+ width: 100%;
23
27
  display: flex;
24
28
  flex-direction: column;
25
29
  gap: 12px;
26
- padding: 8px;
27
- border: none;
28
- border-radius: 8px;
29
30
  }
30
-
31
- .footer {
32
- display: flex;
33
- flex-direction: row;
34
- align-items: center;
35
- justify-content: space-between;
36
- padding: 8px 0px;
37
- gap: 12px;
38
- font-size: 12px;
31
+ .body[variant="default"] {
32
+ padding: 12px;
33
+ background-color: transparent;
39
34
  }
40
-
41
- .loader {
42
- width: 1em;
43
- height: 1em;
44
- fill: currentColor;
45
- }
46
-
47
- .dot {
48
- animation: bounce_action 1.05s infinite
35
+ .body[variant="bubble"] {
36
+ padding: 12px 18px;
37
+ border-radius: 18px;
38
+ background-color: var(--u-neutral-200, #f3f4f6);
49
39
  }
50
- .d1 {
51
- animation-delay:.1s
40
+ .body[variant="bubble"][position="left"] {
41
+ border-bottom-left-radius: 4px;
52
42
  }
53
- .d2 {
54
- animation-delay:.2s
43
+ .body[variant="bubble"][position="right"] {
44
+ border-bottom-right-radius: 4px;
55
45
  }
56
46
 
57
- @keyframes bounce_action {
58
- 0%,57.14% {
59
- animation-timing-function: cubic-bezier(0.33,.66,.66,1);
60
- transform: translate(0);
61
- }
62
- 28.57% {
63
- animation-timing-function: cubic-bezier(0.33,0,.66,.33);
64
- transform: translateY(-6px);
65
- }
66
- 100% {
67
- transform: translate(0);
68
- }
47
+ u-dot-loader {
48
+ font-size: 24px;
49
+ color: var(--u-neutral-800, #6b7280);
69
50
  }
70
51
  `;
71
52
 
@@ -0,0 +1,25 @@
1
+ import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
+ /**
3
+ * 채팅 입력 컴포넌트입니다.
4
+ * 텍스트 입력 영역과 우측에 액션 버튼을 배치할 수 있는 슬롯을 제공합니다.
5
+ */
6
+ export declare class UPrompt extends BaseElement {
7
+ static styles: import('lit').CSSResultGroup[];
8
+ static dependencies: Record<string, typeof BaseElement>;
9
+ /** 로딩 상태 여부 */
10
+ loading: boolean;
11
+ /** 최소 행 수 */
12
+ minRows: number;
13
+ /** 최대 행 수 */
14
+ maxRows: number;
15
+ /** 입력 필드의 플레이스홀더 텍스트 */
16
+ placeholder?: string;
17
+ /** 입력 필드의 값 */
18
+ value?: string;
19
+ connectedCallback(): void;
20
+ render(): import('lit-html').TemplateResult<1>;
21
+ send(): void;
22
+ private handleTextBlockInput;
23
+ private handleTextBlockKeydown;
24
+ private handleSendButtonClick;
25
+ }
@@ -0,0 +1,113 @@
1
+ import { html } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
4
+ import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
+ import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
6
+ import { UTextBlock } from '../blocks/UTextBlock.component.js';
7
+ import { styles } from './UPrompt.styles.js';
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __decorateClass = (decorators, target, key, kind) => {
11
+ var result = void 0 ;
12
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
13
+ if (decorator = decorators[i])
14
+ result = (decorator(target, key, result) ) || result;
15
+ if (result) __defProp(target, key, result);
16
+ return result;
17
+ };
18
+ class UPrompt extends BaseElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.loading = false;
22
+ this.minRows = 1;
23
+ this.maxRows = 10;
24
+ this.handleSendButtonClick = (e) => {
25
+ e.preventDefault();
26
+ e.stopPropagation();
27
+ this.send();
28
+ };
29
+ }
30
+ static {
31
+ this.styles = [super.styles, styles];
32
+ }
33
+ static {
34
+ this.dependencies = {
35
+ "u-icon": UIcon,
36
+ "u-button": UButton,
37
+ "u-text-block": UTextBlock
38
+ };
39
+ }
40
+ connectedCallback() {
41
+ super.connectedCallback();
42
+ this.setAttribute("tabindex", "0");
43
+ }
44
+ render() {
45
+ return html`
46
+ <slot name="header"></slot>
47
+
48
+ <u-text-block part="input"
49
+ editable
50
+ .minRows=${this.minRows}
51
+ .maxRows=${this.maxRows}
52
+ .value=${this.value}
53
+ .placeholder=${this.placeholder}
54
+ @input=${this.handleTextBlockInput}
55
+ @keydown=${this.handleTextBlockKeydown}
56
+ ></u-text-block>
57
+
58
+ <div class="control" part="control">
59
+ <slot name="left-actions"></slot>
60
+ <div style="flex: 1;"></div>
61
+ <slot name="right-actions"></slot>
62
+
63
+ <u-button class="send-btn" part="send-btn"
64
+ ?disabled=${!this.loading && !this.value}
65
+ @click=${this.handleSendButtonClick}>
66
+ <u-icon
67
+ lib="internal"
68
+ name=${this.loading ? "stop-circle" : "arrow-up"}
69
+ ></u-icon>
70
+ </u-button>
71
+ </div>
72
+
73
+ <slot name="footer"></slot>
74
+ `;
75
+ }
76
+ send() {
77
+ const value = this.value?.trim();
78
+ if (this.loading) {
79
+ this.emit("u-cancel");
80
+ } else if (value) {
81
+ this.emit("u-submit", { value: this.value });
82
+ this.value = "";
83
+ } else ;
84
+ }
85
+ handleTextBlockInput(e) {
86
+ e.preventDefault();
87
+ const target = e.target;
88
+ this.value = target.value;
89
+ }
90
+ handleTextBlockKeydown(e) {
91
+ if (e.key === "Enter" && !e.shiftKey) {
92
+ e.preventDefault();
93
+ this.send();
94
+ }
95
+ }
96
+ }
97
+ __decorateClass([
98
+ property({ type: Boolean, reflect: true })
99
+ ], UPrompt.prototype, "loading");
100
+ __decorateClass([
101
+ property({ type: Number })
102
+ ], UPrompt.prototype, "minRows");
103
+ __decorateClass([
104
+ property({ type: Number })
105
+ ], UPrompt.prototype, "maxRows");
106
+ __decorateClass([
107
+ property({ type: String })
108
+ ], UPrompt.prototype, "placeholder");
109
+ __decorateClass([
110
+ property({ type: String })
111
+ ], UPrompt.prototype, "value");
112
+
113
+ export { UPrompt };
@@ -0,0 +1,7 @@
1
+ import { UPrompt } from './UPrompt.component.js';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ "u-prompt": UPrompt;
5
+ }
6
+ }
7
+ export { UPrompt };
@@ -0,0 +1,5 @@
1
+ import { UPrompt } from './UPrompt.component.js';
2
+
3
+ UPrompt.define("u-prompt");
4
+
5
+ export { UPrompt };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;
@@ -0,0 +1,42 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ :host {
5
+ display: flex;
6
+ flex-direction: column;
7
+ padding: 12px;
8
+ border: 1px solid var(--u-border-color, #e0e0e0);
9
+ border-radius: 8px;
10
+ background-color: var(--u-bg-color);
11
+ }
12
+ :host(:focus-within) {
13
+ outline: none;
14
+ border-color: var(--u-neutral-400, #9ca3af);
15
+ box-shadow: 0 0 0 1px var(--u-neutral-200, #9ca3af);
16
+ }
17
+
18
+ u-text-block {
19
+ flex: 1;
20
+ padding: 8px;
21
+ }
22
+
23
+ .control {
24
+ display: flex;
25
+ flex-direction: row;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ gap: 8px;
29
+ }
30
+
31
+ .send-btn {
32
+ font-size: 16px;
33
+ color: var(--u-neutral-0);
34
+ background-color: var(--u-neutral-800);
35
+ }
36
+ .send-btn[disabled] {
37
+ opacity: 0.5;
38
+ cursor: not-allowed;
39
+ }
40
+ `;
41
+
42
+ export { styles };
@@ -0,0 +1,22 @@
1
+ import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
+ /**
3
+ * 참조 소스를 카드 형태로 표시하는 공통 컴포넌트입니다.
4
+ * Web과 Document 타입 모두 지원합니다.
5
+ */
6
+ export declare class URefCard extends BaseElement {
7
+ static styles: import('lit').CSSResultGroup[];
8
+ static dependencies: Record<string, typeof BaseElement>;
9
+ /** 카드 타입 (web 또는 document) */
10
+ type: 'web' | 'document';
11
+ /** 외부 링크 URL */
12
+ href: string;
13
+ /** 카드 타이틀 */
14
+ heading?: string;
15
+ /** 태그 목록 */
16
+ tags?: string[];
17
+ render(): import('lit-html').TemplateResult<1>;
18
+ /** URL에서 Google의 파비콘 URL을 반환합니다. */
19
+ private getFaviconUrl;
20
+ /** URL에서 도메인 사이트 주소를 반환합니다. */
21
+ private getPageTitle;
22
+ }
@@ -0,0 +1,96 @@
1
+ import { html } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
+ import { arrayAttrConverter } from '@iyulab/components/dist/utilities/converters.js';
5
+ import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
6
+ import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
7
+ import { styles } from './URefCard.styles.js';
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __decorateClass = (decorators, target, key, kind) => {
11
+ var result = void 0 ;
12
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
13
+ if (decorator = decorators[i])
14
+ result = (decorator(target, key, result) ) || result;
15
+ if (result) __defProp(target, key, result);
16
+ return result;
17
+ };
18
+ class URefCard extends BaseElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.type = "web";
22
+ this.href = "#";
23
+ }
24
+ static {
25
+ this.styles = [super.styles, styles];
26
+ }
27
+ static {
28
+ this.dependencies = {
29
+ "u-icon": UIcon
30
+ };
31
+ }
32
+ render() {
33
+ return html`
34
+ <a href="${this.href}" target="_blank" rel="noopener noreferrer">
35
+ <div class="header">
36
+ <img class="favicon"
37
+ src="${this.getFaviconUrl(this.href)}"
38
+ alt="favicon"
39
+ />
40
+ <div class="title" title="${ifDefined(this.heading)}">
41
+ ${this.heading || this.getPageTitle(this.href)}
42
+ </div>
43
+
44
+ <div style="flex: 1;"></div>
45
+
46
+ <div class="badge" type=${this.type}>
47
+ <u-icon
48
+ lib="internal"
49
+ name=${this.type === "web" ? "globe" : "file-earmark"}
50
+ ></u-icon>
51
+ ${this.type.toUpperCase()}
52
+ </div>
53
+ </div>
54
+
55
+ <div class="body">
56
+ <slot></slot>
57
+ </div>
58
+
59
+ <div class="footer" ?hidden=${!this.tags || this.tags.length === 0}>
60
+ ${this.tags?.map((tag) => html`<span class="tag">${tag}</span>`)}
61
+ </div>
62
+ </a>
63
+ `;
64
+ }
65
+ /** URL에서 Google의 파비콘 URL을 반환합니다. */
66
+ getFaviconUrl(url) {
67
+ try {
68
+ const hostname = new URL(url).hostname;
69
+ return `https://www.google.com/s2/favicons?sz=64&domain=${hostname}`;
70
+ } catch {
71
+ return `/favicon.ico`;
72
+ }
73
+ }
74
+ /** URL에서 도메인 사이트 주소를 반환합니다. */
75
+ getPageTitle(url) {
76
+ try {
77
+ return new URL(url).hostname;
78
+ } catch {
79
+ return "Unkown";
80
+ }
81
+ }
82
+ }
83
+ __decorateClass([
84
+ property({ type: String, reflect: true })
85
+ ], URefCard.prototype, "type");
86
+ __decorateClass([
87
+ property({ type: String })
88
+ ], URefCard.prototype, "href");
89
+ __decorateClass([
90
+ property({ type: String })
91
+ ], URefCard.prototype, "heading");
92
+ __decorateClass([
93
+ property({ type: Array, converter: arrayAttrConverter((v) => v) })
94
+ ], URefCard.prototype, "tags");
95
+
96
+ export { URefCard };
@@ -0,0 +1,7 @@
1
+ import { URefCard } from './URefCard.component.js';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ "u-ref-card": URefCard;
5
+ }
6
+ }
7
+ export { URefCard };
@@ -0,0 +1,5 @@
1
+ import { URefCard } from './URefCard.component.js';
2
+
3
+ URefCard.define("u-ref-card");
4
+
5
+ export { URefCard };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;