sellmate-design-system-react 9.0.0-beta.47 → 9.0.0-beta.48
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/AGENTS.md +5 -4
- package/dist/components/SChatAttachedFile/README.md +3 -4
- package/dist/components/SChatAttachedFile/SChatAttachedFile.d.ts +3 -44
- package/dist/components/SChatAttachedFile/chatAttachedFile.config.d.ts +19 -39
- package/dist/components/SChatAttachedFile/index.d.ts +1 -1
- package/dist/components/SChatFile/README.md +33 -0
- package/dist/components/SChatFile/SChatFile.d.ts +37 -0
- package/dist/components/SChatFile/chatFile.config.d.ts +56 -0
- package/dist/components/SChatFile/index.d.ts +2 -0
- package/dist/components/SChatMessage/README.md +1 -0
- package/dist/components/SChatMessage/SChatMessage.d.ts +12 -0
- package/dist/components/SGhostButton/README.md +2 -0
- package/dist/components/SIcon/README.md +2 -0
- package/dist/index.cjs +252 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +251 -119
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +40 -8
- package/dist/llms.txt +8 -7
- package/dist/styles.css +255 -41
- package/dist/theme.css +74 -5
- package/eslint/scale.gen.mjs +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4681,10 +4681,9 @@ var STextarea = /* @__PURE__ */ react.forwardRef(function STextarea2({
|
|
|
4681
4681
|
);
|
|
4682
4682
|
});
|
|
4683
4683
|
var DEFAULT_PLACEHOLDER = "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694...";
|
|
4684
|
-
var FIELD_MIN_HEIGHT = 48;
|
|
4685
4684
|
var FIELD_BORDER = 1;
|
|
4686
|
-
var TEXTAREA_MIN_HEIGHT =
|
|
4687
|
-
var BUTTON_BOTTOM_INSET = `calc((
|
|
4685
|
+
var TEXTAREA_MIN_HEIGHT = `calc(var(--cmp-chatInput-buttonFrame-height) - ${FIELD_BORDER * 2}px)`;
|
|
4686
|
+
var BUTTON_BOTTOM_INSET = `calc((var(--cmp-chatInput-buttonFrame-height) - var(--cmp-ghostButton-md-size)) / 2)`;
|
|
4688
4687
|
var DEFAULT_MAX_ROWS = 5;
|
|
4689
4688
|
var SChatInputImpl = /* @__PURE__ */ react.forwardRef(function SChatInput({
|
|
4690
4689
|
value = "",
|
|
@@ -4713,8 +4712,8 @@ var SChatInputImpl = /* @__PURE__ */ react.forwardRef(function SChatInput({
|
|
|
4713
4712
|
e.preventDefault();
|
|
4714
4713
|
send();
|
|
4715
4714
|
};
|
|
4716
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col bg-(--
|
|
4717
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-
|
|
4715
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col bg-(--cmp-chatInput-bg)", className), style, children: [
|
|
4716
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-(--cmp-chatInput-gap) p-(--cmp-chatInput-padding)", children: [
|
|
4718
4717
|
onAttach != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4719
4718
|
SGhostButton,
|
|
4720
4719
|
{
|
|
@@ -4776,81 +4775,67 @@ var SChatInputImpl = /* @__PURE__ */ react.forwardRef(function SChatInput({
|
|
|
4776
4775
|
var SChatInput2 = /* @__PURE__ */ withDisplayName(SChatInputImpl, "SChatInput");
|
|
4777
4776
|
|
|
4778
4777
|
// src/components/SChatAttachedFile/chatAttachedFile.config.ts
|
|
4779
|
-
var CHAT_ATTACHED_FILE_VARIANTS = ["attached", "sent"];
|
|
4780
4778
|
var CHAT_ATTACHED_FILE_CONFIG = {
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4779
|
+
/** 바깥 상자 — 좌우·상하 여백·면·선·라운드 */
|
|
4780
|
+
box: "px-(--cmp-chatAttachedFile-paddingX) py-(--cmp-chatAttachedFile-paddingY) rounded-(--cmp-chatAttachedFile-radius) border-(length:--cmp-chatAttachedFile-border-width) border-(--cmp-chatAttachedFile-border-color) bg-(--cmp-chatAttachedFile-bg)",
|
|
4781
|
+
/** 콘텐츠 묶음 ↔ 제거 버튼 간격 */
|
|
4782
|
+
outerGap: "gap-(--cmp-chatAttachedFile-gap)",
|
|
4783
|
+
/** 아이콘 칩 ↔ 파일명 간격 */
|
|
4784
|
+
contentGap: "gap-(--cmp-chatAttachedFile-content-gap)",
|
|
4785
|
+
/** 클립 아이콘이 앉는 칩 — 내부 패딩·면·라운드 (높이는 아이콘+패딩이 정한다) */
|
|
4786
|
+
tile: "p-(--cmp-chatAttachedFile-icon-wrapper-padding) rounded-(--cmp-chatAttachedFile-icon-wrapper-radius) bg-(--cmp-chatAttachedFile-icon-wrapper-bg)",
|
|
4787
|
+
/** 칩 안 클립 아이콘 크기(px). SVG width/height 는 속성값이라 CSS 변수를 못 받아 값으로 둔다 (토큰 값과 동일) */
|
|
4788
|
+
iconSize: 16,
|
|
4789
|
+
/** 파일명 타이포 프리셋 */
|
|
4790
|
+
nameTypo: "typo-body-sm-default",
|
|
4791
|
+
/** 파일명 텍스트색 */
|
|
4792
|
+
textColor: "text-(--cmp-chatAttachedFile-filename-color)"
|
|
4794
4793
|
};
|
|
4795
|
-
var SIZE_UNITS = ["B", "KB", "MB", "GB", "TB"];
|
|
4796
|
-
function formatFileSize(bytes) {
|
|
4797
|
-
if (!Number.isFinite(bytes) || bytes < 0) return "";
|
|
4798
|
-
let value = bytes;
|
|
4799
|
-
let unit = 0;
|
|
4800
|
-
while (value >= 1024 && unit < SIZE_UNITS.length - 1) {
|
|
4801
|
-
value /= 1024;
|
|
4802
|
-
unit += 1;
|
|
4803
|
-
}
|
|
4804
|
-
return unit === 0 ? `${Math.round(value)}${SIZE_UNITS[0]}` : `${value.toFixed(1)}${SIZE_UNITS[unit]}`;
|
|
4805
|
-
}
|
|
4806
|
-
function normalizeExtension(extension) {
|
|
4807
|
-
return extension.trim().replace(/^\.+/, "").toLowerCase();
|
|
4808
|
-
}
|
|
4809
|
-
function fileExtension(name) {
|
|
4810
|
-
const dot = name.lastIndexOf(".");
|
|
4811
|
-
return dot > 0 && dot < name.length - 1 ? name.slice(dot + 1).toLowerCase() : "";
|
|
4812
|
-
}
|
|
4813
4794
|
var SChatAttachedFileImpl = /* @__PURE__ */ react.forwardRef(
|
|
4814
|
-
function SChatAttachedFile({
|
|
4815
|
-
const preset = CHAT_ATTACHED_FILE_CONFIG[variant];
|
|
4816
|
-
const ext = extension != null ? normalizeExtension(extension) : fileExtension(name);
|
|
4817
|
-
const meta = [ext, size != null ? formatFileSize(size) : ""].filter(Boolean).join(" / ");
|
|
4818
|
-
const showMeta = variant === "sent" && meta !== "";
|
|
4819
|
-
const showRemove = variant === "attached" && onRemove != null;
|
|
4795
|
+
function SChatAttachedFile({ name, onRemove, className, ...rest }, ref) {
|
|
4820
4796
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4821
4797
|
"div",
|
|
4822
4798
|
{
|
|
4823
4799
|
ref,
|
|
4824
4800
|
className: cn(
|
|
4825
|
-
"inline-flex max-w-full items-center
|
|
4826
|
-
|
|
4801
|
+
"inline-flex max-w-full items-center border-solid",
|
|
4802
|
+
CHAT_ATTACHED_FILE_CONFIG.box,
|
|
4803
|
+
CHAT_ATTACHED_FILE_CONFIG.outerGap,
|
|
4827
4804
|
className
|
|
4828
4805
|
),
|
|
4829
4806
|
...rest,
|
|
4830
4807
|
children: [
|
|
4831
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4808
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("flex min-w-0 items-center", CHAT_ATTACHED_FILE_CONFIG.contentGap), children: [
|
|
4809
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4810
|
+
"span",
|
|
4811
|
+
{
|
|
4812
|
+
className: cn(
|
|
4813
|
+
"inline-grid shrink-0 place-items-center text-(--sys-color-fg-accentLight)",
|
|
4814
|
+
CHAT_ATTACHED_FILE_CONFIG.tile
|
|
4815
|
+
),
|
|
4816
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "attachFile", color: "grey_65", size: CHAT_ATTACHED_FILE_CONFIG.iconSize })
|
|
4817
|
+
}
|
|
4818
|
+
),
|
|
4819
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4820
|
+
"span",
|
|
4821
|
+
{
|
|
4822
|
+
className: cn(
|
|
4823
|
+
"truncate",
|
|
4824
|
+
CHAT_ATTACHED_FILE_CONFIG.nameTypo,
|
|
4825
|
+
CHAT_ATTACHED_FILE_CONFIG.textColor
|
|
4826
|
+
),
|
|
4827
|
+
children: name
|
|
4828
|
+
}
|
|
4829
|
+
)
|
|
4845
4830
|
] }),
|
|
4846
|
-
|
|
4847
|
-
|
|
4831
|
+
onRemove != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4832
|
+
SGhostButton,
|
|
4848
4833
|
{
|
|
4849
|
-
|
|
4850
|
-
"
|
|
4834
|
+
icon: "close",
|
|
4835
|
+
size: "xs",
|
|
4836
|
+
ariaLabel: `${name} \uC81C\uAC70`,
|
|
4851
4837
|
onClick: onRemove,
|
|
4852
|
-
className: "
|
|
4853
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "close", size: 16 })
|
|
4838
|
+
className: "shrink-0"
|
|
4854
4839
|
}
|
|
4855
4840
|
)
|
|
4856
4841
|
]
|
|
@@ -4859,12 +4844,112 @@ var SChatAttachedFileImpl = /* @__PURE__ */ react.forwardRef(
|
|
|
4859
4844
|
}
|
|
4860
4845
|
);
|
|
4861
4846
|
var SChatAttachedFile2 = /* @__PURE__ */ withDisplayName(SChatAttachedFileImpl, "SChatAttachedFile");
|
|
4847
|
+
|
|
4848
|
+
// src/components/SChatFile/chatFile.config.ts
|
|
4849
|
+
var CHAT_FILE_CONFIG = {
|
|
4850
|
+
/** 바깥 상자 — 좌우 비대칭 여백·상하 여백·면·선·라운드 */
|
|
4851
|
+
box: "pl-(--cmp-chatFile-paddingLeft) pr-(--cmp-chatFile-paddingRight) py-(--cmp-chatFile-paddingY) rounded-(--cmp-chatFile-radius) border-(length:--cmp-chatFile-border-width) border-(--cmp-chatFile-border-color) bg-(--cmp-chatFile-bg-default)",
|
|
4852
|
+
/** 아이콘 칩 ↔ 파일명 간격 */
|
|
4853
|
+
contentGap: "gap-(--cmp-chatFile-gap)",
|
|
4854
|
+
/**
|
|
4855
|
+
* 클립 아이콘이 앉는 칩 — 내부 패딩·면·라운드 (높이는 아이콘+패딩이 정한다).
|
|
4856
|
+
*
|
|
4857
|
+
* hover 면은 상자가 아니라 여기에도 걸린다 — 카드가 어두워질 때 칩은 반대로 밝아져
|
|
4858
|
+
* 칩이 배경에 묻히지 않는다. 상자의 hover 를 따라가야 하므로 group-hover 로 받는다.
|
|
4859
|
+
*
|
|
4860
|
+
* **`--sys-color-bg-frame` 은 임시다.** 시안의 hover 칩 색(`#FFFFFF`)에 대응하는
|
|
4861
|
+
* 컴포넌트 토큰이 없다 — `component.chatMessage.chatFile.icon.wrapper.bg` 는 값이 하나뿐이라
|
|
4862
|
+
* hover 를 담지 못한다. 상자의 `bg.default` 가 참조하는 것과 같은 시스템 토큰으로 대신 걸어 둔다.
|
|
4863
|
+
* 디자인팀에 `icon.wrapper.bg.hover` 를 요청해 나오는 대로 갈아끼운다.
|
|
4864
|
+
*/
|
|
4865
|
+
tile: "p-(--cmp-chatFile-icon-wrapper-padding) rounded-(--cmp-chatFile-icon-wrapper-radius) bg-(--cmp-chatFile-icon-wrapper-bg) group-hover/chat-file:bg-(--sys-color-bg-frame)",
|
|
4866
|
+
/** 칩 안 클립 아이콘 크기(px). SVG width/height 는 속성값이라 CSS 변수를 못 받아 값으로 둔다 (토큰 값과 동일) */
|
|
4867
|
+
iconSize: 20,
|
|
4868
|
+
/** 파일명 타이포 프리셋 */
|
|
4869
|
+
nameTypo: "typo-body-md-bold",
|
|
4870
|
+
/** 파일명·부가정보 텍스트색 */
|
|
4871
|
+
textColor: "text-(--cmp-chatFile-text-color)",
|
|
4872
|
+
/**
|
|
4873
|
+
* 눌리는 모양 — 커서·hover 면·포커스 링. 보낸 파일은 언제나 열 수 있으므로 늘 붙는다
|
|
4874
|
+
* (`onFileClick` 이 필수다).
|
|
4875
|
+
*
|
|
4876
|
+
* 상자의 여백·면·선과 따로 두는 이유: 이건 상호작용을 드러내는 값이라 성격이 다르다.
|
|
4877
|
+
* 링은 `SExpansionItem`·`SStepper` 와 같은 accent outline.
|
|
4878
|
+
*/
|
|
4879
|
+
interactive: "cursor-pointer hover:bg-(--cmp-chatFile-bg-hover) focus-visible:outline focus-visible:outline-2 focus-visible:outline-(--sys-color-border-accent)"
|
|
4880
|
+
};
|
|
4881
|
+
var SIZE_UNITS = ["B", "KB", "MB", "GB", "TB"];
|
|
4882
|
+
function formatFileSize(bytes) {
|
|
4883
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "";
|
|
4884
|
+
let value = bytes;
|
|
4885
|
+
let unit = 0;
|
|
4886
|
+
while (value >= 1024 && unit < SIZE_UNITS.length - 1) {
|
|
4887
|
+
value /= 1024;
|
|
4888
|
+
unit += 1;
|
|
4889
|
+
}
|
|
4890
|
+
return unit === 0 ? `${Math.round(value)}${SIZE_UNITS[0]}` : `${value.toFixed(1)}${SIZE_UNITS[unit]}`;
|
|
4891
|
+
}
|
|
4892
|
+
function normalizeExtension(extension) {
|
|
4893
|
+
return extension.trim().replace(/^\.+/, "").toLowerCase();
|
|
4894
|
+
}
|
|
4895
|
+
function fileExtension(name) {
|
|
4896
|
+
const dot = name.lastIndexOf(".");
|
|
4897
|
+
return dot > 0 && dot < name.length - 1 ? name.slice(dot + 1).toLowerCase() : "";
|
|
4898
|
+
}
|
|
4899
|
+
var SChatFileImpl = /* @__PURE__ */ react.forwardRef(function SChatFile({ name, extension, size, onFileClick, className, ...rest }, ref) {
|
|
4900
|
+
const ext = extension != null ? normalizeExtension(extension) : fileExtension(name);
|
|
4901
|
+
const meta = [ext, size != null ? formatFileSize(size) : ""].filter(Boolean).join(" / ");
|
|
4902
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4903
|
+
"div",
|
|
4904
|
+
{
|
|
4905
|
+
ref,
|
|
4906
|
+
className: cn(
|
|
4907
|
+
// group/chat-file: 아이콘 칩이 상자의 hover 를 따라가야 해서 이름을 붙인다 (config.tile 참고)
|
|
4908
|
+
"group/chat-file inline-flex max-w-full items-center border-solid",
|
|
4909
|
+
CHAT_FILE_CONFIG.box,
|
|
4910
|
+
CHAT_FILE_CONFIG.contentGap,
|
|
4911
|
+
CHAT_FILE_CONFIG.interactive,
|
|
4912
|
+
className
|
|
4913
|
+
),
|
|
4914
|
+
...rest,
|
|
4915
|
+
role: "button",
|
|
4916
|
+
tabIndex: 0,
|
|
4917
|
+
onClick: (event) => {
|
|
4918
|
+
rest.onClick?.(event);
|
|
4919
|
+
onFileClick?.();
|
|
4920
|
+
},
|
|
4921
|
+
onKeyDown: (event) => {
|
|
4922
|
+
rest.onKeyDown?.(event);
|
|
4923
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
4924
|
+
event.preventDefault();
|
|
4925
|
+
onFileClick?.();
|
|
4926
|
+
},
|
|
4927
|
+
children: [
|
|
4928
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4929
|
+
"span",
|
|
4930
|
+
{
|
|
4931
|
+
className: cn(
|
|
4932
|
+
"inline-grid shrink-0 place-items-center text-(--sys-color-fg-accentLight)",
|
|
4933
|
+
CHAT_FILE_CONFIG.tile
|
|
4934
|
+
),
|
|
4935
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "attachFile", size: CHAT_FILE_CONFIG.iconSize })
|
|
4936
|
+
}
|
|
4937
|
+
),
|
|
4938
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
4939
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("truncate", CHAT_FILE_CONFIG.nameTypo, CHAT_FILE_CONFIG.textColor), children: name }),
|
|
4940
|
+
meta !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("typo-body-xs-default truncate", CHAT_FILE_CONFIG.textColor), children: meta })
|
|
4941
|
+
] })
|
|
4942
|
+
]
|
|
4943
|
+
}
|
|
4944
|
+
);
|
|
4945
|
+
});
|
|
4946
|
+
var SChatFile2 = /* @__PURE__ */ withDisplayName(SChatFileImpl, "SChatFile");
|
|
4862
4947
|
var CHAT_MESSAGE_DIRECTIONS = ["incoming", "outgoing"];
|
|
4863
4948
|
var CHAT_MESSAGE_VARIANTS = ["default", "template"];
|
|
4864
4949
|
var BUBBLE_SURFACE = {
|
|
4865
|
-
incoming: "bg-(--
|
|
4866
|
-
outgoing: "bg-(--
|
|
4867
|
-
template: "bg-(--
|
|
4950
|
+
incoming: "bg-(--cmp-chatBubble-incoming-bg) text-(--cmp-chatBubble-incoming-content)",
|
|
4951
|
+
outgoing: "bg-(--cmp-chatBubble-outgoing-bg) text-(--cmp-chatBubble-outgoing-content)",
|
|
4952
|
+
template: "bg-(--cmp-chatBubble-templete-bg) text-(--cmp-chatBubble-templete-content)"
|
|
4868
4953
|
};
|
|
4869
4954
|
var CHAT_MESSAGE_READ_STATUSES = ["read", "unread"];
|
|
4870
4955
|
var READ_STATUS_LABEL = {
|
|
@@ -4872,8 +4957,8 @@ var READ_STATUS_LABEL = {
|
|
|
4872
4957
|
unread: "\uC548 \uC77D\uC74C"
|
|
4873
4958
|
};
|
|
4874
4959
|
var READ_STATUS_COLOR = {
|
|
4875
|
-
read: "text-(--
|
|
4876
|
-
unread: "text-(--
|
|
4960
|
+
read: "text-(--cmp-chatTimeStamp-color)",
|
|
4961
|
+
unread: "text-(--cmp-chatReadMark-color)"
|
|
4877
4962
|
};
|
|
4878
4963
|
var AVATAR_SIZE = 32;
|
|
4879
4964
|
var AVATAR_ROW_HEIGHT = 40;
|
|
@@ -4885,7 +4970,7 @@ function Avatar({ src, alt, placeholder }) {
|
|
|
4885
4970
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center", style: { height: AVATAR_ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4886
4971
|
"div",
|
|
4887
4972
|
{
|
|
4888
|
-
className: "relative overflow-hidden rounded-
|
|
4973
|
+
className: "relative overflow-hidden rounded-(--cmp-chatAvatar-radius) bg-(--cmp-chatAvatar-bg)",
|
|
4889
4974
|
style: { width: AVATAR_SIZE, height: AVATAR_SIZE },
|
|
4890
4975
|
children: src != null ? /* @__PURE__ */ jsxRuntime.jsx(SImage, { src, alt: alt ?? "", fit: "cover", className: "h-full w-full" }) : (
|
|
4891
4976
|
// 원 밖으로 나가는 만큼을 좌우로 나눠 가운데를 맞추고, 아래는 원이 자른다.
|
|
@@ -4894,7 +4979,7 @@ function Avatar({ src, alt, placeholder }) {
|
|
|
4894
4979
|
{
|
|
4895
4980
|
name: "user",
|
|
4896
4981
|
size: AVATAR_ICON_SIZE,
|
|
4897
|
-
color: "var(--
|
|
4982
|
+
color: "var(--cmp-chatAvatar-icon)",
|
|
4898
4983
|
className: "absolute top-0",
|
|
4899
4984
|
style: { left: (AVATAR_SIZE - AVATAR_ICON_SIZE) / 2 }
|
|
4900
4985
|
}
|
|
@@ -4914,12 +4999,14 @@ var SChatMessageImpl = /* @__PURE__ */ react.forwardRef(function SChatMessage({
|
|
|
4914
4999
|
variant = "default",
|
|
4915
5000
|
actions,
|
|
4916
5001
|
messages,
|
|
5002
|
+
attachments,
|
|
4917
5003
|
className,
|
|
4918
5004
|
...rest
|
|
4919
5005
|
}, ref) {
|
|
4920
5006
|
const outgoing = direction === "outgoing";
|
|
4921
5007
|
const surface = direction === "outgoing" && variant === "template" ? "template" : direction;
|
|
4922
5008
|
const bubbles = messages ?? [];
|
|
5009
|
+
const files = attachments ?? [];
|
|
4923
5010
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4924
5011
|
"div",
|
|
4925
5012
|
{
|
|
@@ -4927,45 +5014,77 @@ var SChatMessageImpl = /* @__PURE__ */ react.forwardRef(function SChatMessage({
|
|
|
4927
5014
|
className: cn(
|
|
4928
5015
|
// 아바타와 본문 열이 같은 줄에 서고, 보낸 메시지는 좌우를 뒤집는다.
|
|
4929
5016
|
// items-start 라 이름이 있든 없든 아바타는 언제나 첫 줄에 붙는다.
|
|
4930
|
-
"flex items-start gap-
|
|
5017
|
+
"flex items-start gap-(--cmp-chatMessage-avatarGap)",
|
|
4931
5018
|
outgoing && "flex-row-reverse",
|
|
4932
5019
|
className
|
|
4933
5020
|
),
|
|
4934
5021
|
...rest,
|
|
4935
5022
|
children: [
|
|
4936
5023
|
!outgoing && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatarSrc, alt: avatarAlt, placeholder: continued }),
|
|
4937
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
5024
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5025
|
+
"div",
|
|
5026
|
+
{
|
|
5027
|
+
className: cn(
|
|
5028
|
+
"flex min-w-0 flex-col gap-(--cmp-chatMessage-contents-gap)",
|
|
5029
|
+
outgoing ? "items-end" : "items-start"
|
|
5030
|
+
),
|
|
5031
|
+
children: [
|
|
5032
|
+
!outgoing && !continued && sender != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-bold px-(--cmp-chatMessage-name-paddingX) text-(--cmp-chatMessage-name-color)", children: sender }),
|
|
5033
|
+
bubbles.length > 0 && // 말풍선끼리는 이름·시각과의 간격(4px)보다 벌려 한 덩어리 안의 여러 발화로 읽히게 한다.
|
|
5034
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4945
5035
|
"div",
|
|
4946
5036
|
{
|
|
4947
5037
|
className: cn(
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
// 한글은 기본 규칙으로 두면 어절 한가운데서도 줄이 바뀐다 — 띄어쓰기에서만 끊고,
|
|
4951
|
-
// 끊을 자리가 없는 긴 토큰(URL·주문번호)만 흘려보낸다.
|
|
4952
|
-
"break-keep wrap-break-word",
|
|
4953
|
-
BUBBLE_SURFACE[surface]
|
|
5038
|
+
"flex min-w-0 flex-col gap-(--cmp-chatMessage-group-bubble-gap)",
|
|
5039
|
+
outgoing ? "items-end" : "items-start"
|
|
4954
5040
|
),
|
|
4955
|
-
children: message
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
5041
|
+
children: bubbles.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5042
|
+
"div",
|
|
5043
|
+
{
|
|
5044
|
+
className: cn(
|
|
5045
|
+
"typo-body-md-medium max-w-full rounded-(--cmp-chatBubble-radius) px-(--cmp-chatBubble-paddingX) py-(--cmp-chatBubble-paddingY)",
|
|
5046
|
+
// 한글은 기본 규칙으로 두면 어절 한가운데서도 줄이 바뀐다 — 띄어쓰기에서만 끊고,
|
|
5047
|
+
// 끊을 자리가 없는 긴 토큰(URL·주문번호)만 흘려보낸다.
|
|
5048
|
+
"break-keep wrap-break-word",
|
|
5049
|
+
BUBBLE_SURFACE[surface]
|
|
5050
|
+
),
|
|
5051
|
+
children: message
|
|
5052
|
+
},
|
|
5053
|
+
index
|
|
5054
|
+
))
|
|
5055
|
+
}
|
|
5056
|
+
),
|
|
5057
|
+
files.length > 0 && // 파일 칸끼리는 말풍선과 같은 간격으로 벌린다 — 한 덩어리 안의 여러 발화로 읽힌다.
|
|
5058
|
+
// 말풍선과 달리 면으로 감싸지 않는다 (`attachments` 주석 참고).
|
|
5059
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5060
|
+
"div",
|
|
5061
|
+
{
|
|
5062
|
+
className: cn(
|
|
5063
|
+
"flex min-w-0 flex-col gap-(--cmp-chatMessage-group-bubble-gap)",
|
|
5064
|
+
outgoing ? "items-end" : "items-start"
|
|
5065
|
+
),
|
|
5066
|
+
children: files.map((file, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-full", children: file }, index))
|
|
5067
|
+
}
|
|
5068
|
+
),
|
|
5069
|
+
(readStatus != null || time != null) && // 읽음 표시와 시각은 한 줄에 선다 — 읽음이 먼저, 시각이 뒤다.
|
|
5070
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-(--cmp-chatMessage-subData-gap) px-(--cmp-chatMessage-subData-paddingX)", children: [
|
|
5071
|
+
readStatus != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("typo-body-sm-bold", READ_STATUS_COLOR[readStatus]), children: READ_STATUS_LABEL[readStatus] }),
|
|
5072
|
+
time != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-medium text-(--cmp-chatTimeStamp-color)", children: time })
|
|
5073
|
+
] }),
|
|
5074
|
+
actions != null && // 버튼이 많아 한 줄에 안 들어가면 감싼다 — 넘쳐서 잘리는 것보다 낫다.
|
|
5075
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5076
|
+
"div",
|
|
5077
|
+
{
|
|
5078
|
+
className: cn(
|
|
5079
|
+
"flex flex-wrap gap-sd-8 px-(--cmp-chatMessage-bottomButtons-paddingX)",
|
|
5080
|
+
outgoing && "justify-end"
|
|
5081
|
+
),
|
|
5082
|
+
children: actions
|
|
5083
|
+
}
|
|
5084
|
+
)
|
|
5085
|
+
]
|
|
5086
|
+
}
|
|
5087
|
+
)
|
|
4969
5088
|
]
|
|
4970
5089
|
}
|
|
4971
5090
|
);
|
|
@@ -4981,14 +5100,13 @@ var SChatSystemMessageImpl = /* @__PURE__ */ react.forwardRef(
|
|
|
4981
5100
|
"span",
|
|
4982
5101
|
{
|
|
4983
5102
|
className: cn(
|
|
4984
|
-
//
|
|
4985
|
-
//
|
|
4986
|
-
//
|
|
4987
|
-
|
|
4988
|
-
"
|
|
4989
|
-
"
|
|
4990
|
-
"
|
|
4991
|
-
"px-sd-16 py-sd-4 text-center",
|
|
5103
|
+
// 라운드는 말풍선과 같은 토큰을 쓴다 — 여러 줄이 돼도 모서리가 상자 높이를 따라
|
|
5104
|
+
// 부풀지 않는다. 제 몫인 chatSystemMessage.radius 는 pill(9999px)이라 쓰지 않는다.
|
|
5105
|
+
// 두 줄부터 좌우가 커다란 반원이 되어 첫 글자가 안으로 밀리기 때문이다.
|
|
5106
|
+
"inline-flex max-w-full rounded-(--cmp-chatBubble-radius) border",
|
|
5107
|
+
"border-(--cmp-chatSystemMessage-border-color) bg-(--cmp-chatSystemMessage-bg)",
|
|
5108
|
+
"typo-body-sm-medium text-(--cmp-chatSystemMessage-color)",
|
|
5109
|
+
"px-(--cmp-chatSystemMessage-paddingX) py-(--cmp-chatSystemMessage-paddingY) text-center",
|
|
4992
5110
|
// 한글은 기본 규칙으로 두면 어절 한가운데서도 줄이 바뀐다 — 띄어쓰기에서만 끊고,
|
|
4993
5111
|
// 끊을 자리가 없는 긴 토큰(URL·주문번호)만 흘려보낸다 (SChatMessage 말풍선과 같은 규칙).
|
|
4994
5112
|
// 가운데 정렬이라 마지막 줄에 한 단어만 남으면 특히 눈에 띄므로 text-pretty 로 줄을 고른다.
|
|
@@ -6313,10 +6431,21 @@ function SCheckbox({
|
|
|
6313
6431
|
) })
|
|
6314
6432
|
}
|
|
6315
6433
|
),
|
|
6316
|
-
label && // 고스트(500) 텍스트로 너비를 고정 → 두께 400↔500 전환 시 레이아웃이 밀리지
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6434
|
+
label && // 고스트(500) 텍스트로 너비를 고정 → 두께 400↔500 전환 시 레이아웃이 밀리지 않음.
|
|
6435
|
+
// 한글은 기본 규칙으로 두면 어절 한가운데서도 줄이 바뀐다. 그러면 min-content 가 한 글자가
|
|
6436
|
+
// 되어, flex 아이템을 지켜 주는 min-width:auto 가 무력해지고 폭이 남는데도 라벨부터
|
|
6437
|
+
// 찌그러진다 — 띄어쓰기에서만 끊고, 끊을 자리가 없는 긴 토큰만 흘려보낸다
|
|
6438
|
+
// (SRadio·SSwitch 라벨과 같은 규칙). 두 사본에 함께 걸려야 하므로 바깥 grid 에 준다.
|
|
6439
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "grid break-keep wrap-break-word", style: { color: labelColor }, children: [
|
|
6440
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "typo-body-sm-medium invisible", style: { gridArea: "1 / 1" }, children: label }),
|
|
6441
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6442
|
+
"span",
|
|
6443
|
+
{
|
|
6444
|
+
className: isChecked ? "typo-body-sm-medium" : "typo-body-sm-default",
|
|
6445
|
+
style: { gridArea: "1 / 1" },
|
|
6446
|
+
children: label
|
|
6447
|
+
}
|
|
6448
|
+
)
|
|
6320
6449
|
] })
|
|
6321
6450
|
]
|
|
6322
6451
|
}
|
|
@@ -7770,7 +7899,7 @@ function SSwitch({
|
|
|
7770
7899
|
style
|
|
7771
7900
|
}) {
|
|
7772
7901
|
const right = rightLabel;
|
|
7773
|
-
const renderLabel = (text) => text ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "
|
|
7902
|
+
const renderLabel = (text) => text ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-medium break-keep wrap-break-word", children: text }) : null;
|
|
7774
7903
|
const trackBg = disabled ? value ? "var(--cmp-switch-bg-disabled-on)" : "var(--cmp-switch-bg-disabled-off)" : value ? "var(--cmp-switch-bg-on)" : "var(--cmp-switch-bg-off)";
|
|
7775
7904
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7776
7905
|
"label",
|
|
@@ -11777,7 +11906,7 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
|
11777
11906
|
// plain 에는 전용 배경 토큰이 없어 시스템 흰 표면을 쓴다(토큰이 생기면 그것으로 갈아끼운다).
|
|
11778
11907
|
bar ? "h-(--cmp-pageHeader-bar-height) border-b border-(--cmp-pageHeader-bar-border) bg-(--cmp-pageHeader-bar-bg) py-(--cmp-pageHeader-bar-paddingY)" : cn(
|
|
11779
11908
|
// 스크롤되면 그림자를 더해 콘텐츠 위에 뜬 것처럼 보이게 한다.
|
|
11780
|
-
"bg-(--sys-color-bg-frame)
|
|
11909
|
+
"bg-(--sys-color-bg-frame) py-(--cmp-pageHeader-plain-paddingY)",
|
|
11781
11910
|
isScrolled && "shadow-floating"
|
|
11782
11911
|
),
|
|
11783
11912
|
className
|
|
@@ -11787,7 +11916,10 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
|
11787
11916
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11788
11917
|
"div",
|
|
11789
11918
|
{
|
|
11790
|
-
className:
|
|
11919
|
+
className: cn(
|
|
11920
|
+
"flex min-w-0 flex-1 gap-(--cmp-pageHeader-gap)",
|
|
11921
|
+
bar ? "items-center" : "items-start"
|
|
11922
|
+
),
|
|
11791
11923
|
style: rowStyle,
|
|
11792
11924
|
children: [
|
|
11793
11925
|
hasBack && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -11797,7 +11929,7 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
|
11797
11929
|
size: "xs",
|
|
11798
11930
|
ariaLabel: "\uB4A4\uB85C\uAC00\uAE30",
|
|
11799
11931
|
onClick: onBack,
|
|
11800
|
-
className: "shrink-0"
|
|
11932
|
+
className: cn("shrink-0", bar ? "" : "mt-[3px]")
|
|
11801
11933
|
}
|
|
11802
11934
|
),
|
|
11803
11935
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -15930,7 +16062,7 @@ function SRadio({
|
|
|
15930
16062
|
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15931
16063
|
"span",
|
|
15932
16064
|
{
|
|
15933
|
-
className: "grid",
|
|
16065
|
+
className: "grid break-keep wrap-break-word",
|
|
15934
16066
|
style: {
|
|
15935
16067
|
color: disabled ? "var(--cmp-radio-label-disabled)" : "var(--cmp-radio-label-default)"
|
|
15936
16068
|
},
|
|
@@ -23568,7 +23700,7 @@ exports.CALENDAR_BOARD_EVENT_COLORS = CALENDAR_BOARD_EVENT_COLORS;
|
|
|
23568
23700
|
exports.CALENDAR_BOARD_EVENT_PRESETS = CALENDAR_BOARD_EVENT_PRESETS;
|
|
23569
23701
|
exports.CALENDAR_BOARD_MAX_VISIBLE_EVENTS = CALENDAR_BOARD_MAX_VISIBLE_EVENTS;
|
|
23570
23702
|
exports.CHAT_ATTACHED_FILE_CONFIG = CHAT_ATTACHED_FILE_CONFIG;
|
|
23571
|
-
exports.
|
|
23703
|
+
exports.CHAT_FILE_CONFIG = CHAT_FILE_CONFIG;
|
|
23572
23704
|
exports.CHAT_MESSAGE_DIRECTIONS = CHAT_MESSAGE_DIRECTIONS;
|
|
23573
23705
|
exports.CHAT_MESSAGE_READ_STATUSES = CHAT_MESSAGE_READ_STATUSES;
|
|
23574
23706
|
exports.CHAT_MESSAGE_VARIANTS = CHAT_MESSAGE_VARIANTS;
|
|
@@ -23606,6 +23738,7 @@ exports.SCalendarBoard = SCalendarBoard;
|
|
|
23606
23738
|
exports.SCallout = SCallout;
|
|
23607
23739
|
exports.SCard = SCard;
|
|
23608
23740
|
exports.SChatAttachedFile = SChatAttachedFile2;
|
|
23741
|
+
exports.SChatFile = SChatFile2;
|
|
23609
23742
|
exports.SChatInput = SChatInput2;
|
|
23610
23743
|
exports.SChatMessage = SChatMessage2;
|
|
23611
23744
|
exports.SChatSystemMessage = SChatSystemMessage2;
|