hanbiro-react16-sdk 1.0.26 → 1.0.28

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 (46) hide show
  1. package/dist/components/ChatAIDraft/ChatList/LoadingDots.js +4 -3
  2. package/dist/components/ChatAIDraft/ChatList/MessageItem.js +4 -4
  3. package/dist/components/ChatAIDraft/ReplyPanel/BaseModal.d.ts +15 -0
  4. package/dist/components/ChatAIDraft/ReplyPanel/BaseModal.js +101 -0
  5. package/dist/components/ChatAIDraft/ReplyPanel/ContextPreviewModal.d.ts +13 -0
  6. package/dist/components/ChatAIDraft/ReplyPanel/ContextPreviewModal.js +63 -0
  7. package/dist/components/ChatAIDraft/ReplyPanel/EmptyState.d.ts +1 -8
  8. package/dist/components/ChatAIDraft/ReplyPanel/EmptyState.js +1 -217
  9. package/dist/components/ChatAIDraft/ReplyPanel/Header/SelectedChip.d.ts +10 -0
  10. package/dist/components/ChatAIDraft/ReplyPanel/Header/SelectedChip.js +79 -0
  11. package/dist/components/ChatAIDraft/ReplyPanel/Header/SourceCard.d.ts +8 -0
  12. package/dist/components/ChatAIDraft/ReplyPanel/Header/SourceCard.js +52 -0
  13. package/dist/components/ChatAIDraft/ReplyPanel/Header/index.d.ts +12 -0
  14. package/dist/components/ChatAIDraft/ReplyPanel/Header/index.js +135 -0
  15. package/dist/components/ChatAIDraft/ReplyPanel/MailListSelect.d.ts +1 -0
  16. package/dist/components/ChatAIDraft/ReplyPanel/MailListSelect.js +62 -149
  17. package/dist/components/ChatAIDraft/ReplyPanel/helper.js +1 -1
  18. package/dist/components/ChatAIDraft/ReplyPanel/index.d.ts +5 -1
  19. package/dist/components/ChatAIDraft/ReplyPanel/index.js +35 -196
  20. package/dist/components/Pagination/index.d.ts +20 -0
  21. package/dist/components/Pagination/index.js +131 -0
  22. package/dist/components/SummaryAIEmails/FilterTabs.d.ts +8 -0
  23. package/dist/components/SummaryAIEmails/FilterTabs.js +57 -0
  24. package/dist/components/SummaryAIEmails/LanguagePopover.d.ts +24 -0
  25. package/dist/components/SummaryAIEmails/LanguagePopover.js +110 -0
  26. package/dist/components/SummaryAIEmails/SummaryItem.d.ts +7 -0
  27. package/dist/components/SummaryAIEmails/SummaryItem.js +74 -0
  28. package/dist/components/SummaryAIEmails/TargetInfoBar.d.ts +9 -0
  29. package/dist/components/SummaryAIEmails/TargetInfoBar.js +81 -0
  30. package/dist/components/SummaryAIEmails/index.d.ts +34 -0
  31. package/dist/components/SummaryAIEmails/index.js +213 -0
  32. package/dist/components/SummaryAIEmails/types.d.ts +16 -0
  33. package/dist/components/SummaryAIEmails/utils.d.ts +11 -0
  34. package/dist/components/SummaryAIEmails/utils.js +46 -0
  35. package/dist/components/index.d.ts +2 -4
  36. package/dist/hanbiro-react16-sdk.style.css +7 -2
  37. package/dist/hanbiro-react16-sdk.umd.js +1959 -966
  38. package/dist/index.js +11 -13
  39. package/dist/node_modules/react-feather/dist/icons/arrow-down.js +73 -0
  40. package/dist/node_modules/react-feather/dist/icons/chevron-left.js +68 -0
  41. package/dist/node_modules/react-feather/dist/icons/chevron-right.js +68 -0
  42. package/dist/node_modules/react-feather/dist/icons/globe.js +77 -0
  43. package/dist/node_modules/react-feather/dist/icons/x.js +76 -0
  44. package/dist/utils/index.d.ts +1 -1
  45. package/dist/utils/url.js +0 -13
  46. package/package.json +1 -1
