@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
@@ -0,0 +1,36 @@
1
+ import { nothing, PropertyValues } from 'lit';
2
+ import { ChartType, ChartData, ChartOptions } from 'chart.js/auto';
3
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
+ /**
5
+ * 차트 위젯 컴포넌트
6
+ * Chart.js를 사용하여 다양한 차트를 렌더링
7
+ */
8
+ export declare class UChartWidget extends UElement {
9
+ static styles: import('lit').CSSResultGroup[];
10
+ static dependencies: Record<string, typeof UElement>;
11
+ /** 차트 유형 (bar, line, pie 등) */
12
+ type?: ChartType;
13
+ /** 차트 데이터 */
14
+ data?: ChartData;
15
+ /** 차트 옵션 */
16
+ options?: ChartOptions;
17
+ private canvas?;
18
+ private viewport?;
19
+ /** 차트 생성 에러 메시지 */
20
+ private error;
21
+ private chartjs;
22
+ private observer?;
23
+ connectedCallback(): void;
24
+ disconnectedCallback(): void;
25
+ protected updated(changedProperties: PropertyValues): void;
26
+ render(): import('lit-html').TemplateResult<1> | typeof nothing;
27
+ /** Chart.js로 차트 생성 */
28
+ private createChart;
29
+ /** 기존 차트 인스턴스 제거 */
30
+ private destroyChart;
31
+ /** 현재 테마의 CSS 변수를 읽어 Chart.defaults에 전역 적용 */
32
+ private applyTheme;
33
+ private handleDownloadPNG;
34
+ private handleDownloadJSON;
35
+ private handleFullscreen;
36
+ }
@@ -0,0 +1,180 @@
1
+ import { nothing, html } from 'lit';
2
+ import { property, query, state } from 'lit/decorators.js';
3
+ import { Chart } from 'chart.js/auto';
4
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
5
+ import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
6
+ import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
7
+ import { styles } from './UChartWidget.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 UChartWidget extends UElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.error = null;
22
+ this.chartjs = null;
23
+ }
24
+ static {
25
+ this.styles = [super.styles, styles];
26
+ }
27
+ static {
28
+ this.dependencies = {
29
+ "u-icon": UIcon,
30
+ "u-button": UButton
31
+ };
32
+ }
33
+ connectedCallback() {
34
+ super.connectedCallback();
35
+ this.observer = new MutationObserver(() => {
36
+ this.applyTheme();
37
+ this.createChart();
38
+ });
39
+ this.observer.observe(document.documentElement, {
40
+ attributes: true,
41
+ attributeFilter: ["theme"]
42
+ });
43
+ }
44
+ disconnectedCallback() {
45
+ super.disconnectedCallback();
46
+ this.observer?.disconnect();
47
+ this.destroyChart();
48
+ }
49
+ updated(changedProperties) {
50
+ super.updated(changedProperties);
51
+ if (changedProperties.has("data") || changedProperties.has("type") || changedProperties.has("options")) {
52
+ this.createChart();
53
+ }
54
+ }
55
+ render() {
56
+ if (!this.data) return nothing;
57
+ return html`
58
+ <div class="toolbar">
59
+ <div class="toolbar-left"></div>
60
+ <div class="toolbar-right">
61
+ <u-button title="PNG Download" @click=${this.handleDownloadPNG}>
62
+ PNG
63
+ <u-icon slot="suffix" lib="internal" name="download"></u-icon>
64
+ </u-button>
65
+ <u-button title="JSON Download" @click=${this.handleDownloadJSON}>
66
+ JSON
67
+ <u-icon slot="suffix" lib="internal" name="download"></u-icon>
68
+ </u-button>
69
+ <u-button title="Full Screen" @click=${this.handleFullscreen}>
70
+ <u-icon lib="internal" name="box-arrow-up-right"></u-icon>
71
+ </u-button>
72
+ </div>
73
+ </div>
74
+ <div class="viewport">
75
+ <canvas></canvas>
76
+ <div class="error-overlay" ?hidden=${!this.error}>
77
+ <u-icon lib="internal" name="exclamation-triangle-fill"></u-icon>
78
+ <span>${this.error}</span>
79
+ </div>
80
+ </div>
81
+ `;
82
+ }
83
+ /** Chart.js로 차트 생성 */
84
+ createChart() {
85
+ if (!this.canvas) return;
86
+ if (!this.type || !this.data) return;
87
+ this.destroyChart();
88
+ this.error = null;
89
+ const ctx = this.canvas.getContext("2d");
90
+ if (!ctx) {
91
+ this.error = "Canvas 2D context를 가져올 수 없습니다.";
92
+ return;
93
+ }
94
+ try {
95
+ this.applyTheme();
96
+ this.chartjs = new Chart(ctx, {
97
+ type: this.type,
98
+ data: this.data,
99
+ options: {
100
+ responsive: true,
101
+ maintainAspectRatio: true,
102
+ ...this.options
103
+ }
104
+ });
105
+ } catch (e) {
106
+ this.error = e instanceof Error ? e.message : String(e);
107
+ }
108
+ }
109
+ /** 기존 차트 인스턴스 제거 */
110
+ destroyChart() {
111
+ if (this.chartjs) {
112
+ this.chartjs.destroy();
113
+ this.chartjs = null;
114
+ }
115
+ }
116
+ /** 현재 테마의 CSS 변수를 읽어 Chart.defaults에 전역 적용 */
117
+ applyTheme() {
118
+ const css = (v) => getComputedStyle(this).getPropertyValue(v).trim();
119
+ const textColor = css("--u-txt-color");
120
+ const weakColor = css("--u-txt-color-weak");
121
+ const borderColor = css("--u-border-color");
122
+ const bgColor = css("--u-bg-color");
123
+ Chart.defaults.color = textColor;
124
+ Chart.defaults.borderColor = borderColor;
125
+ Chart.defaults.plugins.tooltip.backgroundColor = bgColor;
126
+ Chart.defaults.plugins.tooltip.titleColor = textColor;
127
+ Chart.defaults.plugins.tooltip.bodyColor = weakColor;
128
+ Chart.defaults.plugins.tooltip.borderColor = borderColor;
129
+ Chart.defaults.plugins.tooltip.borderWidth = 1;
130
+ Chart.defaults.scale.ticks.color = weakColor;
131
+ Chart.defaults.scale.grid.color = borderColor;
132
+ }
133
+ handleDownloadPNG() {
134
+ if (!this.chartjs) return;
135
+ const url = this.chartjs.toBase64Image("image/png", 1);
136
+ const a = document.createElement("a");
137
+ a.href = url;
138
+ a.download = "chart-image.png";
139
+ a.click();
140
+ }
141
+ handleDownloadJSON() {
142
+ if (!this.data) return;
143
+ const json = JSON.stringify(this.data, null, 2);
144
+ const blob = new Blob([json], { type: "application/json;charset=utf-8;" });
145
+ const url = URL.createObjectURL(blob);
146
+ const a = document.createElement("a");
147
+ a.href = url;
148
+ a.download = "chart-data.json";
149
+ a.click();
150
+ URL.revokeObjectURL(url);
151
+ }
152
+ handleFullscreen() {
153
+ const target = this.viewport ?? this;
154
+ if (document.fullscreenElement) {
155
+ document.exitFullscreen();
156
+ } else {
157
+ target.requestFullscreen?.();
158
+ }
159
+ }
160
+ }
161
+ __decorateClass([
162
+ property({ type: String })
163
+ ], UChartWidget.prototype, "type");
164
+ __decorateClass([
165
+ property({ type: Object })
166
+ ], UChartWidget.prototype, "data");
167
+ __decorateClass([
168
+ property({ type: Object })
169
+ ], UChartWidget.prototype, "options");
170
+ __decorateClass([
171
+ query("canvas")
172
+ ], UChartWidget.prototype, "canvas");
173
+ __decorateClass([
174
+ query(".viewport")
175
+ ], UChartWidget.prototype, "viewport");
176
+ __decorateClass([
177
+ state()
178
+ ], UChartWidget.prototype, "error");
179
+
180
+ export { UChartWidget };
@@ -0,0 +1,7 @@
1
+ import { UChartWidget } from './UChartWidget.component.js';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ "u-chart-widget": UChartWidget;
5
+ }
6
+ }
7
+ export { UChartWidget };
@@ -0,0 +1,5 @@
1
+ import { UChartWidget } from './UChartWidget.component.js';
2
+
3
+ UChartWidget.define("u-chart-widget");
4
+
5
+ export { UChartWidget };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;
@@ -0,0 +1,86 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ :host {
5
+ margin: 0.75em auto;
6
+ display: block;
7
+ width: 100%;
8
+ background: var(--u-bg-color);
9
+ border: 1px solid var(--u-border-color);
10
+ border-radius: 8px;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .toolbar {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ padding: 6px 12px;
19
+ background-color: var(--u-neutral-100);
20
+ border-bottom: 1px solid var(--u-border-color);
21
+ gap: 8px;
22
+ }
23
+
24
+ .toolbar-left {
25
+ flex: 1;
26
+ }
27
+
28
+ .toolbar-right {
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 6px;
32
+ flex-shrink: 0;
33
+ }
34
+
35
+ .toolbar-right u-button {
36
+ font-size: 12px;
37
+ }
38
+ .toolbar-right u-button[title="Full Screen"] {
39
+ font-size: 15px;
40
+ }
41
+
42
+ .viewport {
43
+ position: relative;
44
+ padding: 1em;
45
+ }
46
+
47
+ .viewport:fullscreen {
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ background: var(--u-bg-color);
52
+ padding: 2em;
53
+ }
54
+ .viewport:fullscreen canvas {
55
+ max-width: 90vw;
56
+ max-height: 90vh;
57
+ }
58
+
59
+ canvas {
60
+ width: 100% !important;
61
+ min-height: 60px;
62
+ }
63
+
64
+ .error-overlay {
65
+ position: absolute;
66
+ bottom: 10px;
67
+ right: 10px;
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 6px;
71
+ padding: 6px 10px;
72
+ background: var(--u-red-0);
73
+ border: 1px solid var(--u-red-200);
74
+ border-radius: 6px;
75
+ color: var(--u-red-800);
76
+ font-size: 12px;
77
+ pointer-events: none;
78
+ }
79
+
80
+ .error-overlay u-icon {
81
+ color: var(--u-red-600);
82
+ flex-shrink: 0;
83
+ }
84
+ `;
85
+
86
+ export { styles };
@@ -0,0 +1,30 @@
1
+ import { nothing } from 'lit';
2
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
+ export interface ImageSlide {
4
+ src: string;
5
+ alt?: string;
6
+ caption?: string;
7
+ }
8
+ /**
9
+ * 이미지 갤러리 위젯 컴포넌트
10
+ * u-carousel 기반 가로 슬라이드 + 슬라이딩 라이트박스
11
+ */
12
+ export declare class UImagesWidget extends UElement {
13
+ static styles: import('lit').CSSResultGroup[];
14
+ static dependencies: Record<string, typeof UElement>;
15
+ /** 이미지 슬라이드 배열 */
16
+ items: ImageSlide[];
17
+ /** 라이트박스에서 현재 열려있는 이미지 인덱스, null이면 라이트박스 닫힘 */
18
+ private index;
19
+ connectedCallback(): void;
20
+ disconnectedCallback(): void;
21
+ render(): import('lit-html').TemplateResult<1> | typeof nothing;
22
+ private renderLightbox;
23
+ open: (i: number) => void;
24
+ close: () => void;
25
+ prev: () => void;
26
+ next: () => void;
27
+ private handlePrevClick;
28
+ private handleNextClick;
29
+ private handleKeyDown;
30
+ }
@@ -0,0 +1,164 @@
1
+ import { nothing, html } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { repeat } from 'lit/directives/repeat.js';
4
+ import { UElement } from '@iyulab/components/dist/components/UElement.js';
5
+ import { UCarousel } from '@iyulab/components/dist/components/carousel/UCarousel.component.js';
6
+ import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
7
+ import { styles } from './UImagesWidget.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 UImagesWidget extends UElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.items = [];
22
+ this.index = null;
23
+ this.open = (i) => {
24
+ this.index = i;
25
+ };
26
+ this.close = () => {
27
+ this.index = null;
28
+ };
29
+ this.prev = () => {
30
+ if (this.index !== null && this.index > 0) {
31
+ this.index--;
32
+ }
33
+ };
34
+ this.next = () => {
35
+ if (this.index !== null && this.index < this.items.length - 1) {
36
+ this.index++;
37
+ }
38
+ };
39
+ this.handlePrevClick = (e) => {
40
+ e.stopPropagation();
41
+ this.prev();
42
+ };
43
+ this.handleNextClick = (e) => {
44
+ e.stopPropagation();
45
+ this.next();
46
+ };
47
+ this.handleKeyDown = (e) => {
48
+ if (this.index === null) return;
49
+ if (e.key === "Escape") this.close();
50
+ else if (e.key === "ArrowLeft") this.prev();
51
+ else if (e.key === "ArrowRight") this.next();
52
+ };
53
+ }
54
+ static {
55
+ this.styles = [super.styles, styles];
56
+ }
57
+ static {
58
+ this.dependencies = {
59
+ "u-carousel": UCarousel,
60
+ "u-icon": UIcon
61
+ };
62
+ }
63
+ connectedCallback() {
64
+ super.connectedCallback();
65
+ document.addEventListener("keydown", this.handleKeyDown);
66
+ }
67
+ disconnectedCallback() {
68
+ document.removeEventListener("keydown", this.handleKeyDown);
69
+ super.disconnectedCallback();
70
+ }
71
+ render() {
72
+ if (!this.items?.length) return nothing;
73
+ const count = this.items.length;
74
+ return html`
75
+ <u-carousel
76
+ .loop=${false}
77
+ .navigation=${false}
78
+ .pagination=${true}
79
+ .draggable=${true}
80
+ .slidesPerView=${Math.min(count, 3)}
81
+ .gap=${8}
82
+ >
83
+ ${repeat(this.items, (item, i) => html`
84
+ <div class="slide"
85
+ @click=${() => this.open(i)}>
86
+ <img
87
+ src=${item.src}
88
+ alt=${item.alt || ""}
89
+ loading="lazy"
90
+ />
91
+ <div class="caption"
92
+ ?hidden=${!item.caption}>
93
+ ${item.caption}
94
+ </div>
95
+ </div>
96
+ `)}
97
+ </u-carousel>
98
+
99
+ ${this.renderLightbox()}
100
+ `;
101
+ }
102
+ renderLightbox() {
103
+ const idx = this.index;
104
+ if (idx === null) return nothing;
105
+ if (idx < 0 || idx >= this.items.length) return nothing;
106
+ const item = this.items[idx];
107
+ if (!item) return nothing;
108
+ const total = this.items.length;
109
+ const translateX = `calc(15vw - ${idx} * (70vw + 16px))`;
110
+ return html`
111
+ <div class="lb-overlay">
112
+
113
+ <!-- 상단: 카운터(중앙) + 닫기 버튼(우측) -->
114
+ <header class="lb-header">
115
+ <div class="lb-counter" ?hidden=${total <= 1}>
116
+ ${idx + 1} / ${total}
117
+ </div>
118
+ <button class="lb-close" @click=${this.close}>
119
+ <u-icon lib="internal" name="x-lg"></u-icon>
120
+ </button>
121
+ </header>
122
+
123
+ <!-- 중앙: 뷰포트 + 이전/다음 버튼(absolute 오버레이) -->
124
+ <div class="lb-body">
125
+ <div class="lb-viewport">
126
+ <div class="lb-track" style="transform:translateX(${translateX})">
127
+ ${repeat(this.items, (img, i) => html`
128
+ <div class="lb-slide" ?active=${i === idx}>
129
+ <img src=${img.src} alt=${img.alt || ""} />
130
+ </div>
131
+ `)}
132
+ </div>
133
+ </div>
134
+
135
+ <button class="lb-nav prev"
136
+ ?hidden=${idx <= 0}
137
+ @click=${this.handlePrevClick}>
138
+ <u-icon lib="internal" name="chevron-left"></u-icon>
139
+ </button>
140
+
141
+ <button class="lb-nav next"
142
+ ?hidden=${idx >= total - 1}
143
+ @click=${this.handleNextClick}>
144
+ <u-icon lib="internal" name="chevron-right"></u-icon>
145
+ </button>
146
+ </div>
147
+
148
+ <!-- 하단: 캡션 -->
149
+ <footer class="lb-footer" ?hidden=${!item.caption}>
150
+ <p class="lb-caption">${item.caption}</p>
151
+ </footer>
152
+
153
+ </div>
154
+ `;
155
+ }
156
+ }
157
+ __decorateClass([
158
+ property({ type: Array })
159
+ ], UImagesWidget.prototype, "items");
160
+ __decorateClass([
161
+ state()
162
+ ], UImagesWidget.prototype, "index");
163
+
164
+ export { UImagesWidget };
@@ -0,0 +1,7 @@
1
+ import { UImagesWidget } from './UImagesWidget.component.js';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ "u-images-widget": UImagesWidget;
5
+ }
6
+ }
7
+ export { UImagesWidget };
@@ -0,0 +1,5 @@
1
+ import { UImagesWidget } from './UImagesWidget.component.js';
2
+
3
+ UImagesWidget.define("u-images-widget");
4
+
5
+ export { UImagesWidget };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;