sellmate-design-system-react 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/components/SCallout/SCallout.cjs +76 -1
  2. package/dist/components/SCallout/SCallout.cjs.map +1 -1
  3. package/dist/components/SCallout/SCallout.d.ts +6 -2
  4. package/dist/components/SCallout/SCallout.js +76 -1
  5. package/dist/components/SCallout/SCallout.js.map +1 -1
  6. package/dist/components/SDraggableItem/SDraggableItem.cjs +3079 -0
  7. package/dist/components/SDraggableItem/SDraggableItem.cjs.map +1 -0
  8. package/dist/components/SDraggableItem/SDraggableItem.d.ts +33 -0
  9. package/dist/components/SDraggableItem/SDraggableItem.js +3077 -0
  10. package/dist/components/SDraggableItem/SDraggableItem.js.map +1 -0
  11. package/dist/components/SDraggableItem/index.d.ts +1 -0
  12. package/dist/components/SExpansionItem/SExpansionItem.cjs +6 -15
  13. package/dist/components/SExpansionItem/SExpansionItem.cjs.map +1 -1
  14. package/dist/components/SExpansionItem/SExpansionItem.js +6 -15
  15. package/dist/components/SExpansionItem/SExpansionItem.js.map +1 -1
  16. package/dist/components/SList/SList.cjs +38 -0
  17. package/dist/components/SList/SList.cjs.map +1 -0
  18. package/dist/components/SList/SList.d.ts +10 -0
  19. package/dist/components/SList/SList.js +36 -0
  20. package/dist/components/SList/SList.js.map +1 -0
  21. package/dist/components/SList/index.d.ts +1 -0
  22. package/dist/components/SListItem/SListItem.cjs +83 -0
  23. package/dist/components/SListItem/SListItem.cjs.map +1 -0
  24. package/dist/components/SListItem/SListItem.d.ts +26 -0
  25. package/dist/components/SListItem/SListItem.js +81 -0
  26. package/dist/components/SListItem/SListItem.js.map +1 -0
  27. package/dist/components/SListItem/index.d.ts +1 -0
  28. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.cjs +3414 -0
  29. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.cjs.map +1 -0
  30. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.d.ts +32 -0
  31. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.js +3392 -0
  32. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.js.map +1 -0
  33. package/dist/components/SSectionHeaderCard/index.d.ts +1 -0
  34. package/dist/index.cjs +815 -419
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.ts +4 -0
  37. package/dist/index.js +815 -423
  38. package/dist/index.js.map +1 -1
  39. package/dist/styles.css +336 -19
  40. package/dist/theme.css +14 -0
  41. package/package.json +1 -1