@@ -43,13 +43,13 @@ import { callAI } from "../helper.js";
43
43
  import ChatList from "../ChatList/index.js";
44
44
  import ChatInput from "../ChatInput.js";
45
45
  import EmptyState from "./EmptyState.js";
46
+ import ContextHeader from "./Header/index.js";
46
47
  import MailListSelect from "./MailListSelect.js";
48
+ import ContextPreviewModal from "./ContextPreviewModal.js";
47
49
  import { fetchMailView, fetchMailAiContext } from "./helper.js";
48
50
  import { LENGTH_OPTIONS, TONE_OPTIONS } from "../constants.js";
49
51
  import { AI_LANG_FLAGS } from "../../../constants/index.js";
50
52
  import v4 from "../../../node_modules/uuid/dist/esm-browser/v4.js";
51
- import Lock from "../../../node_modules/react-feather/dist/icons/lock.js";
52
- import Plus from "../../../node_modules/react-feather/dist/icons/plus.js";
53
53
  class ReplyPanel extends React.Component {
54
54
  constructor(props) {
55
55
  var _a;
@@ -98,6 +98,15 @@ class ReplyPanel extends React.Component {
98
98
  selectedMails: this.state.selectedMails.filter((m) => m.mid !== mid)
99
99
  });
100
100
  });
101
+ __publicField(this, "handlePreviewSelected", (mail) => {
102
+ this.setState({ preview: { mail, mode: "ai" } });
103
+ });
104
+ __publicField(this, "handlePreviewSource", (mail) => {
105
+ this.setState({ preview: { mail, mode: "html" } });
106
+ });
107
+ __publicField(this, "handlePreviewClose", () => {
108
+ this.setState({ preview: null });
109
+ });
101
110
  __publicField(this, "handleMessageChange", (value) => {
102
111
  this.setState({ message: value });
103
112
  });
