@x-plat/design-system 0.5.42 → 0.5.44
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.
- package/dist/components/Dropdown/index.cjs +22 -22
- package/dist/components/Dropdown/index.js +22 -22
- package/dist/components/PopOver/index.cjs +22 -22
- package/dist/components/PopOver/index.js +22 -22
- package/dist/components/Select/index.cjs +22 -22
- package/dist/components/Select/index.js +22 -22
- package/dist/components/Video/index.cjs +201 -201
- package/dist/components/Video/index.js +243 -243
- package/dist/components/index.cjs +278 -278
- package/dist/components/index.css +700 -188
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +278 -278
- package/dist/index.cjs +278 -278
- package/dist/index.css +700 -188
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +278 -278
- package/dist/layout/index.css +520 -8
- package/guidelines/AGENT_PROMPT.md +248 -0
- package/guidelines/Guidelines.md +8 -0
- package/guidelines/composition/layout.md +87 -16
- package/guidelines/setup.md +11 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6036,15 +6036,31 @@ var Badge = (props) => {
|
|
|
6036
6036
|
Badge.displayName = "Badge";
|
|
6037
6037
|
var Badge_default = Badge;
|
|
6038
6038
|
|
|
6039
|
-
// src/components/
|
|
6039
|
+
// src/components/Box/Box.tsx
|
|
6040
6040
|
var import_jsx_runtime299 = require("react/jsx-runtime");
|
|
6041
|
+
var Box = ({
|
|
6042
|
+
children,
|
|
6043
|
+
title,
|
|
6044
|
+
variant = "outlined",
|
|
6045
|
+
padding = "md"
|
|
6046
|
+
}) => {
|
|
6047
|
+
return /* @__PURE__ */ (0, import_jsx_runtime299.jsxs)("div", { className: clsx_default("lib-xplat-box", variant, `pad-${padding}`), children: [
|
|
6048
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime299.jsx)("div", { className: "box-title", children: title }),
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime299.jsx)("div", { className: "box-content", children })
|
|
6050
|
+
] });
|
|
6051
|
+
};
|
|
6052
|
+
Box.displayName = "Box";
|
|
6053
|
+
var Box_default = Box;
|
|
6054
|
+
|
|
6055
|
+
// src/components/Breadcrumb/Breadcrumb.tsx
|
|
6056
|
+
var import_jsx_runtime300 = require("react/jsx-runtime");
|
|
6041
6057
|
var Breadcrumb = (props) => {
|
|
6042
6058
|
const { items, separator = "/" } = props;
|
|
6043
|
-
return /* @__PURE__ */ (0,
|
|
6059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("nav", { className: "lib-xplat-breadcrumb", "aria-label": "\uACBD\uB85C", children: /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("ol", { children: items.map((item, index) => {
|
|
6044
6060
|
const isLast = index === items.length - 1;
|
|
6045
|
-
return /* @__PURE__ */ (0,
|
|
6046
|
-
isLast ? /* @__PURE__ */ (0,
|
|
6047
|
-
!isLast && /* @__PURE__ */ (0,
|
|
6061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime300.jsxs)("li", { children: [
|
|
6062
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("span", { className: "current", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("a", { href: item.href, className: "link", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("button", { className: "link", onClick: item.onClick, children: item.label }),
|
|
6063
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime300.jsx)("span", { className: "separator", children: separator })
|
|
6048
6064
|
] }, index);
|
|
6049
6065
|
}) }) });
|
|
6050
6066
|
};
|
|
@@ -6052,7 +6068,7 @@ Breadcrumb.displayName = "Breadcrumb";
|
|
|
6052
6068
|
var Breadcrumb_default = Breadcrumb;
|
|
6053
6069
|
|
|
6054
6070
|
// src/components/Button/Button.tsx
|
|
6055
|
-
var
|
|
6071
|
+
var import_jsx_runtime301 = require("react/jsx-runtime");
|
|
6056
6072
|
var Button = (props) => {
|
|
6057
6073
|
const {
|
|
6058
6074
|
children,
|
|
@@ -6061,7 +6077,7 @@ var Button = (props) => {
|
|
|
6061
6077
|
disabled,
|
|
6062
6078
|
...rest
|
|
6063
6079
|
} = props;
|
|
6064
|
-
return /* @__PURE__ */ (0,
|
|
6080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
|
|
6065
6081
|
"button",
|
|
6066
6082
|
{
|
|
6067
6083
|
className: clsx_default("lib-xplat-button", type, size),
|
|
@@ -6178,7 +6194,7 @@ var MONTH_LABELS = {
|
|
|
6178
6194
|
};
|
|
6179
6195
|
|
|
6180
6196
|
// src/components/Calendar/Calendar.tsx
|
|
6181
|
-
var
|
|
6197
|
+
var import_jsx_runtime302 = require("react/jsx-runtime");
|
|
6182
6198
|
var DayCell = import_react3.default.memo(
|
|
6183
6199
|
({
|
|
6184
6200
|
day,
|
|
@@ -6190,7 +6206,7 @@ var DayCell = import_react3.default.memo(
|
|
|
6190
6206
|
onEventClick
|
|
6191
6207
|
}) => {
|
|
6192
6208
|
if (renderDay) {
|
|
6193
|
-
return /* @__PURE__ */ (0,
|
|
6209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6194
6210
|
"div",
|
|
6195
6211
|
{
|
|
6196
6212
|
className: clsx_default(
|
|
@@ -6207,7 +6223,7 @@ var DayCell = import_react3.default.memo(
|
|
|
6207
6223
|
}
|
|
6208
6224
|
);
|
|
6209
6225
|
}
|
|
6210
|
-
return /* @__PURE__ */ (0,
|
|
6226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime302.jsxs)(
|
|
6211
6227
|
"div",
|
|
6212
6228
|
{
|
|
6213
6229
|
className: clsx_default(
|
|
@@ -6223,9 +6239,9 @@ var DayCell = import_react3.default.memo(
|
|
|
6223
6239
|
if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
|
|
6224
6240
|
},
|
|
6225
6241
|
children: [
|
|
6226
|
-
/* @__PURE__ */ (0,
|
|
6227
|
-
dayEvents.length > 0 && /* @__PURE__ */ (0,
|
|
6228
|
-
dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0,
|
|
6242
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("span", { className: "calendar-day-number", children: day.day }),
|
|
6243
|
+
dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime302.jsxs)("div", { className: "calendar-day-events", children: [
|
|
6244
|
+
dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6229
6245
|
"span",
|
|
6230
6246
|
{
|
|
6231
6247
|
className: "calendar-event-dot",
|
|
@@ -6238,7 +6254,7 @@ var DayCell = import_react3.default.memo(
|
|
|
6238
6254
|
},
|
|
6239
6255
|
ei
|
|
6240
6256
|
)),
|
|
6241
|
-
dayEvents.length > 3 && /* @__PURE__ */ (0,
|
|
6257
|
+
dayEvents.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime302.jsxs)("span", { className: "calendar-event-more", children: [
|
|
6242
6258
|
"+",
|
|
6243
6259
|
dayEvents.length - 3
|
|
6244
6260
|
] })
|
|
@@ -6359,21 +6375,21 @@ var Calendar = (props) => {
|
|
|
6359
6375
|
const weekdays = WEEKDAY_LABELS[locale];
|
|
6360
6376
|
const monthLabels = MONTH_LABELS[locale];
|
|
6361
6377
|
const titleText = pickerMode === "days" ? locale === "ko" ? `${year}\uB144 ${monthLabels[month]}` : `${monthLabels[month]} ${year}` : pickerMode === "months" ? `${year}` : `${yearRangeStart} - ${yearRangeStart + 11}`;
|
|
6362
|
-
return /* @__PURE__ */ (0,
|
|
6378
|
+
return /* @__PURE__ */ (0, import_jsx_runtime302.jsxs)(
|
|
6363
6379
|
"div",
|
|
6364
6380
|
{
|
|
6365
6381
|
className: "lib-xplat-calendar",
|
|
6366
6382
|
style: selectedColor ? { "--calendar-selected-color": `var(--${selectedColor})` } : void 0,
|
|
6367
6383
|
children: [
|
|
6368
|
-
/* @__PURE__ */ (0,
|
|
6369
|
-
/* @__PURE__ */ (0,
|
|
6370
|
-
/* @__PURE__ */ (0,
|
|
6371
|
-
/* @__PURE__ */ (0,
|
|
6372
|
-
showToday && /* @__PURE__ */ (0,
|
|
6384
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsxs)("div", { className: "calendar-header", children: [
|
|
6385
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("button", { className: "calendar-nav", onClick: handlePrev, "aria-label": "\uC774\uC804", children: /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(ChevronLeftIcon_default, {}) }),
|
|
6386
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("button", { className: "calendar-title", onClick: handleTitleClick, type: "button", children: titleText }),
|
|
6387
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("button", { className: "calendar-nav", onClick: handleNext, "aria-label": "\uB2E4\uC74C", children: /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(ChevronRightIcon_default, {}) }),
|
|
6388
|
+
showToday && /* @__PURE__ */ (0, import_jsx_runtime302.jsx)("button", { className: "calendar-today-btn", onClick: handleToday, children: locale === "ko" ? "\uC624\uB298" : "Today" })
|
|
6373
6389
|
] }),
|
|
6374
|
-
pickerMode === "years" && /* @__PURE__ */ (0,
|
|
6390
|
+
pickerMode === "years" && /* @__PURE__ */ (0, import_jsx_runtime302.jsx)("div", { className: "calendar-picker-grid", children: Array.from({ length: 12 }, (_, i) => {
|
|
6375
6391
|
const y = yearRangeStart + i;
|
|
6376
|
-
return /* @__PURE__ */ (0,
|
|
6392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6377
6393
|
"button",
|
|
6378
6394
|
{
|
|
6379
6395
|
type: "button",
|
|
@@ -6384,7 +6400,7 @@ var Calendar = (props) => {
|
|
|
6384
6400
|
y
|
|
6385
6401
|
);
|
|
6386
6402
|
}) }),
|
|
6387
|
-
pickerMode === "months" && /* @__PURE__ */ (0,
|
|
6403
|
+
pickerMode === "months" && /* @__PURE__ */ (0, import_jsx_runtime302.jsx)("div", { className: "calendar-picker-grid", children: monthLabels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6388
6404
|
"button",
|
|
6389
6405
|
{
|
|
6390
6406
|
type: "button",
|
|
@@ -6394,8 +6410,8 @@ var Calendar = (props) => {
|
|
|
6394
6410
|
},
|
|
6395
6411
|
i
|
|
6396
6412
|
)) }),
|
|
6397
|
-
pickerMode === "days" && /* @__PURE__ */ (0,
|
|
6398
|
-
/* @__PURE__ */ (0,
|
|
6413
|
+
pickerMode === "days" && /* @__PURE__ */ (0, import_jsx_runtime302.jsxs)(import_jsx_runtime302.Fragment, { children: [
|
|
6414
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("div", { className: "calendar-weekdays", children: weekdays.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6399
6415
|
"div",
|
|
6400
6416
|
{
|
|
6401
6417
|
className: clsx_default(
|
|
@@ -6407,12 +6423,12 @@ var Calendar = (props) => {
|
|
|
6407
6423
|
},
|
|
6408
6424
|
label
|
|
6409
6425
|
)) }),
|
|
6410
|
-
/* @__PURE__ */ (0,
|
|
6426
|
+
/* @__PURE__ */ (0, import_jsx_runtime302.jsx)("div", { className: "calendar-grid", children: days.map((day, idx) => {
|
|
6411
6427
|
const dayEvents = getEventsForDay(day.date);
|
|
6412
6428
|
const t = day.date.getTime();
|
|
6413
6429
|
const disabled = t < minTime || t > maxTime;
|
|
6414
6430
|
const isSelected = selectedDate ? isSameDay(day.date, selectedDate) : false;
|
|
6415
|
-
return /* @__PURE__ */ (0,
|
|
6431
|
+
return /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6416
6432
|
DayCell,
|
|
6417
6433
|
{
|
|
6418
6434
|
day,
|
|
@@ -6434,139 +6450,14 @@ var Calendar = (props) => {
|
|
|
6434
6450
|
Calendar.displayName = "Calendar";
|
|
6435
6451
|
var Calendar_default = Calendar;
|
|
6436
6452
|
|
|
6437
|
-
// src/components/ChatInput/ChatInput.tsx
|
|
6438
|
-
var import_react4 = __toESM(require("react"), 1);
|
|
6439
|
-
|
|
6440
|
-
// src/components/IconButton/IconButton.tsx
|
|
6441
|
-
var import_jsx_runtime302 = require("react/jsx-runtime");
|
|
6442
|
-
var IconButton = (props) => {
|
|
6443
|
-
const {
|
|
6444
|
-
icon,
|
|
6445
|
-
type = "primary",
|
|
6446
|
-
size = "md",
|
|
6447
|
-
disabled,
|
|
6448
|
-
...rest
|
|
6449
|
-
} = props;
|
|
6450
|
-
return /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
|
|
6451
|
-
"button",
|
|
6452
|
-
{
|
|
6453
|
-
className: clsx_default("lib-xplat-icon-button", type, size),
|
|
6454
|
-
disabled,
|
|
6455
|
-
...rest,
|
|
6456
|
-
children: icon
|
|
6457
|
-
}
|
|
6458
|
-
);
|
|
6459
|
-
};
|
|
6460
|
-
IconButton.displayName = "IconButton";
|
|
6461
|
-
var IconButton_default = IconButton;
|
|
6462
|
-
|
|
6463
|
-
// src/components/ChatInput/ChatInput.tsx
|
|
6464
|
-
var import_jsx_runtime303 = require("react/jsx-runtime");
|
|
6465
|
-
var MAX_HEIGHT = 200;
|
|
6466
|
-
var ChatInput = import_react4.default.forwardRef(
|
|
6467
|
-
(props, ref) => {
|
|
6468
|
-
const {
|
|
6469
|
-
placeholder,
|
|
6470
|
-
value: valueProp,
|
|
6471
|
-
disabled = false,
|
|
6472
|
-
buttonType = "primary",
|
|
6473
|
-
onSubmit,
|
|
6474
|
-
onChange
|
|
6475
|
-
} = props;
|
|
6476
|
-
const isControlled = valueProp !== void 0;
|
|
6477
|
-
const [internalValue, setInternalValue] = import_react4.default.useState("");
|
|
6478
|
-
const value = isControlled ? valueProp : internalValue;
|
|
6479
|
-
const hasText = value.trim().length > 0;
|
|
6480
|
-
const textareaRef = import_react4.default.useRef(null);
|
|
6481
|
-
const setRefs = import_react4.default.useCallback(
|
|
6482
|
-
(el) => {
|
|
6483
|
-
textareaRef.current = el;
|
|
6484
|
-
if (typeof ref === "function") ref(el);
|
|
6485
|
-
else if (ref) ref.current = el;
|
|
6486
|
-
},
|
|
6487
|
-
[ref]
|
|
6488
|
-
);
|
|
6489
|
-
const updateHeight = import_react4.default.useCallback(() => {
|
|
6490
|
-
const el = textareaRef.current;
|
|
6491
|
-
if (!el) return;
|
|
6492
|
-
el.style.height = "0px";
|
|
6493
|
-
el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
|
|
6494
|
-
}, []);
|
|
6495
|
-
const handleChange = (e) => {
|
|
6496
|
-
const val = e.target.value;
|
|
6497
|
-
if (!isControlled) setInternalValue(val);
|
|
6498
|
-
onChange?.(val);
|
|
6499
|
-
};
|
|
6500
|
-
const handleSubmit = () => {
|
|
6501
|
-
if (!hasText || disabled) return;
|
|
6502
|
-
onSubmit?.(value);
|
|
6503
|
-
if (!isControlled) setInternalValue("");
|
|
6504
|
-
requestAnimationFrame(updateHeight);
|
|
6505
|
-
};
|
|
6506
|
-
const handleKeyDown = (e) => {
|
|
6507
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
6508
|
-
e.preventDefault();
|
|
6509
|
-
handleSubmit();
|
|
6510
|
-
}
|
|
6511
|
-
};
|
|
6512
|
-
import_react4.default.useEffect(() => {
|
|
6513
|
-
updateHeight();
|
|
6514
|
-
}, [value, updateHeight]);
|
|
6515
|
-
return /* @__PURE__ */ (0, import_jsx_runtime303.jsxs)("div", { className: clsx_default("lib-xplat-chat-input", disabled && "disabled"), children: [
|
|
6516
|
-
/* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
|
|
6517
|
-
"textarea",
|
|
6518
|
-
{
|
|
6519
|
-
ref: setRefs,
|
|
6520
|
-
className: "chat-input-textarea",
|
|
6521
|
-
placeholder,
|
|
6522
|
-
value,
|
|
6523
|
-
disabled,
|
|
6524
|
-
rows: 1,
|
|
6525
|
-
onChange: handleChange,
|
|
6526
|
-
onKeyDown: handleKeyDown
|
|
6527
|
-
}
|
|
6528
|
-
),
|
|
6529
|
-
/* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
|
|
6530
|
-
IconButton_default,
|
|
6531
|
-
{
|
|
6532
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime303.jsx)(MessageSquareIcon_default, {}),
|
|
6533
|
-
type: buttonType,
|
|
6534
|
-
size: "sm",
|
|
6535
|
-
disabled: !hasText || disabled,
|
|
6536
|
-
onClick: handleSubmit,
|
|
6537
|
-
"aria-label": "\uC804\uC1A1"
|
|
6538
|
-
}
|
|
6539
|
-
)
|
|
6540
|
-
] });
|
|
6541
|
-
}
|
|
6542
|
-
);
|
|
6543
|
-
ChatInput.displayName = "ChatInput";
|
|
6544
|
-
var ChatInput_default = ChatInput;
|
|
6545
|
-
|
|
6546
|
-
// src/components/Box/Box.tsx
|
|
6547
|
-
var import_jsx_runtime304 = require("react/jsx-runtime");
|
|
6548
|
-
var Box = ({
|
|
6549
|
-
children,
|
|
6550
|
-
title,
|
|
6551
|
-
variant = "outlined",
|
|
6552
|
-
padding = "md"
|
|
6553
|
-
}) => {
|
|
6554
|
-
return /* @__PURE__ */ (0, import_jsx_runtime304.jsxs)("div", { className: clsx_default("lib-xplat-box", variant, `pad-${padding}`), children: [
|
|
6555
|
-
title && /* @__PURE__ */ (0, import_jsx_runtime304.jsx)("div", { className: "box-title", children: title }),
|
|
6556
|
-
/* @__PURE__ */ (0, import_jsx_runtime304.jsx)("div", { className: "box-content", children })
|
|
6557
|
-
] });
|
|
6558
|
-
};
|
|
6559
|
-
Box.displayName = "Box";
|
|
6560
|
-
var Box_default = Box;
|
|
6561
|
-
|
|
6562
6453
|
// src/components/CardTab/CardTab.tsx
|
|
6563
|
-
var
|
|
6454
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
6564
6455
|
|
|
6565
6456
|
// src/components/CardTab/CardTabPanel.tsx
|
|
6566
|
-
var
|
|
6457
|
+
var import_jsx_runtime303 = require("react/jsx-runtime");
|
|
6567
6458
|
var CardTabPanel = (props) => {
|
|
6568
6459
|
const { children, columns = 3 } = props;
|
|
6569
|
-
return /* @__PURE__ */ (0,
|
|
6460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
|
|
6570
6461
|
"div",
|
|
6571
6462
|
{
|
|
6572
6463
|
className: "card-tab-panel",
|
|
@@ -6579,7 +6470,7 @@ CardTabPanel.displayName = "CardTab.Panel";
|
|
|
6579
6470
|
var CardTabPanel_default = CardTabPanel;
|
|
6580
6471
|
|
|
6581
6472
|
// src/components/CardTab/CardTab.tsx
|
|
6582
|
-
var
|
|
6473
|
+
var import_jsx_runtime304 = require("react/jsx-runtime");
|
|
6583
6474
|
var CardTabRoot = (props) => {
|
|
6584
6475
|
const {
|
|
6585
6476
|
tabs,
|
|
@@ -6589,7 +6480,7 @@ var CardTabRoot = (props) => {
|
|
|
6589
6480
|
children
|
|
6590
6481
|
} = props;
|
|
6591
6482
|
const isControlled = activeValueProp !== void 0;
|
|
6592
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
6483
|
+
const [uncontrolledValue, setUncontrolledValue] = import_react4.default.useState(tabs[0]?.value ?? "");
|
|
6593
6484
|
const activeValue = isControlled ? activeValueProp : uncontrolledValue;
|
|
6594
6485
|
const handleTabClick = (tab) => {
|
|
6595
6486
|
if (!isControlled) {
|
|
@@ -6597,16 +6488,16 @@ var CardTabRoot = (props) => {
|
|
|
6597
6488
|
}
|
|
6598
6489
|
onChange?.(tab);
|
|
6599
6490
|
};
|
|
6600
|
-
const panels =
|
|
6601
|
-
(child) =>
|
|
6491
|
+
const panels = import_react4.default.Children.toArray(children).filter(
|
|
6492
|
+
(child) => import_react4.default.isValidElement(child) && child.type === CardTabPanel_default
|
|
6602
6493
|
);
|
|
6603
6494
|
const activePanel = panels.find(
|
|
6604
6495
|
(panel) => panel.props.value === activeValue
|
|
6605
6496
|
);
|
|
6606
|
-
return /* @__PURE__ */ (0,
|
|
6607
|
-
/* @__PURE__ */ (0,
|
|
6497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime304.jsxs)("div", { className: clsx_default("lib-xplat-card-tab", size), children: [
|
|
6498
|
+
/* @__PURE__ */ (0, import_jsx_runtime304.jsx)("div", { className: "card-tab-bar", children: tabs.map((tab) => {
|
|
6608
6499
|
const isActive = tab.value === activeValue;
|
|
6609
|
-
return /* @__PURE__ */ (0,
|
|
6500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime304.jsx)(
|
|
6610
6501
|
"button",
|
|
6611
6502
|
{
|
|
6612
6503
|
className: clsx_default("card-tab-trigger", isActive && "active"),
|
|
@@ -6618,7 +6509,7 @@ var CardTabRoot = (props) => {
|
|
|
6618
6509
|
tab.value
|
|
6619
6510
|
);
|
|
6620
6511
|
}) }),
|
|
6621
|
-
/* @__PURE__ */ (0,
|
|
6512
|
+
/* @__PURE__ */ (0, import_jsx_runtime304.jsx)("div", { className: "card-tab-body", children: activePanel })
|
|
6622
6513
|
] });
|
|
6623
6514
|
};
|
|
6624
6515
|
CardTabRoot.displayName = "CardTab";
|
|
@@ -6628,8 +6519,8 @@ var CardTab = Object.assign(CardTabRoot, {
|
|
|
6628
6519
|
var CardTab_default = CardTab;
|
|
6629
6520
|
|
|
6630
6521
|
// src/components/Chart/Chart.tsx
|
|
6631
|
-
var
|
|
6632
|
-
var
|
|
6522
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
6523
|
+
var import_jsx_runtime305 = require("react/jsx-runtime");
|
|
6633
6524
|
var CATEGORICAL_COUNT2 = 8;
|
|
6634
6525
|
var LINE_BAR_PALETTES = Array.from({ length: CATEGORICAL_COUNT2 }, (_, i) => {
|
|
6635
6526
|
const n = i + 1;
|
|
@@ -6674,8 +6565,8 @@ var toSmoothPath = (points) => {
|
|
|
6674
6565
|
return d;
|
|
6675
6566
|
};
|
|
6676
6567
|
var useChartSize = (ref) => {
|
|
6677
|
-
const [size, setSize] =
|
|
6678
|
-
|
|
6568
|
+
const [size, setSize] = import_react5.default.useState({ width: 0, height: 0 });
|
|
6569
|
+
import_react5.default.useEffect(() => {
|
|
6679
6570
|
const el = ref.current;
|
|
6680
6571
|
if (!el) return;
|
|
6681
6572
|
let rafId = 0;
|
|
@@ -6701,10 +6592,10 @@ var useChartSize = (ref) => {
|
|
|
6701
6592
|
};
|
|
6702
6593
|
var prefersReducedMotion = () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
6703
6594
|
var useChartAnimation = (containerRef, dataKey) => {
|
|
6704
|
-
const [animate, setAnimate] =
|
|
6705
|
-
const prevDataKey =
|
|
6706
|
-
const hasAnimated =
|
|
6707
|
-
|
|
6595
|
+
const [animate, setAnimate] = import_react5.default.useState(false);
|
|
6596
|
+
const prevDataKey = import_react5.default.useRef(dataKey);
|
|
6597
|
+
const hasAnimated = import_react5.default.useRef(false);
|
|
6598
|
+
import_react5.default.useEffect(() => {
|
|
6708
6599
|
if (prefersReducedMotion()) return;
|
|
6709
6600
|
const el = containerRef.current;
|
|
6710
6601
|
if (!el) return;
|
|
@@ -6720,7 +6611,7 @@ var useChartAnimation = (containerRef, dataKey) => {
|
|
|
6720
6611
|
observer.observe(el);
|
|
6721
6612
|
return () => observer.disconnect();
|
|
6722
6613
|
}, [containerRef]);
|
|
6723
|
-
|
|
6614
|
+
import_react5.default.useEffect(() => {
|
|
6724
6615
|
if (dataKey !== prevDataKey.current) {
|
|
6725
6616
|
prevDataKey.current = dataKey;
|
|
6726
6617
|
if (prefersReducedMotion()) return;
|
|
@@ -6734,15 +6625,15 @@ var useChartAnimation = (containerRef, dataKey) => {
|
|
|
6734
6625
|
};
|
|
6735
6626
|
var TOOLTIP_OFFSET = 12;
|
|
6736
6627
|
var useChartTooltip = (enabled) => {
|
|
6737
|
-
const [tooltip, setTooltip] =
|
|
6628
|
+
const [tooltip, setTooltip] = import_react5.default.useState({
|
|
6738
6629
|
visible: false,
|
|
6739
6630
|
x: 0,
|
|
6740
6631
|
y: 0,
|
|
6741
6632
|
content: ""
|
|
6742
6633
|
});
|
|
6743
|
-
const containerRef =
|
|
6744
|
-
const rafRef =
|
|
6745
|
-
const move =
|
|
6634
|
+
const containerRef = import_react5.default.useRef(null);
|
|
6635
|
+
const rafRef = import_react5.default.useRef(0);
|
|
6636
|
+
const move = import_react5.default.useCallback((e) => {
|
|
6746
6637
|
if (!enabled) return;
|
|
6747
6638
|
const cx = e.clientX;
|
|
6748
6639
|
const cy = e.clientY;
|
|
@@ -6753,24 +6644,24 @@ var useChartTooltip = (enabled) => {
|
|
|
6753
6644
|
setTooltip((prev) => ({ ...prev, x: cx - rect.left, y: cy - rect.top }));
|
|
6754
6645
|
});
|
|
6755
6646
|
}, [enabled]);
|
|
6756
|
-
const show =
|
|
6647
|
+
const show = import_react5.default.useCallback((e, content) => {
|
|
6757
6648
|
if (!enabled) return;
|
|
6758
6649
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
6759
6650
|
if (!rect) return;
|
|
6760
6651
|
setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
|
|
6761
6652
|
}, [enabled]);
|
|
6762
|
-
const hide =
|
|
6653
|
+
const hide = import_react5.default.useCallback(() => {
|
|
6763
6654
|
cancelAnimationFrame(rafRef.current);
|
|
6764
6655
|
setTooltip((prev) => ({ ...prev, visible: false }));
|
|
6765
6656
|
}, []);
|
|
6766
6657
|
return { tooltip, show, hide, move, containerRef };
|
|
6767
6658
|
};
|
|
6768
|
-
var GridLines =
|
|
6659
|
+
var GridLines = import_react5.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(import_jsx_runtime305.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
|
|
6769
6660
|
const y = PADDING.top + (1 - ratio) * chartH;
|
|
6770
6661
|
const val = Math.round(maxVal * ratio);
|
|
6771
|
-
return /* @__PURE__ */ (0,
|
|
6772
|
-
/* @__PURE__ */ (0,
|
|
6773
|
-
/* @__PURE__ */ (0,
|
|
6662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
|
|
6663
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
|
|
6664
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
|
|
6774
6665
|
] }, ratio);
|
|
6775
6666
|
}) }));
|
|
6776
6667
|
GridLines.displayName = "GridLines";
|
|
@@ -6780,18 +6671,18 @@ var getLabelStep = (count, chartW) => {
|
|
|
6780
6671
|
if (count <= maxLabels) return 1;
|
|
6781
6672
|
return Math.ceil(count / maxLabels);
|
|
6782
6673
|
};
|
|
6783
|
-
var AxisLabels =
|
|
6674
|
+
var AxisLabels = import_react5.default.memo(({ labels, count, chartW, height }) => {
|
|
6784
6675
|
const step = getLabelStep(count, chartW);
|
|
6785
|
-
return /* @__PURE__ */ (0,
|
|
6676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(import_jsx_runtime305.Fragment, { children: labels.map((label, i) => {
|
|
6786
6677
|
if (i % step !== 0) return null;
|
|
6787
6678
|
const x = PADDING.left + i / (count - 1 || 1) * chartW;
|
|
6788
|
-
return /* @__PURE__ */ (0,
|
|
6679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
|
|
6789
6680
|
}) });
|
|
6790
6681
|
});
|
|
6791
6682
|
AxisLabels.displayName = "AxisLabels";
|
|
6792
6683
|
var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
6793
|
-
const [activeIndex, setActiveIndex] =
|
|
6794
|
-
const handleMouseMove =
|
|
6684
|
+
const [activeIndex, setActiveIndex] = import_react5.default.useState(null);
|
|
6685
|
+
const handleMouseMove = import_react5.default.useCallback((e) => {
|
|
6795
6686
|
const svg = e.currentTarget;
|
|
6796
6687
|
const rect = svg.getBoundingClientRect();
|
|
6797
6688
|
const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
|
|
@@ -6810,17 +6701,17 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
6810
6701
|
}
|
|
6811
6702
|
setActiveIndex(minDist <= threshold ? closest : null);
|
|
6812
6703
|
}, [seriesPoints]);
|
|
6813
|
-
const handleMouseLeave =
|
|
6704
|
+
const handleMouseLeave = import_react5.default.useCallback(() => {
|
|
6814
6705
|
setActiveIndex(null);
|
|
6815
6706
|
}, []);
|
|
6816
|
-
const tooltipContent =
|
|
6707
|
+
const tooltipContent = import_react5.default.useMemo(() => {
|
|
6817
6708
|
if (activeIndex === null) return "";
|
|
6818
6709
|
return entries.map(([key], di) => {
|
|
6819
6710
|
const p = seriesPoints[di]?.[activeIndex];
|
|
6820
6711
|
return p ? `${key}: ${p.v}` : "";
|
|
6821
6712
|
}).filter(Boolean).join(" / ");
|
|
6822
6713
|
}, [activeIndex, entries, seriesPoints]);
|
|
6823
|
-
const getTooltipAt =
|
|
6714
|
+
const getTooltipAt = import_react5.default.useCallback((idx) => {
|
|
6824
6715
|
return entries.map(([key], di) => {
|
|
6825
6716
|
const p = seriesPoints[di]?.[idx];
|
|
6826
6717
|
return p ? `${key}: ${p.v}` : "";
|
|
@@ -6828,16 +6719,16 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
|
|
|
6828
6719
|
}, [entries, seriesPoints]);
|
|
6829
6720
|
return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
|
|
6830
6721
|
};
|
|
6831
|
-
var LineChart =
|
|
6832
|
-
const entries =
|
|
6833
|
-
const maxVal =
|
|
6722
|
+
var LineChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
6723
|
+
const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
|
|
6724
|
+
const maxVal = import_react5.default.useMemo(() => {
|
|
6834
6725
|
const allValues = entries.flatMap(([, v]) => v);
|
|
6835
6726
|
return Math.max(...allValues) * 1.2 || 1;
|
|
6836
6727
|
}, [entries]);
|
|
6837
6728
|
const count = labels.length;
|
|
6838
6729
|
const chartW = width - PADDING.left - PADDING.right;
|
|
6839
6730
|
const chartH = height - PADDING.top - PADDING.bottom;
|
|
6840
|
-
const seriesPoints =
|
|
6731
|
+
const seriesPoints = import_react5.default.useMemo(
|
|
6841
6732
|
() => entries.map(
|
|
6842
6733
|
([, values]) => values.map((v, i) => ({
|
|
6843
6734
|
x: PADDING.left + i / (count - 1 || 1) * chartW,
|
|
@@ -6847,9 +6738,9 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6847
6738
|
),
|
|
6848
6739
|
[entries, count, chartW, chartH, maxVal]
|
|
6849
6740
|
);
|
|
6850
|
-
const clipRef =
|
|
6741
|
+
const clipRef = import_react5.default.useRef(null);
|
|
6851
6742
|
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
6852
|
-
|
|
6743
|
+
import_react5.default.useEffect(() => {
|
|
6853
6744
|
if (!animate || !clipRef.current) return;
|
|
6854
6745
|
clipRef.current.setAttribute("width", "0");
|
|
6855
6746
|
requestAnimationFrame(() => {
|
|
@@ -6861,7 +6752,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6861
6752
|
}, [animate, width]);
|
|
6862
6753
|
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
6863
6754
|
const lineClipId = "line-area-clip";
|
|
6864
|
-
return /* @__PURE__ */ (0,
|
|
6755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)(
|
|
6865
6756
|
"svg",
|
|
6866
6757
|
{
|
|
6867
6758
|
viewBox: `0 0 ${width} ${height}`,
|
|
@@ -6879,9 +6770,9 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6879
6770
|
onLeave();
|
|
6880
6771
|
},
|
|
6881
6772
|
children: [
|
|
6882
|
-
animate && /* @__PURE__ */ (0,
|
|
6883
|
-
/* @__PURE__ */ (0,
|
|
6884
|
-
/* @__PURE__ */ (0,
|
|
6773
|
+
animate && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("clipPath", { id: lineClipId, children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("rect", { ref: clipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
|
|
6774
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(GridLines, { width, height, chartH, maxVal }),
|
|
6775
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(AxisLabels, { labels, count, chartW, height }),
|
|
6885
6776
|
entries.map(([key], di) => {
|
|
6886
6777
|
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
6887
6778
|
const color = palette[2];
|
|
@@ -6890,16 +6781,16 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6890
6781
|
const gradientId = `line-gradient-${di}`;
|
|
6891
6782
|
const polyPoints = points.map((p) => `${p.x},${p.y}`).join(" ");
|
|
6892
6783
|
const areaD = `M ${points[0].x},${points[0].y} ${points.map((p) => `L ${p.x},${p.y}`).join(" ")} L ${points[points.length - 1].x},${PADDING.top + chartH} L ${points[0].x},${PADDING.top + chartH} Z`;
|
|
6893
|
-
return /* @__PURE__ */ (0,
|
|
6894
|
-
/* @__PURE__ */ (0,
|
|
6895
|
-
/* @__PURE__ */ (0,
|
|
6896
|
-
/* @__PURE__ */ (0,
|
|
6784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
|
|
6785
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
6786
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
|
|
6787
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
|
|
6897
6788
|
] }) }),
|
|
6898
|
-
/* @__PURE__ */ (0,
|
|
6899
|
-
/* @__PURE__ */ (0,
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
6789
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
|
|
6790
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("path", { d: areaD, fill: `url(#${gradientId})` }),
|
|
6791
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
|
|
6901
6792
|
] }),
|
|
6902
|
-
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0,
|
|
6793
|
+
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
6903
6794
|
"circle",
|
|
6904
6795
|
{
|
|
6905
6796
|
cx: points[activeIndex].x,
|
|
@@ -6911,7 +6802,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6911
6802
|
)
|
|
6912
6803
|
] }, di);
|
|
6913
6804
|
}),
|
|
6914
|
-
activeX !== null && /* @__PURE__ */ (0,
|
|
6805
|
+
activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
6915
6806
|
"line",
|
|
6916
6807
|
{
|
|
6917
6808
|
x1: activeX,
|
|
@@ -6921,7 +6812,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6921
6812
|
className: "chart-crosshair"
|
|
6922
6813
|
}
|
|
6923
6814
|
),
|
|
6924
|
-
/* @__PURE__ */ (0,
|
|
6815
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
6925
6816
|
"rect",
|
|
6926
6817
|
{
|
|
6927
6818
|
x: PADDING.left,
|
|
@@ -6937,16 +6828,16 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
|
|
|
6937
6828
|
);
|
|
6938
6829
|
});
|
|
6939
6830
|
LineChart.displayName = "LineChart";
|
|
6940
|
-
var CurveChart =
|
|
6941
|
-
const entries =
|
|
6942
|
-
const maxVal =
|
|
6831
|
+
var CurveChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
6832
|
+
const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
|
|
6833
|
+
const maxVal = import_react5.default.useMemo(() => {
|
|
6943
6834
|
const allValues = entries.flatMap(([, v]) => v);
|
|
6944
6835
|
return Math.max(...allValues) * 1.2 || 1;
|
|
6945
6836
|
}, [entries]);
|
|
6946
6837
|
const count = labels.length;
|
|
6947
6838
|
const chartW = width - PADDING.left - PADDING.right;
|
|
6948
6839
|
const chartH = height - PADDING.top - PADDING.bottom;
|
|
6949
|
-
const seriesPoints =
|
|
6840
|
+
const seriesPoints = import_react5.default.useMemo(
|
|
6950
6841
|
() => entries.map(
|
|
6951
6842
|
([, values]) => values.map((v, i) => ({
|
|
6952
6843
|
x: PADDING.left + i / (count - 1 || 1) * chartW,
|
|
@@ -6956,9 +6847,9 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
6956
6847
|
),
|
|
6957
6848
|
[entries, count, chartW, chartH, maxVal]
|
|
6958
6849
|
);
|
|
6959
|
-
const curveClipRef =
|
|
6850
|
+
const curveClipRef = import_react5.default.useRef(null);
|
|
6960
6851
|
const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
|
|
6961
|
-
|
|
6852
|
+
import_react5.default.useEffect(() => {
|
|
6962
6853
|
if (!animate || !curveClipRef.current) return;
|
|
6963
6854
|
curveClipRef.current.setAttribute("width", "0");
|
|
6964
6855
|
requestAnimationFrame(() => {
|
|
@@ -6970,7 +6861,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
6970
6861
|
}, [animate, width]);
|
|
6971
6862
|
const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
|
|
6972
6863
|
const curveClipId = "curve-area-clip";
|
|
6973
|
-
return /* @__PURE__ */ (0,
|
|
6864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)(
|
|
6974
6865
|
"svg",
|
|
6975
6866
|
{
|
|
6976
6867
|
viewBox: `0 0 ${width} ${height}`,
|
|
@@ -6989,9 +6880,9 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
6989
6880
|
onLeave();
|
|
6990
6881
|
},
|
|
6991
6882
|
children: [
|
|
6992
|
-
animate && /* @__PURE__ */ (0,
|
|
6993
|
-
/* @__PURE__ */ (0,
|
|
6994
|
-
/* @__PURE__ */ (0,
|
|
6883
|
+
animate && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("clipPath", { id: curveClipId, children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("rect", { ref: curveClipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
|
|
6884
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(GridLines, { width, height, chartH, maxVal }),
|
|
6885
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(AxisLabels, { labels, count, chartW, height }),
|
|
6995
6886
|
entries.map(([key], di) => {
|
|
6996
6887
|
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
6997
6888
|
const color = palette[2];
|
|
@@ -7000,16 +6891,16 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
7000
6891
|
const gradientId = `curve-gradient-${di}`;
|
|
7001
6892
|
const linePath = toSmoothPath(points);
|
|
7002
6893
|
const areaPath = linePath + ` L ${points[points.length - 1].x} ${PADDING.top + chartH} L ${points[0].x} ${PADDING.top + chartH} Z`;
|
|
7003
|
-
return /* @__PURE__ */ (0,
|
|
7004
|
-
/* @__PURE__ */ (0,
|
|
7005
|
-
/* @__PURE__ */ (0,
|
|
7006
|
-
/* @__PURE__ */ (0,
|
|
6894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
|
|
6895
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
6896
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
|
|
6897
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
|
|
7007
6898
|
] }) }),
|
|
7008
|
-
/* @__PURE__ */ (0,
|
|
7009
|
-
/* @__PURE__ */ (0,
|
|
7010
|
-
/* @__PURE__ */ (0,
|
|
6899
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
|
|
6900
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
|
|
6901
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
|
|
7011
6902
|
] }),
|
|
7012
|
-
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0,
|
|
6903
|
+
activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7013
6904
|
"circle",
|
|
7014
6905
|
{
|
|
7015
6906
|
cx: points[activeIndex].x,
|
|
@@ -7021,7 +6912,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
7021
6912
|
)
|
|
7022
6913
|
] }, di);
|
|
7023
6914
|
}),
|
|
7024
|
-
activeX !== null && /* @__PURE__ */ (0,
|
|
6915
|
+
activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7025
6916
|
"line",
|
|
7026
6917
|
{
|
|
7027
6918
|
x1: activeX,
|
|
@@ -7031,7 +6922,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
7031
6922
|
className: "chart-crosshair"
|
|
7032
6923
|
}
|
|
7033
6924
|
),
|
|
7034
|
-
/* @__PURE__ */ (0,
|
|
6925
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7035
6926
|
"rect",
|
|
7036
6927
|
{
|
|
7037
6928
|
x: PADDING.left,
|
|
@@ -7047,9 +6938,9 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
|
|
|
7047
6938
|
);
|
|
7048
6939
|
});
|
|
7049
6940
|
CurveChart.displayName = "CurveChart";
|
|
7050
|
-
var BarChart =
|
|
7051
|
-
const entries =
|
|
7052
|
-
const maxVal =
|
|
6941
|
+
var BarChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
|
|
6942
|
+
const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
|
|
6943
|
+
const maxVal = import_react5.default.useMemo(() => {
|
|
7053
6944
|
const allValues = entries.flatMap(([, v]) => v);
|
|
7054
6945
|
return Math.max(...allValues) * 1.2 || 1;
|
|
7055
6946
|
}, [entries]);
|
|
@@ -7061,7 +6952,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
|
|
|
7061
6952
|
const barGap = groupCount > 1 ? 2 : 0;
|
|
7062
6953
|
const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
|
|
7063
6954
|
const baseline = PADDING.top + chartH;
|
|
7064
|
-
const bars =
|
|
6955
|
+
const bars = import_react5.default.useMemo(
|
|
7065
6956
|
() => entries.map(
|
|
7066
6957
|
([, values], di) => values.map((v, i) => {
|
|
7067
6958
|
const totalBarsW = barW * groupCount + barGap * (groupCount - 1);
|
|
@@ -7074,11 +6965,11 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
|
|
|
7074
6965
|
[entries, maxVal, chartH, groupW, barW, barGap, groupCount]
|
|
7075
6966
|
);
|
|
7076
6967
|
const barLabelStep = getLabelStep(count, chartW);
|
|
7077
|
-
return /* @__PURE__ */ (0,
|
|
7078
|
-
/* @__PURE__ */ (0,
|
|
6968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
|
|
6969
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)(GridLines, { width, height, chartH, maxVal }),
|
|
7079
6970
|
labels.map((label, i) => {
|
|
7080
6971
|
if (i % barLabelStep !== 0) return null;
|
|
7081
|
-
return /* @__PURE__ */ (0,
|
|
6972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
|
|
7082
6973
|
}),
|
|
7083
6974
|
entries.map(([key], di) => {
|
|
7084
6975
|
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
@@ -7087,7 +6978,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
|
|
|
7087
6978
|
const r2 = Math.min(4, b.w / 2);
|
|
7088
6979
|
const d = b.h <= r2 ? `M ${b.x} ${b.y + b.h} V ${b.y} H ${b.x + b.w} V ${b.y + b.h} Z` : `M ${b.x} ${b.y + b.h} V ${b.y + r2} Q ${b.x} ${b.y} ${b.x + r2} ${b.y} H ${b.x + b.w - r2} Q ${b.x + b.w} ${b.y} ${b.x + b.w} ${b.y + r2} V ${b.y + b.h} Z`;
|
|
7089
6980
|
const delay = 100 + i * 80;
|
|
7090
|
-
return /* @__PURE__ */ (0,
|
|
6981
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7091
6982
|
"path",
|
|
7092
6983
|
{
|
|
7093
6984
|
d,
|
|
@@ -7108,11 +6999,11 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
|
|
|
7108
6999
|
] });
|
|
7109
7000
|
});
|
|
7110
7001
|
BarChart.displayName = "BarChart";
|
|
7111
|
-
var PieDonutChart =
|
|
7002
|
+
var PieDonutChart = import_react5.default.memo(
|
|
7112
7003
|
({ data, labels, width, height, animate, isDoughnut, onHover, onMove, onLeave }) => {
|
|
7113
|
-
const entries =
|
|
7114
|
-
const values =
|
|
7115
|
-
const total =
|
|
7004
|
+
const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
|
|
7005
|
+
const values = import_react5.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
|
|
7006
|
+
const total = import_react5.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
|
|
7116
7007
|
const size = Math.min(width, height);
|
|
7117
7008
|
const cx = size / 2;
|
|
7118
7009
|
const cy = size / 2;
|
|
@@ -7120,10 +7011,10 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
7120
7011
|
const innerR = isDoughnut ? r2 * 0.5 : 0;
|
|
7121
7012
|
const firstKey = entries[0]?.[0] ?? "";
|
|
7122
7013
|
const colorOffset = hashString(firstKey);
|
|
7123
|
-
const maskRef =
|
|
7014
|
+
const maskRef = import_react5.default.useRef(null);
|
|
7124
7015
|
const maskR = r2 + 10;
|
|
7125
7016
|
const maskCircumference = 2 * Math.PI * maskR;
|
|
7126
|
-
|
|
7017
|
+
import_react5.default.useEffect(() => {
|
|
7127
7018
|
if (!animate || !maskRef.current) return;
|
|
7128
7019
|
const el = maskRef.current;
|
|
7129
7020
|
el.style.strokeDasharray = `${maskCircumference}`;
|
|
@@ -7133,7 +7024,7 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
7133
7024
|
el.style.strokeDashoffset = "0";
|
|
7134
7025
|
});
|
|
7135
7026
|
}, [animate, maskCircumference]);
|
|
7136
|
-
const sliceData =
|
|
7027
|
+
const sliceData = import_react5.default.useMemo(() => {
|
|
7137
7028
|
let angle0 = -Math.PI / 2;
|
|
7138
7029
|
let cumulativeAngle = 0;
|
|
7139
7030
|
return values.map((v, i) => {
|
|
@@ -7167,8 +7058,8 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
7167
7058
|
});
|
|
7168
7059
|
}, [values, total, cx, cy, r2, innerR, labels]);
|
|
7169
7060
|
const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
|
|
7170
|
-
return /* @__PURE__ */ (0,
|
|
7171
|
-
animate && /* @__PURE__ */ (0,
|
|
7061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
|
|
7062
|
+
animate && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7172
7063
|
"circle",
|
|
7173
7064
|
{
|
|
7174
7065
|
ref: maskRef,
|
|
@@ -7181,7 +7072,7 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
7181
7072
|
transform: `rotate(-90 ${cx} ${cy})`
|
|
7182
7073
|
}
|
|
7183
7074
|
) }) }),
|
|
7184
|
-
/* @__PURE__ */ (0,
|
|
7075
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
|
|
7185
7076
|
"path",
|
|
7186
7077
|
{
|
|
7187
7078
|
d: s.d,
|
|
@@ -7197,9 +7088,9 @@ var PieDonutChart = import_react6.default.memo(
|
|
|
7197
7088
|
);
|
|
7198
7089
|
PieDonutChart.displayName = "PieDonutChart";
|
|
7199
7090
|
var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, children }) => {
|
|
7200
|
-
const ref =
|
|
7201
|
-
const [pos, setPos] =
|
|
7202
|
-
|
|
7091
|
+
const ref = import_react5.default.useRef(null);
|
|
7092
|
+
const [pos, setPos] = import_react5.default.useState({ left: 0, top: 0 });
|
|
7093
|
+
import_react5.default.useLayoutEffect(() => {
|
|
7203
7094
|
const el = ref.current;
|
|
7204
7095
|
if (!el) return;
|
|
7205
7096
|
const w = el.offsetWidth;
|
|
@@ -7216,15 +7107,15 @@ var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, childr
|
|
|
7216
7107
|
const sepIdx = content.indexOf(" \u2014 ");
|
|
7217
7108
|
const title = sepIdx >= 0 ? content.slice(0, sepIdx) : content;
|
|
7218
7109
|
const desc = sepIdx >= 0 ? content.slice(sepIdx + 3) : "";
|
|
7219
|
-
return /* @__PURE__ */ (0,
|
|
7110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)(
|
|
7220
7111
|
"div",
|
|
7221
7112
|
{
|
|
7222
7113
|
ref,
|
|
7223
7114
|
className: `lib-xplat-tooltip ${tooltipType} chart-tooltip-pos`,
|
|
7224
7115
|
style: { left: pos.left, top: pos.top },
|
|
7225
7116
|
children: [
|
|
7226
|
-
title && /* @__PURE__ */ (0,
|
|
7227
|
-
desc && /* @__PURE__ */ (0,
|
|
7117
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("div", { className: "tooltip-title", children: title }),
|
|
7118
|
+
desc && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("div", { className: "tooltip-desc", children: desc })
|
|
7228
7119
|
]
|
|
7229
7120
|
}
|
|
7230
7121
|
);
|
|
@@ -7236,14 +7127,14 @@ var ChartLegend = ({ data, labels, type }) => {
|
|
|
7236
7127
|
const total = values.reduce((a, b) => a + b, 0) || 1;
|
|
7237
7128
|
const firstKey = entries[0]?.[0] ?? "";
|
|
7238
7129
|
const colorOffset = hashString(firstKey);
|
|
7239
|
-
return /* @__PURE__ */ (0,
|
|
7130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("div", { className: "chart-legend", children: values.map((v, i) => {
|
|
7240
7131
|
const pct = Math.round(v / total * 100);
|
|
7241
7132
|
const color = PIE_COLORS[(i + colorOffset) % PIE_COLORS.length];
|
|
7242
|
-
return /* @__PURE__ */ (0,
|
|
7243
|
-
/* @__PURE__ */ (0,
|
|
7244
|
-
/* @__PURE__ */ (0,
|
|
7245
|
-
/* @__PURE__ */ (0,
|
|
7246
|
-
/* @__PURE__ */ (0,
|
|
7133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "chart-legend-item", children: [
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
7135
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "chart-legend-text", children: [
|
|
7136
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
|
|
7137
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("span", { className: "chart-legend-value", children: [
|
|
7247
7138
|
v.toLocaleString(),
|
|
7248
7139
|
"(",
|
|
7249
7140
|
pct,
|
|
@@ -7253,42 +7144,151 @@ var ChartLegend = ({ data, labels, type }) => {
|
|
|
7253
7144
|
] }, i);
|
|
7254
7145
|
}) });
|
|
7255
7146
|
}
|
|
7256
|
-
return /* @__PURE__ */ (0,
|
|
7147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("div", { className: "chart-legend", children: entries.map(([key], di) => {
|
|
7257
7148
|
const palette = getPalette(LINE_BAR_PALETTES, di, key);
|
|
7258
7149
|
const color = palette[2];
|
|
7259
7150
|
const values = entries[di][1];
|
|
7260
7151
|
const sum = values.reduce((a, b) => a + b, 0);
|
|
7261
|
-
return /* @__PURE__ */ (0,
|
|
7262
|
-
/* @__PURE__ */ (0,
|
|
7263
|
-
/* @__PURE__ */ (0,
|
|
7264
|
-
/* @__PURE__ */ (0,
|
|
7265
|
-
/* @__PURE__ */ (0,
|
|
7152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "chart-legend-item", children: [
|
|
7153
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
|
|
7154
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "chart-legend-text", children: [
|
|
7155
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("span", { className: "chart-legend-label", children: key }),
|
|
7156
|
+
/* @__PURE__ */ (0, import_jsx_runtime305.jsx)("span", { className: "chart-legend-value", children: sum.toLocaleString() })
|
|
7266
7157
|
] })
|
|
7267
7158
|
] }, di);
|
|
7268
7159
|
}) });
|
|
7269
7160
|
};
|
|
7270
|
-
var Chart =
|
|
7161
|
+
var Chart = import_react5.default.memo((props) => {
|
|
7271
7162
|
const { type, data, labels, tooltip: showTooltip = true, tooltipType = "light" } = props;
|
|
7272
7163
|
const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
|
|
7273
7164
|
const { width, height } = useChartSize(containerRef);
|
|
7274
|
-
const stableData =
|
|
7275
|
-
const stableLabels =
|
|
7276
|
-
const dataKey =
|
|
7165
|
+
const stableData = import_react5.default.useMemo(() => data, [JSON.stringify(data)]);
|
|
7166
|
+
const stableLabels = import_react5.default.useMemo(() => labels, [JSON.stringify(labels)]);
|
|
7167
|
+
const dataKey = import_react5.default.useMemo(() => JSON.stringify(labels), [labels]);
|
|
7277
7168
|
const animate = useChartAnimation(containerRef, dataKey);
|
|
7278
7169
|
const ready = width > 0 && height > 0;
|
|
7279
|
-
return /* @__PURE__ */ (0,
|
|
7280
|
-
ready && type === "line" && /* @__PURE__ */ (0,
|
|
7281
|
-
ready && type === "curve" && /* @__PURE__ */ (0,
|
|
7282
|
-
ready && type === "bar" && /* @__PURE__ */ (0,
|
|
7283
|
-
ready && type === "pie" && /* @__PURE__ */ (0,
|
|
7284
|
-
ready && type === "doughnut" && /* @__PURE__ */ (0,
|
|
7285
|
-
ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0,
|
|
7286
|
-
tooltip.visible && tooltip.content && /* @__PURE__ */ (0,
|
|
7170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
|
|
7171
|
+
ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
7172
|
+
ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
7173
|
+
ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
7174
|
+
ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
|
|
7175
|
+
ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
|
|
7176
|
+
ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
|
|
7177
|
+
tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
|
|
7287
7178
|
] });
|
|
7288
7179
|
});
|
|
7289
7180
|
Chart.displayName = "Chart";
|
|
7290
7181
|
var Chart_default = Chart;
|
|
7291
7182
|
|
|
7183
|
+
// src/components/ChatInput/ChatInput.tsx
|
|
7184
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
7185
|
+
|
|
7186
|
+
// src/components/IconButton/IconButton.tsx
|
|
7187
|
+
var import_jsx_runtime306 = require("react/jsx-runtime");
|
|
7188
|
+
var IconButton = (props) => {
|
|
7189
|
+
const {
|
|
7190
|
+
icon,
|
|
7191
|
+
type = "primary",
|
|
7192
|
+
size = "md",
|
|
7193
|
+
disabled,
|
|
7194
|
+
...rest
|
|
7195
|
+
} = props;
|
|
7196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(
|
|
7197
|
+
"button",
|
|
7198
|
+
{
|
|
7199
|
+
className: clsx_default("lib-xplat-icon-button", type, size),
|
|
7200
|
+
disabled,
|
|
7201
|
+
...rest,
|
|
7202
|
+
children: icon
|
|
7203
|
+
}
|
|
7204
|
+
);
|
|
7205
|
+
};
|
|
7206
|
+
IconButton.displayName = "IconButton";
|
|
7207
|
+
var IconButton_default = IconButton;
|
|
7208
|
+
|
|
7209
|
+
// src/components/ChatInput/ChatInput.tsx
|
|
7210
|
+
var import_jsx_runtime307 = require("react/jsx-runtime");
|
|
7211
|
+
var MAX_HEIGHT = 200;
|
|
7212
|
+
var ChatInput = import_react6.default.forwardRef(
|
|
7213
|
+
(props, ref) => {
|
|
7214
|
+
const {
|
|
7215
|
+
placeholder,
|
|
7216
|
+
value: valueProp,
|
|
7217
|
+
disabled = false,
|
|
7218
|
+
buttonType = "primary",
|
|
7219
|
+
onSubmit,
|
|
7220
|
+
onChange
|
|
7221
|
+
} = props;
|
|
7222
|
+
const isControlled = valueProp !== void 0;
|
|
7223
|
+
const [internalValue, setInternalValue] = import_react6.default.useState("");
|
|
7224
|
+
const value = isControlled ? valueProp : internalValue;
|
|
7225
|
+
const hasText = value.trim().length > 0;
|
|
7226
|
+
const textareaRef = import_react6.default.useRef(null);
|
|
7227
|
+
const setRefs = import_react6.default.useCallback(
|
|
7228
|
+
(el) => {
|
|
7229
|
+
textareaRef.current = el;
|
|
7230
|
+
if (typeof ref === "function") ref(el);
|
|
7231
|
+
else if (ref) ref.current = el;
|
|
7232
|
+
},
|
|
7233
|
+
[ref]
|
|
7234
|
+
);
|
|
7235
|
+
const updateHeight = import_react6.default.useCallback(() => {
|
|
7236
|
+
const el = textareaRef.current;
|
|
7237
|
+
if (!el) return;
|
|
7238
|
+
el.style.height = "0px";
|
|
7239
|
+
el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
|
|
7240
|
+
}, []);
|
|
7241
|
+
const handleChange = (e) => {
|
|
7242
|
+
const val = e.target.value;
|
|
7243
|
+
if (!isControlled) setInternalValue(val);
|
|
7244
|
+
onChange?.(val);
|
|
7245
|
+
};
|
|
7246
|
+
const handleSubmit = () => {
|
|
7247
|
+
if (!hasText || disabled) return;
|
|
7248
|
+
onSubmit?.(value);
|
|
7249
|
+
if (!isControlled) setInternalValue("");
|
|
7250
|
+
requestAnimationFrame(updateHeight);
|
|
7251
|
+
};
|
|
7252
|
+
const handleKeyDown = (e) => {
|
|
7253
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
7254
|
+
e.preventDefault();
|
|
7255
|
+
handleSubmit();
|
|
7256
|
+
}
|
|
7257
|
+
};
|
|
7258
|
+
import_react6.default.useEffect(() => {
|
|
7259
|
+
updateHeight();
|
|
7260
|
+
}, [value, updateHeight]);
|
|
7261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: clsx_default("lib-xplat-chat-input", disabled && "disabled"), children: [
|
|
7262
|
+
/* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
|
|
7263
|
+
"textarea",
|
|
7264
|
+
{
|
|
7265
|
+
ref: setRefs,
|
|
7266
|
+
className: "chat-input-textarea",
|
|
7267
|
+
placeholder,
|
|
7268
|
+
value,
|
|
7269
|
+
disabled,
|
|
7270
|
+
rows: 1,
|
|
7271
|
+
onChange: handleChange,
|
|
7272
|
+
onKeyDown: handleKeyDown
|
|
7273
|
+
}
|
|
7274
|
+
),
|
|
7275
|
+
/* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
|
|
7276
|
+
IconButton_default,
|
|
7277
|
+
{
|
|
7278
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(MessageSquareIcon_default, {}),
|
|
7279
|
+
type: buttonType,
|
|
7280
|
+
size: "sm",
|
|
7281
|
+
disabled: !hasText || disabled,
|
|
7282
|
+
onClick: handleSubmit,
|
|
7283
|
+
"aria-label": "\uC804\uC1A1"
|
|
7284
|
+
}
|
|
7285
|
+
)
|
|
7286
|
+
] });
|
|
7287
|
+
}
|
|
7288
|
+
);
|
|
7289
|
+
ChatInput.displayName = "ChatInput";
|
|
7290
|
+
var ChatInput_default = ChatInput;
|
|
7291
|
+
|
|
7292
7292
|
// src/tokens/breakpoints.ts
|
|
7293
7293
|
var BREAKPOINT_KEYS_ORDERED = ["laptop", "tablet", "mobile"];
|
|
7294
7294
|
var breakpoints = {
|