@iyulab/chat-components 0.2.0 → 0.4.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 (113) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/assets/action-prompt.md.js +3 -0
  3. package/dist/assets/widget-prompt.md.js +3 -0
  4. package/dist/components/actions/UQuestionAction.component.d.ts +18 -0
  5. package/dist/components/actions/UQuestionAction.component.js +58 -0
  6. package/dist/components/actions/UQuestionAction.d.ts +7 -0
  7. package/dist/components/actions/UQuestionAction.js +5 -0
  8. package/dist/components/actions/UQuestionAction.styles.js +45 -0
  9. package/dist/components/blocks/UCodeBlock.component.d.ts +5 -3
  10. package/dist/components/blocks/UCodeBlock.component.js +14 -2
  11. package/dist/components/blocks/UCodeBlock.styles.js +6 -0
  12. package/dist/components/blocks/UFilesBlock.component.d.ts +22 -0
  13. package/dist/components/blocks/UFilesBlock.component.js +192 -0
  14. package/dist/components/blocks/UFilesBlock.d.ts +7 -0
  15. package/dist/components/blocks/UFilesBlock.js +5 -0
  16. package/dist/components/blocks/UFilesBlock.styles.d.ts +1 -0
  17. package/dist/components/blocks/UFilesBlock.styles.js +206 -0
  18. package/dist/components/blocks/UJsonBlock.component.d.ts +3 -3
  19. package/dist/components/blocks/UJsonBlock.component.js +2 -2
  20. package/dist/components/blocks/UMarkedBlock.component.d.ts +19 -24
  21. package/dist/components/blocks/UMarkedBlock.component.js +92 -62
  22. package/dist/components/blocks/URefBlock.component.d.ts +17 -0
  23. package/dist/components/blocks/URefBlock.component.js +73 -0
  24. package/dist/components/blocks/URefBlock.d.ts +7 -0
  25. package/dist/components/blocks/URefBlock.js +5 -0
  26. package/dist/components/blocks/URefBlock.styles.d.ts +1 -0
  27. package/dist/components/blocks/URefBlock.styles.js +75 -0
  28. package/dist/components/blocks/UTableBlock.component.d.ts +49 -0
  29. package/dist/components/blocks/UTableBlock.component.js +228 -0
  30. package/dist/components/blocks/UTableBlock.d.ts +7 -0
  31. package/dist/components/blocks/UTableBlock.js +5 -0
  32. package/dist/components/blocks/UTableBlock.styles.d.ts +1 -0
  33. package/dist/components/blocks/UTableBlock.styles.js +134 -0
  34. package/dist/components/blocks/UTextBlock.component.d.ts +3 -3
  35. package/dist/components/blocks/UTextBlock.component.js +2 -2
  36. package/dist/components/blocks/UThinkBlock.component.d.ts +3 -3
  37. package/dist/components/blocks/UThinkBlock.component.js +2 -2
  38. package/dist/components/blocks/UToolBlock.component.d.ts +3 -3
  39. package/dist/components/blocks/UToolBlock.component.js +2 -2
  40. package/dist/components/buttons/UAttachButton.component.d.ts +3 -3
  41. package/dist/components/buttons/UAttachButton.component.js +2 -2
  42. package/dist/components/buttons/UCopyButton.component.d.ts +3 -3
  43. package/dist/components/buttons/UCopyButton.component.js +2 -2
  44. package/dist/components/buttons/UReportButton.component.d.ts +3 -3
  45. package/dist/components/buttons/UReportButton.component.js +2 -2
  46. package/dist/components/buttons/URetryButton.component.d.ts +3 -3
  47. package/dist/components/buttons/URetryButton.component.js +2 -2
  48. package/dist/components/buttons/UShareButton.component.d.ts +3 -3
  49. package/dist/components/buttons/UShareButton.component.js +2 -2
  50. package/dist/components/buttons/UVoteButton.component.d.ts +3 -3
  51. package/dist/components/buttons/UVoteButton.component.js +7 -4
  52. package/dist/components/message/UMessage.component.d.ts +7 -7
  53. package/dist/components/message/UMessage.component.js +16 -44
  54. package/dist/components/message/UMessage.styles.js +38 -11
  55. package/dist/components/prompt/UPrompt.component.d.ts +3 -3
  56. package/dist/components/prompt/UPrompt.component.js +2 -2
  57. package/dist/components/prompt/UPrompt.styles.js +28 -0
  58. package/dist/components/references/URefCard.component.d.ts +12 -7
  59. package/dist/components/references/URefCard.component.js +25 -12
  60. package/dist/components/references/URefCardGroup.component.d.ts +4 -3
  61. package/dist/components/references/URefCardGroup.component.js +3 -3
  62. package/dist/components/references/URefTag.component.d.ts +6 -4
  63. package/dist/components/references/URefTag.component.js +12 -7
  64. package/dist/components/widgets/UChartWidget.component.d.ts +36 -0
  65. package/dist/components/widgets/UChartWidget.component.js +180 -0
  66. package/dist/components/widgets/UChartWidget.d.ts +7 -0
  67. package/dist/components/widgets/UChartWidget.js +5 -0
  68. package/dist/components/widgets/UChartWidget.styles.d.ts +1 -0
  69. package/dist/components/widgets/UChartWidget.styles.js +86 -0
  70. package/dist/components/widgets/UImagesWidget.component.d.ts +30 -0
  71. package/dist/components/widgets/UImagesWidget.component.js +164 -0
  72. package/dist/components/widgets/UImagesWidget.d.ts +7 -0
  73. package/dist/components/widgets/UImagesWidget.js +5 -0
  74. package/dist/components/widgets/UImagesWidget.styles.d.ts +1 -0
  75. package/dist/components/widgets/UImagesWidget.styles.js +218 -0
  76. package/dist/components/widgets/UMapWidget.component.d.ts +20 -0
  77. package/dist/components/widgets/UMapWidget.component.js +65 -0
  78. package/dist/components/widgets/UMapWidget.d.ts +7 -0
  79. package/dist/components/widgets/UMapWidget.js +5 -0
  80. package/dist/components/widgets/UMapWidget.styles.d.ts +1 -0
  81. package/dist/components/widgets/UMapWidget.styles.js +47 -0
  82. package/dist/components/widgets/UVideoWidget.component.d.ts +21 -0
  83. package/dist/components/widgets/UVideoWidget.component.js +106 -0
  84. package/dist/components/widgets/UVideoWidget.d.ts +7 -0
  85. package/dist/components/widgets/UVideoWidget.js +5 -0
  86. package/dist/components/widgets/UVideoWidget.styles.d.ts +1 -0
  87. package/dist/components/widgets/UVideoWidget.styles.js +36 -0
  88. package/dist/components/widgets/UWidget.component.d.ts +43 -0
  89. package/dist/components/widgets/UWidget.component.js +140 -0
  90. package/dist/components/widgets/UWidget.d.ts +7 -0
  91. package/dist/components/widgets/UWidget.js +5 -0
  92. package/dist/components/widgets/UWidget.styles.d.ts +1 -0
  93. package/dist/components/widgets/UWidget.styles.js +33 -0
  94. package/dist/index.d.ts +15 -2
  95. package/dist/index.js +32 -12
  96. package/dist/types/Actions.d.ts +24 -0
  97. package/dist/types/Actions.js +34 -0
  98. package/dist/types/BlockItem.d.ts +41 -4
  99. package/dist/types/JsonSchema.d.ts +59 -0
  100. package/dist/types/{BlockReference.d.ts → References.d.ts} +6 -10
  101. package/dist/types/Widgets.d.ts +34 -0
  102. package/dist/types/Widgets.js +115 -0
  103. package/dist/utilities/ActionPromptBuilder.d.ts +40 -0
  104. package/dist/utilities/ActionPromptBuilder.js +93 -0
  105. package/dist/utilities/WidgetPromptBuilder.d.ts +28 -0
  106. package/dist/utilities/WidgetPromptBuilder.js +87 -0
  107. package/package.json +13 -13
  108. package/dist/components/loaders/UDotLoader.component.d.ts +0 -9
  109. package/dist/components/loaders/UDotLoader.component.js +0 -23
  110. package/dist/components/loaders/UDotLoader.d.ts +0 -7
  111. package/dist/components/loaders/UDotLoader.js +0 -5
  112. package/dist/components/loaders/UDotLoader.styles.js +0 -50
  113. /package/dist/components/{loaders/UDotLoader.styles.d.ts → actions/UQuestionAction.styles.d.ts} +0 -0