@@ -177,6 +186,7 @@ class ReplyPanel extends React.Component {
177
186
  selectedMails: [],
178
187
  isLoadingSource: false,
179
188
  isLoadingSelected: false,
189
+ preview: null,
180
190
  message: "",
181
191
  messages: [],
182
192
  isSending: false,
@@ -189,189 +199,6 @@ class ReplyPanel extends React.Component {
189
199
  componentDidMount() {
190
200
  this.loadSourceMail();
191
201
  }
192
- renderContextHeader() {
193
- const { sourceMail, selectedMails } = this.state;
194
- return /* @__PURE__ */ React.createElement(
195
- "div",
196
- {
197
- style: {
198
- display: "flex",
199
- flexDirection: "column",
200
- gap: 8,
201
- paddingBottom: 12,
202
- borderBottom: "1px solid var(--border-light)",
203
- marginBottom: 12
204
- }
205
- },
206
- sourceMail && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, /* @__PURE__ */ React.createElement(
207
- "div",
208
- {
209
- style: {
210
- display: "flex",
211
- alignItems: "center",
212
- gap: 6,
213
- fontSize: 12,
214
- fontWeight: 600,
215
- color: "var(--text-primary)"
216
- }
217
- },
218
- /* @__PURE__ */ React.createElement("span", null, "Source context"),
219
- /* @__PURE__ */ React.createElement(
220
- "span",
221
- {
222
- style: {
223
- background: "var(--primary-main)",
224
- color: "var(--primary-contrasttext)",
225
- fontSize: 10,
226
- padding: "1px 6px",
227
- borderRadius: 999
228
- }
229
- },
230
- "1"
231
- ),
232
- /* @__PURE__ */ React.createElement(
233
- "span",
234
- {
235
- style: {
236
- display: "inline-flex",
237
- alignItems: "center",
238
- gap: 2,
239
- fontSize: 11,
240
- color: "var(--text-secondary)"
241
- }
242
- },
243
- /* @__PURE__ */ React.createElement(Lock, { size: 11 }),
244
- " Auto"
245
- )
246
- ), /* @__PURE__ */ React.createElement(
247
- "div",
248
- {
249
- style: {
250
- fontSize: 12,
251
- color: "var(--text-secondary)",
252
- whiteSpace: "nowrap",
253
- overflow: "hidden",
254
- textOverflow: "ellipsis"
255
- }
256
- },
257
- sourceMail.subject,
258
- " ·",
259
- " ",
260
- /* @__PURE__ */ React.createElement("span", { style: { color: "var(--text-primary)" } }, sourceMail.from_name)
261
- )),
262
- /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 6 } }, /* @__PURE__ */ React.createElement(
263
- "div",
264
- {
265
- style: {
266
- display: "flex",
267
- alignItems: "center",
268
- justifyContent: "space-between"
269
- }
270
- },
271
- /* @__PURE__ */ React.createElement(
272
- "div",
273
- {
274
- style: {
275
- display: "flex",
276
- alignItems: "center",
277
- gap: 6,
278
- fontSize: 12,
279
- fontWeight: 600,
280
- color: "var(--text-primary)"
281
- }
282
- },
283
- /* @__PURE__ */ React.createElement("span", null, "Selected context"),
284
- /* @__PURE__ */ React.createElement(
285
- "span",
286
- {
287
- style: {
288
- background: "var(--background-softGrey)",
289
- color: "var(--text-primary)",
290
- fontSize: 10,
291
- padding: "1px 6px",
292
- borderRadius: 999
293
- }
294
- },
295
- selectedMails.length
296
- )
297
- ),
298
- /* @__PURE__ */ React.createElement(
299
- "button",
300
- {
301
- type: "button",
302
- onClick: this.handleAddClick,
303
- className: "text-button primary"
304
- },
305
- /* @__PURE__ */ React.createElement(Plus, { size: 12 }),
306
- " Add"
307
- )
308
- ), selectedMails.length > 0 && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 } }, selectedMails.map((m, i) => /* @__PURE__ */ React.createElement(
309
- "div",
310
- {
311
- key: m.mid,
312
- style: {
313
- display: "inline-flex",
314
- alignItems: "center",
315
- gap: 6,
316
- padding: "4px 8px",
317
- borderRadius: 8,
318
- border: "1px solid var(--border-light)",
319
- background: "var(--primary-lighter)",
320
- fontSize: 11,
321
- maxWidth: 160
322
- }
323
- },
324
- /* @__PURE__ */ React.createElement(
325
- "span",
326
- {
327
- style: {
328
- width: 14,
329
- height: 14,
330
- borderRadius: "50%",
331
- background: "var(--primary-main)",
332
- color: "var(--primary-contrasttext)",
333
- fontSize: 9,
334
- fontWeight: 700,
335
- display: "inline-flex",
336
- alignItems: "center",
337
- justifyContent: "center",
338
- flexShrink: 0
339
- }
340
- },
341
- i + 1
342
- ),
343
- /* @__PURE__ */ React.createElement(
344
- "span",
345
- {
346
- style: {
347
- whiteSpace: "nowrap",
348
- overflow: "hidden",
349
- textOverflow: "ellipsis"
350
- }
351
- },
352
- m.subject || "(no subject)"
353
- ),
354
- /* @__PURE__ */ React.createElement(
355
- "button",
356
- {
357
- type: "button",
358
- onClick: () => this.handleRemoveSelected(m.mid),
359
- style: {
360
- border: "none",
361
- background: "transparent",
362
- cursor: "pointer",
363
- padding: 0,
364
- color: "var(--text-secondary)",
365
- display: "inline-flex",
366
- alignItems: "center",
367
- flexShrink: 0
368
- }
369
- },
370
- "×"
371
- )
372
- ))))
373
- );
374
- }
375
202
  render() {
376
203
  const { onApply, getEditorContent } = this.props;
377
204
  const {
@@ -385,7 +212,8 @@ class ReplyPanel extends React.Component {
385
212
  lang,
386
213
  tone,
387
214
  length,
388
- isLoadingSelected
215
+ isLoadingSelected,
216
+ preview
389
217
  } = this.state;
390
218
  if (view === "list") {
391
219
  return /* @__PURE__ */ React.createElement(
@@ -393,6 +221,7 @@ class ReplyPanel extends React.Component {
393
221
  {
394
222
  accountEmail,
395
223
  initialSelected: selectedMails.map((m) => m.mid),
224
+ isConfirming: isLoadingSelected,
396
225
  onCancel: this.handleListCancel,
397
226
  onConfirm: this.handleListConfirm
398
227
  }
@@ -412,22 +241,25 @@ class ReplyPanel extends React.Component {
412
241
  boxSizing: "border-box"
413
242
  }
414
243
  },
415
- view === "chat" ? /* @__PURE__ */ React.createElement(React.Fragment, null, this.renderContextHeader(), /* @__PURE__ */ React.createElement(
416
- ChatList,
417
- {
418
- items: messages,
419
- onApply,
420
- getEditorContent
421
- }
422
- )) : /* @__PURE__ */ React.createElement(
423
- EmptyState,
244
+ /* @__PURE__ */ React.createElement(
245
+ ContextHeader,
424
246
  {
425
247
  sourceMail,
426
248
  selectedMails,
427
249
  onAddClick: this.handleAddClick,
428
- onRemoveSelected: this.handleRemoveSelected
250
+ onSourceClick: this.handlePreviewSource,
251
+ onChipClick: this.handlePreviewSelected,
252
+ onRemoveChip: this.handleRemoveSelected
429
253
  }
430
254
  ),
255
+ view === "chat" ? /* @__PURE__ */ React.createElement(
256
+ ChatList,
257
+ {
258
+ items: messages,
259
+ onApply,
260
+ getEditorContent
261
+ }
262
+ ) : /* @__PURE__ */ React.createElement(EmptyState, null),
431
263
  isLoadingSelected && /* @__PURE__ */ React.createElement(
432
264
  "div",
433
265
  {
@@ -456,6 +288,13 @@ class ReplyPanel extends React.Component {
456
288
  parentRef: this.rootRef,
457
289
  placeholder: "Type a message..."
458
290
  }
291
+ ),
292
+ /* @__PURE__ */ React.createElement(
293
+ ContextPreviewModal,
294
+ {
295
+ preview,
296
+ onClose: this.handlePreviewClose
297
+ }
459
298
  )
460
299
  );
461
300
  }
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ interface PaginationProps {
3
+ total: number;
4
+ page: number;
5
+ totalPages: number;
6
+ onChangePage: (page: number) => void;
7
+ }
8
+ interface PaginationState {
9
+ inputValue: string;
10
+ }
11
+ declare class Pagination extends React.Component<PaginationProps, PaginationState> {
12
+ constructor(props: PaginationProps);
13
+ componentDidUpdate(prevProps: PaginationProps): void;
14
+ clamp: (value: number) => number;
15
+ handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
16
+ commit: () => void;
17
+ handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
18
+ render(): React.JSX.Element;
19
+ }
20
+ export default Pagination;
@@ -0,0 +1,131 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import * as React from "react";
5
+ import ChevronLeft from "../../node_modules/react-feather/dist/icons/chevron-left.js";
6
+ import ChevronRight from "../../node_modules/react-feather/dist/icons/chevron-right.js";
7
+ class Pagination extends React.Component {
8
+ constructor(props) {
9
+ super(props);
10
+ __publicField(this, "clamp", (value) => {
11
+ const { totalPages } = this.props;
12
+ if (Number.isNaN(value)) return this.props.page;
13
+ return Math.min(Math.max(1, Math.floor(value)), Math.max(1, totalPages));
14
+ });
15
+ __publicField(this, "handleInputChange", (e) => {
16
+ this.setState({ inputValue: e.target.value });
17
+ });
18
+ __publicField(this, "commit", () => {
19
+ const next = this.clamp(parseInt(this.state.inputValue, 10));
20
+ this.setState({ inputValue: String(next) });
21
+ if (next !== this.props.page) {
22
+ this.props.onChangePage(next);
23
+ }
24
+ });
25
+ __publicField(this, "handleKeyDown", (e) => {
26
+ if (e.key === "Enter") {
27
+ e.preventDefault();
28
+ this.commit();
29
+ }
30
+ });
31
+ this.state = { inputValue: String(props.page) };
32
+ }
33
+ componentDidUpdate(prevProps) {
34
+ if (prevProps.page !== this.props.page) {
35
+ this.setState({ inputValue: String(this.props.page) });
36
+ }
37
+ }
38
+ render() {
39
+ const { total, page, totalPages, onChangePage } = this.props;
40
+ const { inputValue } = this.state;
41
+ return /* @__PURE__ */ React.createElement(
42
+ "div",
43
+ {
44
+ style: {
45
+ display: "flex",
46
+ alignItems: "center",
47
+ justifyContent: "space-between",
48
+ gap: 8,
49
+ padding: "8px 0",
50
+ marginTop: 8,
51
+ borderTop: "1px solid var(--border-light)"
52
+ }
53
+ },
54
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12, color: "var(--text-secondary)" } }, "Total ", total, " | Page ", page, " / ", totalPages),
55
+ /* @__PURE__ */ React.createElement(
56
+ "div",
57
+ {
58
+ style: {
59
+ display: "inline-flex",
60
+ alignItems: "center",
61
+ gap: 4
62
+ }
63
+ },
64
+ /* @__PURE__ */ React.createElement(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ onClick: () => page > 1 && onChangePage(page - 1),
69
+ disabled: page <= 1,
70
+ className: "icon-button small"
71
+ },
72
+ /* @__PURE__ */ React.createElement(ChevronLeft, { size: 14 })
73
+ ),
74
+ /* @__PURE__ */ React.createElement(
75
+ "button",
76
+ {
77
+ type: "button",
78
+ onClick: () => page < totalPages && onChangePage(page + 1),
79
+ disabled: page >= totalPages,
80
+ className: "icon-button small"
81
+ },
82
+ /* @__PURE__ */ React.createElement(ChevronRight, { size: 14 })
83
+ ),
84
+ /* @__PURE__ */ React.createElement(
85
+ "span",
86
+ {
87
+ style: {
88
+ fontSize: 12,
89
+ color: "var(--text-secondary)",
90
+ marginLeft: 4
91
+ }
92
+ },
93
+ "Page"
94
+ ),
95
+ /* @__PURE__ */ React.createElement(
96
+ "input",
97
+ {
98
+ type: "number",
99
+ min: 1,
100
+ max: Math.max(1, totalPages),
101
+ value: inputValue,
102
+ onChange: this.handleInputChange,
103
+ onBlur: this.commit,
104
+ onKeyDown: this.handleKeyDown,
105
+ className: "pagination-input",
106
+ style: {
107
+ width: `${Math.min(
108
+ 4,
109
+ Math.max(1, inputValue.length || 1)
110
+ ) * 10 + 14}px`,
111
+ height: 24,
112
+ padding: "0 6px 0 6px",
113
+ borderRadius: 4,
114
+ border: "1px solid var(--border-light)",
115
+ background: "#fff",
116
+ fontSize: 12,
117
+ color: "var(--text-primary)",
118
+ textAlign: "center",
119
+ fontFamily: "inherit",
120
+ outline: "none",
121
+ MozAppearance: "textfield"
122
+ }
123
+ }
124
+ )
125
+ )
126
+ );
127
+ }
128
+ }
129
+ export {
130
+ Pagination as default
131
+ };
@@ -0,0 +1,8 @@
1
+ import { MailType } from './types';
2
+ import * as React from "react";
3
+ interface FilterTabsProps {
4
+ mailtype: MailType;
5
+ onChangeFilter: (val: MailType) => void;
6
+ }
7
+ declare const FilterTabs: React.FunctionComponent<FilterTabsProps>;
8
+ export default FilterTabs;
@@ -0,0 +1,57 @@
1
+ import * as React from "react";
2
+ import { FILTERS } from "./utils.js";
3
+ const FilterTabs = ({
4
+ mailtype,
5
+ onChangeFilter
6
+ }) => /* @__PURE__ */ React.createElement(
7
+ "div",
8
+ {
9
+ style: {
10
+ display: "flex",
11
+ justifyContent: "space-between",
12
+ alignItems: "center",
13
+ marginBottom: 12,
14
+ gap: 8
15
+ }
16
+ },
17
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: 13, color: "var(--text-secondary)" } }, "This is a summary compiled by AI · May contain some inaccuracies"),
18
+ /* @__PURE__ */ React.createElement(
19
+ "div",
20
+ {
21
+ style: {
22
+ display: "inline-flex",
23
+ background: "var(--background-softGrey)",
24
+ borderRadius: 6,
25
+ padding: 2,
26
+ flexShrink: 0
27
+ }
28
+ },
29
+ FILTERS.map((f) => {
30
+ const isActive = mailtype === f.value;
31
+ return /* @__PURE__ */ React.createElement(
32
+ "button",
33
+ {
34
+ key: f.value,
35
+ type: "button",
36
+ onClick: () => onChangeFilter(f.value),
37
+ style: {
38
+ border: "none",
39
+ background: isActive ? "var(--primary-main)" : "transparent",
40
+ color: isActive ? "var(--primary-contrasttext)" : "var(--text-primary)",
41
+ fontSize: 12,
42
+ fontWeight: isActive ? 600 : 400,
43
+ padding: "4px 12px",
44
+ borderRadius: 4,
45
+ cursor: "pointer",
46
+ fontFamily: "inherit",
47
+ transition: "background 0.15s ease-in-out"
48
+ }
49
+ },
50
+ f.label
51
+ );
52
+ })
53
+ )
54
+ );
55
+ export {
56
+ FilterTabs as default
57
+ };
@@ -0,0 +1,24 @@
1
+ import { LabelValue } from '../../types';
2
+ import * as React from "react";
3
+ interface LanguagePopoverProps {
4
+ anchorEl: HTMLElement | null;
5
+ langList: LabelValue[];
6
+ currentLang: string;
7
+ onSelect: (val: string) => void;
8
+ onClose: () => void;
9
+ }
10
+ interface LanguagePopoverState {
11
+ top: number;
12
+ left: number;
13
+ }
14
+ declare class LanguagePopover extends React.Component<LanguagePopoverProps, LanguagePopoverState> {
15
+ private panelRef;
16
+ constructor(props: LanguagePopoverProps);
17
+ componentDidMount(): void;
18
+ componentDidUpdate(prevProps: LanguagePopoverProps): void;
19
+ componentWillUnmount(): void;
20
+ updatePosition: () => void;
21
+ handleClickOutside: (e: MouseEvent) => void;
22
+ render(): React.ReactPortal | null;
23
+ }
24
+ export default LanguagePopover;
@@ -0,0 +1,110 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import * as React from "react";
5
+ import * as ReactDOM from "react-dom";
6
+ import { AI_LANG_FLAGS } from "../../constants/index.js";
7
+ import CountryFlag from "../CountryFlag/index.js";
8
+ const getFlagCode = (value) => {
9
+ var _a;
10
+ return (_a = AI_LANG_FLAGS.find((l) => l.value === value)) == null ? void 0 : _a.flagCode;
11
+ };
12
+ class LanguagePopover extends React.Component {
13
+ constructor(props) {
14
+ super(props);
15
+ __publicField(this, "panelRef");
16
+ __publicField(this, "updatePosition", () => {
17
+ const { anchorEl } = this.props;
18
+ if (!anchorEl) return;
19
+ const rect = anchorEl.getBoundingClientRect();
20
+ const top = rect.bottom + (window.scrollY || document.documentElement.scrollTop) + 4;
21
+ const right = window.innerWidth - rect.right - (window.scrollX || document.documentElement.scrollLeft);
22
+ this.setState({ top, left: window.innerWidth - right - 180 });
23
+ });
24
+ __publicField(this, "handleClickOutside", (e) => {
25
+ const target = e.target;
26
+ if (this.panelRef.current && !this.panelRef.current.contains(target) && this.props.anchorEl && !this.props.anchorEl.contains(target)) {
27
+ this.props.onClose();
28
+ }
29
+ });
30
+ this.panelRef = React.createRef();
31
+ this.state = { top: 0, left: 0 };
32
+ }
33
+ componentDidMount() {
34
+ document.addEventListener("mousedown", this.handleClickOutside);
35
+ this.updatePosition();
36
+ }
37
+ componentDidUpdate(prevProps) {
38
+ if (prevProps.anchorEl !== this.props.anchorEl) {
39
+ this.updatePosition();
40
+ }
41
+ }
42
+ componentWillUnmount() {
43
+ document.removeEventListener("mousedown", this.handleClickOutside);
44
+ }
45
+ render() {
46
+ const { anchorEl, langList, currentLang, onSelect } = this.props;
47
+ if (!anchorEl) return null;
48
+ const { top, left } = this.state;
49
+ return ReactDOM.createPortal(
50
+ /* @__PURE__ */ React.createElement(
51
+ "div",
52
+ {
53
+ ref: this.panelRef,
54
+ style: {
55
+ position: "absolute",
56
+ top,
57
+ left,
58
+ width: 180,
59
+ maxHeight: 280,
60
+ overflowY: "auto",
61
+ background: "#fff",
62
+ border: "1px solid var(--border-main)",
63
+ borderRadius: 6,
64
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.08)",
65
+ zIndex: 1200,
66
+ padding: "4px 0"
67
+ }
68
+ },
69
+ langList.map((l) => {
70
+ const isActive = l.value === currentLang;
71
+ const flag = getFlagCode(l.value);
72
+ return /* @__PURE__ */ React.createElement(
73
+ "button",
74
+ {
75
+ key: l.value,
76
+ type: "button",
77
+ onClick: () => onSelect(l.value),
78
+ style: {
79
+ width: "100%",
80
+ display: "flex",
81
+ alignItems: "center",
82
+ gap: 8,
83
+ padding: "8px 12px",
84
+ border: "none",
85
+ background: isActive ? "var(--primary-lighter)" : "transparent",
86
+ cursor: "pointer",
87
+ fontSize: 13,
88
+ fontFamily: "inherit",
89
+ textAlign: "left",
90
+ color: "var(--text-primary)"
91
+ }
92
+ },
93
+ flag && /* @__PURE__ */ React.createElement(
94
+ CountryFlag,
95
+ {
96
+ flagCode: flag,
97
+ style: { width: 18, height: 14, flexShrink: 0 }
98
+ }
99
+ ),
100
+ /* @__PURE__ */ React.createElement("span", null, l.label)
101
+ );
102
+ })
103
+ ),
104
+ document.body
105
+ );
106
+ }
107
+ }
108
+ export {
109
+ LanguagePopover as default
110
+ };
@@ -0,0 +1,7 @@
1
+ import { SummaryItemData } from './types';
2
+ import * as React from "react";
3
+ interface SummaryItemProps {
4
+ item: SummaryItemData;
5
+ }
6
+ declare const SummaryItem: React.FunctionComponent<SummaryItemProps>;
7
+ export default SummaryItem;