sellmate-design-system-react 2.1.0 → 2.1.2
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/SActionModal/SActionModal.cjs +8 -2
- package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
- package/dist/components/SActionModal/SActionModal.d.ts +11 -2
- package/dist/components/SActionModal/SActionModal.js +8 -2
- package/dist/components/SActionModal/SActionModal.js.map +1 -1
- package/dist/components/SChipInput/SChipInput.cjs +9 -2
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.js +9 -2
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.cjs +101 -8
- package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.d.ts +4 -3
- package/dist/components/SConfirmModal/SConfirmModal.js +101 -8
- package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
- package/dist/components/SExpansionItem/SExpansionItem.cjs +11 -11
- package/dist/components/SExpansionItem/SExpansionItem.cjs.map +1 -1
- package/dist/components/SExpansionItem/SExpansionItem.js +11 -11
- package/dist/components/SExpansionItem/SExpansionItem.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +20 -19
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +57 -4
- package/dist/components/SKeyValueTable/SKeyValueTable.js +20 -19
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +8 -2
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +8 -2
- package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
- package/dist/components/SModal/SModal.cjs +101 -8
- package/dist/components/SModal/SModal.cjs.map +1 -1
- package/dist/components/SModal/SModal.js +101 -8
- package/dist/components/SModal/SModal.js.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.cjs +8 -2
- package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.js +8 -2
- package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
- package/dist/components/SSelect/SSelect.cjs +20 -19
- package/dist/components/SSelect/SSelect.cjs.map +1 -1
- package/dist/components/SSelect/SSelect.js +20 -19
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/SStepper/SStepper.cjs +1 -1
- package/dist/components/SStepper/SStepper.cjs.map +1 -1
- package/dist/components/SStepper/SStepper.js +1 -1
- package/dist/components/SStepper/SStepper.js.map +1 -1
- package/dist/components/STable/STable.cjs +20 -19
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +20 -19
- package/dist/components/STable/STable.js.map +1 -1
- package/dist/components/STimePicker/STimePicker.cjs +1 -1
- package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
- package/dist/components/STimePicker/STimePicker.js +1 -1
- package/dist/components/STimePicker/STimePicker.js.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
- package/dist/index.cjs +75 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -43
- package/dist/index.js.map +1 -1
- package/dist/styles.css +303 -195
- package/dist/theme.css +229 -121
- package/package.json +1 -1
|
@@ -13,8 +13,9 @@ export interface SConfirmModalProps {
|
|
|
13
13
|
modalTitle?: string;
|
|
14
14
|
/** 제목 엘리먼트에 추가할 클래스 (sd-confirm-modal titleClass) */
|
|
15
15
|
titleClass?: string;
|
|
16
|
-
/**
|
|
16
|
+
/** 콘텐츠 박스 상단 메시지 목록 (각 항목이 한 줄, HTML 문자열 허용 — innerHTML 렌더링) */
|
|
17
17
|
topMessage?: string[];
|
|
18
|
+
/** 콘텐츠 박스 하단 메시지 목록 (각 항목이 한 줄, HTML 문자열 허용 — innerHTML 렌더링) */
|
|
18
19
|
bottomMessage?: string[];
|
|
19
20
|
/** tag 슬롯 기본 태그 레이블 (tagSlot 미지정 시) */
|
|
20
21
|
tagLabel?: string;
|
|
@@ -22,11 +23,11 @@ export interface SConfirmModalProps {
|
|
|
22
23
|
tagShape?: STagShape;
|
|
23
24
|
tagSize?: STagSize;
|
|
24
25
|
tagColor?: STagColor;
|
|
25
|
-
/**
|
|
26
|
+
/** 콘텐츠 박스에서 태그 오른쪽에 오는 텍스트 (optionSlot 미지정 시) */
|
|
26
27
|
slotLabel?: string;
|
|
27
28
|
/** 콘텐츠 박스 tag 위치 커스텀 콘텐츠 (미지정 시 tagLabel 기반 STag) */
|
|
28
29
|
tagSlot?: ReactNode;
|
|
29
|
-
/** 콘텐츠
|
|
30
|
+
/** 콘텐츠 박스에서 태그 오른쪽 커스텀 콘텐츠 (미지정 시 slotLabel 텍스트) */
|
|
30
31
|
optionSlot?: ReactNode;
|
|
31
32
|
/** 메인 버튼 */
|
|
32
33
|
mainButtonLabel?: string;
|
|
@@ -3142,11 +3142,17 @@ function SModalContainer({
|
|
|
3142
3142
|
/* @__PURE__ */ jsx(InsideModalProvider, { value: true, children: /* @__PURE__ */ jsx(PortalContainerProvider, { value: portalContainer, children }) })
|
|
3143
3143
|
]
|
|
3144
3144
|
}
|
|
3145
|
+
),
|
|
3146
|
+
/* @__PURE__ */ jsx(
|
|
3147
|
+
"div",
|
|
3148
|
+
{
|
|
3149
|
+
ref: setPortalContainer,
|
|
3150
|
+
className: "pointer-events-auto fixed left-0 top-0 z-[1001]"
|
|
3151
|
+
}
|
|
3145
3152
|
)
|
|
3146
3153
|
]
|
|
3147
3154
|
}
|
|
3148
|
-
) })
|
|
3149
|
-
/* @__PURE__ */ jsx("div", { ref: setPortalContainer, className: "pointer-events-auto fixed left-0 top-0 z-[1001]" })
|
|
3155
|
+
) })
|
|
3150
3156
|
] }) });
|
|
3151
3157
|
}
|
|
3152
3158
|
|
|
@@ -3315,6 +3321,75 @@ var SButton = forwardRef(function SButton2({
|
|
|
3315
3321
|
}
|
|
3316
3322
|
);
|
|
3317
3323
|
});
|
|
3324
|
+
|
|
3325
|
+
// src/lib/sanitize-inline-html.ts
|
|
3326
|
+
var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
|
|
3327
|
+
var ALLOWED_ATTRS_BY_TAG = {
|
|
3328
|
+
A: /* @__PURE__ */ new Set(["href", "target", "rel", "class"])
|
|
3329
|
+
};
|
|
3330
|
+
var COMMON_ALLOWED_ATTRS = /* @__PURE__ */ new Set(["class"]);
|
|
3331
|
+
var SAFE_HREF_RE = /^(https?:|mailto:|tel:|\/|#|\.)/i;
|
|
3332
|
+
var DROP_CONTENT_TAGS = /* @__PURE__ */ new Set([
|
|
3333
|
+
"SCRIPT",
|
|
3334
|
+
"STYLE",
|
|
3335
|
+
"IFRAME",
|
|
3336
|
+
"OBJECT",
|
|
3337
|
+
"EMBED",
|
|
3338
|
+
"META",
|
|
3339
|
+
"LINK",
|
|
3340
|
+
"BASE",
|
|
3341
|
+
"NOSCRIPT",
|
|
3342
|
+
// SVG/MATH 는 foreign-content 파싱 모드로 전환되어 재직렬화 시 다른 트리로
|
|
3343
|
+
// 재파싱될 수 있다(mXSS 벡터). 인라인 라벨에 필요 없으므로 통째로 제거한다.
|
|
3344
|
+
"SVG",
|
|
3345
|
+
"MATH",
|
|
3346
|
+
"TEMPLATE"
|
|
3347
|
+
]);
|
|
3348
|
+
var escapeHtml = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3349
|
+
var sanitizeNode = (node) => {
|
|
3350
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
3351
|
+
node.remove();
|
|
3352
|
+
return;
|
|
3353
|
+
}
|
|
3354
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return;
|
|
3355
|
+
const element = node;
|
|
3356
|
+
const tagName = element.tagName;
|
|
3357
|
+
if (DROP_CONTENT_TAGS.has(tagName)) {
|
|
3358
|
+
element.remove();
|
|
3359
|
+
return;
|
|
3360
|
+
}
|
|
3361
|
+
Array.from(element.childNodes).forEach((child) => sanitizeNode(child));
|
|
3362
|
+
if (ALLOWED_INLINE_TAGS.has(tagName)) {
|
|
3363
|
+
if (element.hasAttribute("className")) {
|
|
3364
|
+
const val = element.getAttribute("className");
|
|
3365
|
+
element.removeAttribute("className");
|
|
3366
|
+
if (!element.hasAttribute("class")) element.setAttribute("class", val);
|
|
3367
|
+
}
|
|
3368
|
+
const allowedAttrs = ALLOWED_ATTRS_BY_TAG[tagName] ?? COMMON_ALLOWED_ATTRS;
|
|
3369
|
+
Array.from(element.attributes).forEach((attr) => {
|
|
3370
|
+
if (!allowedAttrs.has(attr.name)) element.removeAttribute(attr.name);
|
|
3371
|
+
});
|
|
3372
|
+
if (tagName === "A") {
|
|
3373
|
+
const href = element.getAttribute("href");
|
|
3374
|
+
if (href !== null && href !== "" && !SAFE_HREF_RE.test(href)) element.removeAttribute("href");
|
|
3375
|
+
if (element.hasAttribute("target")) {
|
|
3376
|
+
element.setAttribute("rel", "noopener noreferrer");
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
const parent = element.parentNode;
|
|
3382
|
+
if (parent == null) return;
|
|
3383
|
+
while (element.firstChild) parent.insertBefore(element.firstChild, element);
|
|
3384
|
+
parent.removeChild(element);
|
|
3385
|
+
};
|
|
3386
|
+
var sanitizeInlineHtml = (value) => {
|
|
3387
|
+
if (typeof document === "undefined") return escapeHtml(value);
|
|
3388
|
+
const template = document.createElement("template");
|
|
3389
|
+
template.innerHTML = value;
|
|
3390
|
+
Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
|
|
3391
|
+
return template.innerHTML;
|
|
3392
|
+
};
|
|
3318
3393
|
var TYPE_ICON = {
|
|
3319
3394
|
positive: "notificationOutline",
|
|
3320
3395
|
negative: "warningOutline",
|
|
@@ -3364,7 +3439,8 @@ function SConfirmModal({
|
|
|
3364
3439
|
const mainStyle = MAIN_BUTTON_STYLE[mainButtonName ?? DEFAULT_MAIN_BUTTON[type]];
|
|
3365
3440
|
const tagNode = tagSlot ?? (tagLabel ? /* @__PURE__ */ jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }) : null);
|
|
3366
3441
|
const optionNode = optionSlot ?? (slotLabel ? /* @__PURE__ */ jsx("span", { children: slotLabel }) : null);
|
|
3367
|
-
const
|
|
3442
|
+
const hasContentBox = tagNode != null || optionNode != null;
|
|
3443
|
+
const hasBody = topMessage.length > 0 || bottomMessage.length > 0 || hasContentBox;
|
|
3368
3444
|
return /* @__PURE__ */ jsx(
|
|
3369
3445
|
SModalContainer,
|
|
3370
3446
|
{
|
|
@@ -3391,11 +3467,28 @@ function SConfirmModal({
|
|
|
3391
3467
|
)
|
|
3392
3468
|
] }),
|
|
3393
3469
|
hasBody && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)] w-full", children: [
|
|
3394
|
-
topMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: topMessage.map((m, i) => /* @__PURE__ */ jsx(
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3470
|
+
topMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: topMessage.map((m, i) => /* @__PURE__ */ jsx(
|
|
3471
|
+
"p",
|
|
3472
|
+
{
|
|
3473
|
+
className: "m-0",
|
|
3474
|
+
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(m) }
|
|
3475
|
+
},
|
|
3476
|
+
i
|
|
3477
|
+
)) }),
|
|
3478
|
+
hasContentBox && // content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
|
|
3479
|
+
// tag 왼쪽, slotLabel/optionSlot 이 그 오른쪽에 gap 8 로 나란히 놓인다
|
|
3480
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px] w-full", children: [
|
|
3481
|
+
tagNode,
|
|
3482
|
+
optionNode
|
|
3483
|
+
] }),
|
|
3484
|
+
bottomMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsx(
|
|
3485
|
+
"p",
|
|
3486
|
+
{
|
|
3487
|
+
className: "m-0",
|
|
3488
|
+
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(m) }
|
|
3489
|
+
},
|
|
3490
|
+
i
|
|
3491
|
+
)) })
|
|
3399
3492
|
] })
|
|
3400
3493
|
] }),
|
|
3401
3494
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-shrink-0 gap-[8px]", children: [
|