@@ -5,7 +5,10 @@ export type SCalloutMessage = string | SCalloutMessage[];
5
5
  export interface SCalloutProps {
6
6
  /** 콜아웃 타입 (색상·아이콘·타이틀 결정) */
7
7
  type?: SCalloutType;
8
- /** 표시할 메시지 목록 (배열 중첩으로 depth 표현) */
8
+ /**
9
+ * 표시할 메시지 목록 (배열 중첩으로 depth 표현).
10
+ * 각 문자열은 인라인 HTML(`<b>`, `<a>` 등)을 허용하며 sanitizeInlineHtml 로 살균 후 렌더된다.
11
+ */
9
12
  message?: SCalloutMessage[];
10
13
  /** message 대신 직접 본문을 넣을 때 */
11
14
  children?: ReactNode;
@@ -15,6 +18,7 @@ export interface SCalloutProps {
15
18
  /**
16
19
  * SCallout — sd-callout 포팅.
17
20
  * default/danger 타입, 중첩 리스트(불릿은 span으로 렌더), danger는 좌측 타이틀 표시.
18
- * 색상은 `--cmp-callout-*` 토큰 참조. (원본의 innerHTML 주입은 안전상 제외 — 평문 렌더)
21
+ * 색상은 `--cmp-callout-*` 토큰 참조.
22
+ * message 각 항목은 sanitizeInlineHtml 로 살균한 뒤 innerHTML 로 렌더한다 (원본 sd-callout 과 동일).
19
23
  */
20
24
  export declare const SCallout: import("react").ForwardRefExoticComponent<SCalloutProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -15,6 +15,75 @@ function cn(...inputs) {
15
15
  return twMerge(clsx(inputs));
16
16
  }
17
17
 
18
+ // src/lib/sanitize-inline-html.ts
19
+ var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
20
+ var ALLOWED_ATTRS_BY_TAG = {
21
+ A: /* @__PURE__ */ new Set(["href", "target", "rel", "class"])
22
+ };
23
+ var COMMON_ALLOWED_ATTRS = /* @__PURE__ */ new Set(["class"]);
24
+ var SAFE_HREF_RE = /^(https?:|mailto:|tel:|\/|#|\.)/i;
25
+ var DROP_CONTENT_TAGS = /* @__PURE__ */ new Set([
26
+ "SCRIPT",
27
+ "STYLE",
28
+ "IFRAME",
29
+ "OBJECT",
30
+ "EMBED",
31
+ "META",
32
+ "LINK",
33
+ "BASE",
34
+ "NOSCRIPT",
35
+ // SVG/MATH 는 foreign-content 파싱 모드로 전환되어 재직렬화 시 다른 트리로
36
+ // 재파싱될 수 있다(mXSS 벡터). 인라인 라벨에 필요 없으므로 통째로 제거한다.
37
+ "SVG",
38
+ "MATH",
39
+ "TEMPLATE"
40
+ ]);
41
+ var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
42
+ var sanitizeNode = (node) => {
43
+ if (node.nodeType === Node.COMMENT_NODE) {
44
+ node.remove();
45
+ return;
46
+ }
47
+ if (node.nodeType !== Node.ELEMENT_NODE) return;
48
+ const element = node;
49
+ const tagName = element.tagName;
50
+ if (DROP_CONTENT_TAGS.has(tagName)) {
51
+ element.remove();
52
+ return;
53
+ }
54
+ Array.from(element.childNodes).forEach((child) => sanitizeNode(child));
55
+ if (ALLOWED_INLINE_TAGS.has(tagName)) {
56
+ if (element.hasAttribute("className")) {
57
+ const val = element.getAttribute("className");
58
+ element.removeAttribute("className");
59
+ if (!element.hasAttribute("class")) element.setAttribute("class", val);
60
+ }
61
+ const allowedAttrs = ALLOWED_ATTRS_BY_TAG[tagName] ?? COMMON_ALLOWED_ATTRS;
62
+ Array.from(element.attributes).forEach((attr) => {
63
+ if (!allowedAttrs.has(attr.name)) element.removeAttribute(attr.name);
64
+ });
65
+ if (tagName === "A") {
66
+ const href = element.getAttribute("href");
67
+ if (href !== null && href !== "" && !SAFE_HREF_RE.test(href)) element.removeAttribute("href");
68
+ if (element.hasAttribute("target")) {
69
+ element.setAttribute("rel", "noopener noreferrer");
70
+ }
71
+ }
72
+ return;
73
+ }
74
+ const parent = element.parentNode;
75
+ if (parent == null) return;
76
+ while (element.firstChild) parent.insertBefore(element.firstChild, element);
77
+ parent.removeChild(element);
78
+ };
79
+ var sanitizeInlineHtml = (value) => {
80
+ if (typeof document === "undefined") return escapeHtml(value);
81
+ const template = document.createElement("template");
82
+ template.innerHTML = value;
83
+ Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
84
+ return template.innerHTML;
85
+ };
86
+
18
87
  // src/lib/color.ts
19
88
  var COLOR_KEYS = [
20
89
  "white",
@@ -2865,7 +2934,13 @@ function renderItems(message, depth = 1) {
2865
2934
  className: cn("flex items-start", isDepth2 && "pl-[32px]"),
2866
2935
  children: [
2867
2936
  /* @__PURE__ */ jsx("span", { className: "w-[24px] shrink-0 text-center", "aria-hidden": true, children: isDepth2 ? "\u2022" : "-" }),
2868
- /* @__PURE__ */ jsx("p", { className: "m-0 min-w-0 flex-1 break-words", children: m })
2937
+ /* @__PURE__ */ jsx(
2938
+ "p",
2939
+ {
2940
+ className: "m-0 min-w-0 flex-1 break-words",
2941
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(m) }
2942
+ }
2943
+ )
2869
2944
  ]
2870
2945
  },
2871
2946
  `${depth}-${i}-${out.length}`