@@ -1,9 +1,9 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /**
3
3
  * 메시지 신고 버튼 컴포넌트입니다.
4
4
  */
5
- export declare class UReportButton extends BaseElement {
5
+ export declare class UReportButton extends UElement {
6
6
  static styles: import('lit').CSSResultGroup[];
7
- static dependencies: Record<string, typeof BaseElement>;
7
+ static dependencies: Record<string, typeof UElement>;
8
8
  render(): import('lit-html').TemplateResult<1>;
9
9
  }
@@ -1,11 +1,11 @@
1
1
  import { html } from 'lit';
2
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
3
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
4
4
  import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
5
5
  import { UTooltip } from '@iyulab/components/dist/components/tooltip/UTooltip.component.js';
6
6
  import { styles } from './UReportButton.styles.js';
7
7
 
8
- class UReportButton extends BaseElement {
8
+ class UReportButton extends UElement {
9
9
  static {
10
10
  this.styles = [super.styles, styles];
11
11
  }
@@ -1,10 +1,10 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /**
3
3
  * 메시지 재시도 버튼 컴포넌트입니다.
4
4
  */
5
- export declare class URetryButton extends BaseElement {
5
+ export declare class URetryButton extends UElement {
6
6
  static styles: import('lit').CSSResultGroup[];
7
- static dependencies: Record<string, typeof BaseElement>;
7
+ static dependencies: Record<string, typeof UElement>;
8
8
  /** 재생성 중인지 여부 */
9
9
  loading: boolean;
10
10
  render(): import('lit-html').TemplateResult<1>;
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
4
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
5
  import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
6
6
  import { UTooltip } from '@iyulab/components/dist/components/tooltip/UTooltip.component.js';
@@ -15,7 +15,7 @@ var __decorateClass = (decorators, target, key, kind) => {
15
15
  if (result) __defProp(target, key, result);
16
16
  return result;
17
17
  };
18
- class URetryButton extends BaseElement {
18
+ class URetryButton extends UElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  this.loading = false;
@@ -1,9 +1,9 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /**
3
3
  * 메시지 공유하기 버튼 컴포넌트입니다.
4
4
  */
5
- export declare class UShareButton extends BaseElement {
5
+ export declare class UShareButton extends UElement {
6
6
  static styles: import('lit').CSSResultGroup[];
7
- static dependencies: Record<string, typeof BaseElement>;
7
+ static dependencies: Record<string, typeof UElement>;
8
8
  render(): import('lit-html').TemplateResult<1>;
9
9
  }
@@ -1,11 +1,11 @@
1
1
  import { html } from 'lit';
2
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
3
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
4
4
  import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
5
5
  import { UTooltip } from '@iyulab/components/dist/components/tooltip/UTooltip.component.js';
6
6
  import { styles } from './UShareButton.styles.js';
7
7
 
8
- class UShareButton extends BaseElement {
8
+ class UShareButton extends UElement {
9
9
  static {
10
10
  this.styles = [super.styles, styles];
11
11
  }
@@ -1,12 +1,12 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /** 투표 상태 타입 */
3
3
  export type VoteValue = 'none' | 'up' | 'down';
4
4
  /**
5
5
  * 투표 버튼 컴포넌트입니다.
6
6
  */
7
- export declare class UVoteButton extends BaseElement {
7
+ export declare class UVoteButton extends UElement {
8
8
  static styles: import('lit').CSSResultGroup[];
9
- static dependencies: Record<string, typeof BaseElement>;
9
+ static dependencies: Record<string, typeof UElement>;
10
10
  /** 현재 투표 상태 */
11
11
  value: VoteValue;
12
12
  render(): import('lit-html').TemplateResult<1>;
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
4
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
5
  import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
6
6
  import { UTooltip } from '@iyulab/components/dist/components/tooltip/UTooltip.component.js';
@@ -15,7 +15,7 @@ var __decorateClass = (decorators, target, key, kind) => {
15
15
  if (result) __defProp(target, key, result);
16
16
  return result;
17
17
  };
18
- class UVoteButton extends BaseElement {
18
+ class UVoteButton extends UElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  this.value = "none";
@@ -57,8 +57,11 @@ class UVoteButton extends BaseElement {
57
57
  ></u-icon>
58
58
  </u-button>
59
59
 
60
- <u-tooltip for="u-button" placement="bottom" distance="8">
61
- <slot></slot>
60
+ <u-tooltip for=".up-btn" placement="bottom" distance="8">
61
+ <slot name="up"></slot>
62
+ </u-tooltip>
63
+ <u-tooltip for=".down-btn" placement="bottom" distance="8">
64
+ <slot name="down"></slot>
62
65
  </u-tooltip>
63
66
  `;
64
67
  }
@@ -1,19 +1,19 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
- import { BlockItem } from '../../types/BlockItem';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
2
  /** 메시지 variant 타입 */
4
3
  export type MessageVariant = 'default' | 'bubble';
5
4
  /** 메시지 위치 타입 */
6
5
  export type MessagePosition = 'left' | 'right';
6
+ /** 메시지 너비 타입 */
7
+ export type MessageFit = 'full' | 'auto';
7
8
  /**
8
9
  * 채팅 메시지 컴포넌트입니다.
9
- * 다양한 유형의 블록 아이템과 인용 출처를 렌더링할 수 있습니다.
10
+ * 슬롯을 통해 다양한 블록 컴포넌트를 자유롭게 배치할 수 있습니다.
10
11
  */
11
- export declare class UMessage extends BaseElement {
12
+ export declare class UMessage extends UElement {
12
13
  static styles: import('lit').CSSResultGroup[];
13
- static dependencies: Record<string, typeof BaseElement>;
14
+ static dependencies: Record<string, typeof UElement>;
15
+ loading: boolean;
14
16
  variant: MessageVariant;
15
17
  position: MessagePosition;
16
- loading: boolean;
17
- items?: BlockItem[];
18
18
  render(): import('lit-html').TemplateResult<1>;
19
19
  }
@@ -1,12 +1,6 @@
1
- import { nothing, html } from 'lit';
1
+ import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { repeat } from 'lit/directives/repeat.js';
4
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
5
- import { UTextBlock } from '../blocks/UTextBlock.component.js';
6
- import { UMarkedBlock } from '../blocks/UMarkedBlock.component.js';
7
- import { UThinkBlock } from '../blocks/UThinkBlock.component.js';
8
- import { UToolBlock } from '../blocks/UToolBlock.component.js';
9
- import { UDotLoader } from '../loaders/UDotLoader.component.js';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
10
4
  import { styles } from './UMessage.styles.js';
11
5
 
12
6
  var __defProp = Object.defineProperty;
@@ -18,67 +12,45 @@ var __decorateClass = (decorators, target, key, kind) => {
18
12
  if (result) __defProp(target, key, result);
19
13
  return result;
20
14
  };
21
- class UMessage extends BaseElement {
15
+ class UMessage extends UElement {
22
16
  constructor() {
23
17
  super(...arguments);
18
+ this.loading = false;
24
19
  this.variant = "default";
25
20
  this.position = "left";
26
- this.loading = false;
27
21
  }
28
22
  static {
29
23
  this.styles = [super.styles, styles];
30
24
  }
31
25
  static {
32
- this.dependencies = {
33
- "u-text-block": UTextBlock,
34
- "u-marked-block": UMarkedBlock,
35
- "u-think-block": UThinkBlock,
36
- "u-tool-block": UToolBlock,
37
- "u-dot-loader": UDotLoader
38
- };
26
+ this.dependencies = {};
39
27
  }
40
28
  render() {
41
29
  return html`
42
30
  <slot name="header"></slot>
43
-
31
+
44
32
  <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>
33
+ <slot></slot>
34
+ <svg class="dot-loader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
35
+ ?hidden=${!this.loading}>
36
+ <circle class="d0" cx="4" cy="12" r="3" />
37
+ <circle class="d1" cx="12" cy="12" r="3" />
38
+ <circle class="d2" cx="20" cy="12" r="3" />
39
+ </svg>
65
40
  </div>
66
41
 
67
42
  <slot name="footer" ?hidden=${this.loading}></slot>
68
43
  `;
69
44
  }
70
45
  }
46
+ __decorateClass([
47
+ property({ type: Boolean, reflect: true })
48
+ ], UMessage.prototype, "loading");
71
49
  __decorateClass([
72
50
  property({ type: String, reflect: true })
73
51
  ], UMessage.prototype, "variant");
74
52
  __decorateClass([
75
53
  property({ type: String, reflect: true })
76
54
  ], UMessage.prototype, "position");
77
- __decorateClass([
78
- property({ type: Boolean, reflect: true })
79
- ], UMessage.prototype, "loading");
80
- __decorateClass([
81
- property({ type: Array })
82
- ], UMessage.prototype, "items");
83
55
 
84
56
  export { UMessage };
@@ -2,17 +2,11 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
+ width: auto;
6
+ max-width: 100%;
5
7
  display: flex;
6
8
  flex-direction: column;
7
9
  }
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
10
  :host([position="left"]) {
17
11
  align-self: flex-start;
18
12
  align-items: flex-start;
@@ -44,9 +38,42 @@ const styles = css`
44
38
  border-bottom-right-radius: 4px;
45
39
  }
46
40
 
47
- u-dot-loader {
48
- font-size: 24px;
49
- color: var(--u-neutral-800, #6b7280);
41
+ .dot-loader {
42
+ width: 24px;
43
+ height: 24px;
44
+ fill: var(--u-neutral-800, #6b7280);
45
+ }
46
+ .dot-loader circle {
47
+ animation: bounce 1.05s infinite;
48
+ transform-box: fill-box;
49
+ transform-origin: center;
50
+ }
51
+ .dot-loader circle.d1 {
52
+ animation-delay: 0.1s;
53
+ }
54
+ .dot-loader circle.d2 {
55
+ animation-delay: 0.2s;
56
+ }
57
+
58
+ @media (prefers-reduced-motion: reduce) {
59
+ .dot-loader circle {
60
+ animation: none;
61
+ transform: none;
62
+ }
63
+ }
64
+
65
+ @keyframes bounce {
66
+ 0%,57.14% {
67
+ animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
68
+ transform: translateY(0);
69
+ }
70
+ 28.57% {
71
+ animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
72
+ transform: translateY(-6px);
73
+ }
74
+ 100% {
75
+ transform: translateY(0);
76
+ }
50
77
  }
51
78
  `;
52
79
 
@@ -1,11 +1,11 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /**
3
3
  * 채팅 입력 컴포넌트입니다.
4
4
  * 텍스트 입력 영역과 우측에 액션 버튼을 배치할 수 있는 슬롯을 제공합니다.
5
5
  */
6
- export declare class UPrompt extends BaseElement {
6
+ export declare class UPrompt extends UElement {
7
7
  static styles: import('lit').CSSResultGroup[];
8
- static dependencies: Record<string, typeof BaseElement>;
8
+ static dependencies: Record<string, typeof UElement>;
9
9
  /** 로딩 상태 여부 */
10
10
  loading: boolean;
11
11
  /** 최소 행 수 */
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
4
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
5
  import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
6
6
  import { UTextBlock } from '../blocks/UTextBlock.component.js';
@@ -15,7 +15,7 @@ var __decorateClass = (decorators, target, key, kind) => {
15
15
  if (result) __defProp(target, key, result);
16
16
  return result;
17
17
  };
18
- class UPrompt extends BaseElement {
18
+ class UPrompt extends UElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  this.loading = false;
@@ -2,6 +2,7 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
+ position: relative;
5
6
  display: flex;
6
7
  flex-direction: column;
7
8
  padding: 12px;
@@ -14,6 +15,28 @@ const styles = css`
14
15
  border-color: var(--u-neutral-400, #9ca3af);
15
16
  box-shadow: 0 0 0 1px var(--u-neutral-200, #9ca3af);
16
17
  }
18
+ :host([loading])::before {
19
+ content: '';
20
+ position: absolute;
21
+ inset: -2px;
22
+ border-radius: 10px;
23
+ padding: 2px;
24
+ background: linear-gradient(90deg,
25
+ transparent 0%,
26
+ transparent 25%,
27
+ #f9a8d4 45%,
28
+ #fbbf24 55%,
29
+ transparent 75%,
30
+ transparent 100%
31
+ );
32
+ background-size: 300% 100%;
33
+ animation: border-shimmer 2s linear infinite;
34
+ -webkit-mask:
35
+ linear-gradient(#fff 0 0) content-box,
36
+ linear-gradient(#fff 0 0);
37
+ -webkit-mask-composite: xor;
38
+ mask-composite: exclude;
39
+ }
17
40
 
18
41
  u-text-block {
19
42
  flex: 1;
@@ -37,6 +60,11 @@ const styles = css`
37
60
  opacity: 0.5;
38
61
  cursor: not-allowed;
39
62
  }
63
+
64
+ @keyframes border-shimmer {
65
+ 0% { background-position: 100% 0; }
66
+ 100% { background-position: 0% 0; }
67
+ }
40
68
  `;
41
69
 
42
70
  export { styles };
@@ -1,22 +1,27 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
+ import { UJsonElement } from '@iyulab/components/dist/components/UJsonElement.js';
2
3
  /**
3
4
  * 참조 소스를 카드 형태로 표시하는 공통 컴포넌트입니다.
4
5
  * Web과 Document 타입 모두 지원합니다.
5
6
  */
6
- export declare class URefCard extends BaseElement {
7
- static styles: import('lit').CSSResultGroup[];
8
- static dependencies: Record<string, typeof BaseElement>;
7
+ export declare class URefCard extends UJsonElement {
8
+ static styles: (import('lit').CSSResult | import('lit').CSSResultGroup[])[];
9
+ static dependencies: Record<string, typeof UElement>;
9
10
  /** 카드 타입 (web 또는 document) */
10
11
  type: 'web' | 'document';
11
12
  /** 외부 링크 URL */
12
- href: string;
13
+ url?: string;
13
14
  /** 카드 타이틀 */
14
- heading?: string;
15
+ title: string;
16
+ /** 카드 본문 스니펫 */
17
+ snippet?: string;
15
18
  /** 태그 목록 */
16
19
  tags?: string[];
17
20
  render(): import('lit-html').TemplateResult<1>;
21
+ /** 링크 클릭 핸들러 */
22
+ private handleAnchorClick;
18
23
  /** URL에서 Google의 파비콘 URL을 반환합니다. */
19
24
  private getFaviconUrl;
20
25
  /** URL에서 도메인 사이트 주소를 반환합니다. */
21
- private getPageTitle;
26
+ private getDomainName;
22
27
  }
@@ -2,7 +2,7 @@ import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { ifDefined } from 'lit/directives/if-defined.js';
4
4
  import { arrayAttrConverter } from '@iyulab/components/dist/utilities/converters.js';
5
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
5
+ import { UJsonElement } from '@iyulab/components/dist/components/UJsonElement.js';
6
6
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
7
7
  import { styles } from './URefCard.styles.js';
8
8
 
@@ -15,11 +15,11 @@ var __decorateClass = (decorators, target, key, kind) => {
15
15
  if (result) __defProp(target, key, result);
16
16
  return result;
17
17
  };
18
- class URefCard extends BaseElement {
18
+ class URefCard extends UJsonElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  this.type = "web";
22
- this.href = "#";
22
+ this.title = "";
23
23
  }
24
24
  static {
25
25
  this.styles = [super.styles, styles];
@@ -31,14 +31,15 @@ class URefCard extends BaseElement {
31
31
  }
32
32
  render() {
33
33
  return html`
34
- <a href="${this.href}" target="_blank" rel="noopener noreferrer">
34
+ <a href="${ifDefined(this.url)}" target="_blank" rel="noopener noreferrer"
35
+ @click=${this.handleAnchorClick}>
35
36
  <div class="header">
36
37
  <img class="favicon"
37
- src="${this.getFaviconUrl(this.href)}"
38
+ src="${this.getFaviconUrl(this.url)}"
38
39
  alt="favicon"
39
40
  />
40
- <div class="title" title="${ifDefined(this.heading)}">
41
- ${this.heading || this.getPageTitle(this.href)}
41
+ <div class="title">
42
+ ${this.title || this.getDomainName(this.url)}
42
43
  </div>
43
44
 
44
45
  <div style="flex: 1;"></div>
@@ -53,7 +54,7 @@ class URefCard extends BaseElement {
53
54
  </div>
54
55
 
55
56
  <div class="body">
56
- <slot></slot>
57
+ ${this.snippet}
57
58
  </div>
58
59
 
59
60
  <div class="footer" ?hidden=${!this.tags || this.tags.length === 0}>
@@ -62,8 +63,16 @@ class URefCard extends BaseElement {
62
63
  </a>
63
64
  `;
64
65
  }
66
+ /** 링크 클릭 핸들러 */
67
+ handleAnchorClick(e) {
68
+ if (!this.url) {
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ }
72
+ }
65
73
  /** URL에서 Google의 파비콘 URL을 반환합니다. */
66
74
  getFaviconUrl(url) {
75
+ if (!url) return `/favicon.ico`;
67
76
  try {
68
77
  const hostname = new URL(url).hostname;
69
78
  return `https://www.google.com/s2/favicons?sz=64&domain=${hostname}`;
@@ -72,11 +81,12 @@ class URefCard extends BaseElement {
72
81
  }
73
82
  }
74
83
  /** URL에서 도메인 사이트 주소를 반환합니다. */
75
- getPageTitle(url) {
84
+ getDomainName(url) {
85
+ if (!url) return "";
76
86
  try {
77
87
  return new URL(url).hostname;
78
88
  } catch {
79
- return "Unkown";
89
+ return "";
80
90
  }
81
91
  }
82
92
  }
@@ -85,10 +95,13 @@ __decorateClass([
85
95
  ], URefCard.prototype, "type");
86
96
  __decorateClass([
87
97
  property({ type: String })
88
- ], URefCard.prototype, "href");
98
+ ], URefCard.prototype, "url");
99
+ __decorateClass([
100
+ property({ type: String })
101
+ ], URefCard.prototype, "title");
89
102
  __decorateClass([
90
103
  property({ type: String })
91
- ], URefCard.prototype, "heading");
104
+ ], URefCard.prototype, "snippet");
92
105
  __decorateClass([
93
106
  property({ type: Array, converter: arrayAttrConverter((v) => v) })
94
107
  ], URefCard.prototype, "tags");
@@ -1,12 +1,13 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  import { URefCard } from './URefCard.component.js';
3
3
  /**
4
4
  * 여러 참조 카드를 그룹으로 표시하는 컴포넌트입니다.
5
5
  * 페이지네이션 기능을 제공하여 각 카드를 하나씩 탐색할 수 있습니다.
6
+ * 카드가 1개 이하인 경우 페이지네이션 UI는 자동으로 숨겨집니다.
6
7
  */
7
- export declare class URefCardGroup extends BaseElement {
8
+ export declare class URefCardGroup extends UElement {
8
9
  static styles: import('lit').CSSResultGroup[];
9
- static dependencies: Record<string, typeof BaseElement>;
10
+ static dependencies: Record<string, typeof UElement>;
10
11
  /** slot으로 받은 카드 엘리먼트들 */
11
12
  cards: URefCard[];
12
13
  /** 현재 표시 중인 카드의 인덱스 */
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { state } from 'lit/decorators.js';
3
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
4
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
5
  import { URefCard } from './URefCard.component.js';
6
6
  import { styles } from './URefCardGroup.styles.js';
@@ -14,7 +14,7 @@ var __decorateClass = (decorators, target, key, kind) => {
14
14
  if (result) __defProp(target, key, result);
15
15
  return result;
16
16
  };
17
- class URefCardGroup extends BaseElement {
17
+ class URefCardGroup extends UElement {
18
18
  constructor() {
19
19
  super(...arguments);
20
20
  this.cards = [];
@@ -31,7 +31,7 @@ class URefCardGroup extends BaseElement {
31
31
  }
32
32
  render() {
33
33
  return html`
34
- <div class="header">
34
+ <div class="header" ?hidden=${this.cards.length <= 1}>
35
35
  <button class="nav-button"
36
36
  @click=${this.handlePreviousButtonClick}>
37
37
  <u-icon lib="internal" name="chevron-left"></u-icon>
@@ -1,11 +1,13 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
1
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
2
2
  /**
3
3
  * 인용 태그 컴포넌트입니다.
4
4
  */
5
- export declare class URefTag extends BaseElement {
5
+ export declare class URefTag extends UElement {
6
6
  static styles: import('lit').CSSResultGroup[];
7
- static dependencies: Record<string, typeof BaseElement>;
7
+ static dependencies: Record<string, typeof UElement>;
8
8
  /** 인용 출처 소스 데이터 */
9
- href: string;
9
+ href?: string;
10
10
  render(): import('lit-html').TemplateResult<1>;
11
+ /** 링크 클릭 핸들러 */
12
+ private handleAnchorClick;
11
13
  }
@@ -1,6 +1,7 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
5
  import { UTooltip } from '@iyulab/components/dist/components/tooltip/UTooltip.component.js';
5
6
  import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
6
7
  import { styles } from './URefTag.styles.js';
@@ -14,11 +15,7 @@ var __decorateClass = (decorators, target, key, kind) => {
14
15
  if (result) __defProp(target, key, result);
15
16
  return result;
16
17
  };
17
- class URefTag extends BaseElement {
18
- constructor() {
19
- super(...arguments);
20
- this.href = "#";
21
- }
18
+ class URefTag extends UElement {
22
19
  static {
23
20
  this.styles = [super.styles, styles];
24
21
  }
@@ -30,7 +27,8 @@ class URefTag extends BaseElement {
30
27
  }
31
28
  render() {
32
29
  return html`
33
- <a href="${this.href}" target="_blank" rel="noopener noreferrer">
30
+ <a href="${ifDefined(this.href)}" target="_blank" rel="noopener noreferrer"
31
+ @click=${this.handleAnchorClick}>
34
32
  <slot></slot>
35
33
  </a>
36
34
 
@@ -41,6 +39,13 @@ class URefTag extends BaseElement {
41
39
  </u-tooltip>
42
40
  `;
43
41
  }
42
+ /** 링크 클릭 핸들러 */
43
+ handleAnchorClick(e) {
44
+ if (!this.href) {
45
+ e.preventDefault();
46
+ e.stopPropagation();
47
+ }
48
+ }
44
49
  }
45
50
  __decorateClass([
46
51
  property({ type: String })