@ncds/ui-admin 1.8.25 → 1.8.26-alpha.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 (127) hide show
  1. package/dist/cjs/assets/scripts/notification/FullWidthNotification.js +2 -0
  2. package/dist/cjs/assets/scripts/notification/MessageNotification.js +30 -23
  3. package/dist/cjs/assets/scripts/notification/const/classNames.js +3 -0
  4. package/dist/cjs/assets/scripts/notification/const/icons.js +11 -2
  5. package/dist/cjs/assets/scripts/notification/const/index.js +9 -4
  6. package/dist/cjs/assets/scripts/notification/const/sizes.js +6 -1
  7. package/dist/cjs/assets/scripts/notification/const/types.js +1 -10
  8. package/dist/cjs/assets/scripts/notification/messageTemplate.js +20 -8
  9. package/dist/cjs/assets/scripts/notification/utils.js +21 -17
  10. package/dist/cjs/constant/notification.js +15 -1
  11. package/dist/cjs/src/components/feedback-and-status/badge/Badge.js +1 -1
  12. package/dist/cjs/src/components/forms-and-input/combo-box/ComboBox.js +16 -126
  13. package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  14. package/dist/cjs/src/components/overlays/notification/FloatingNotification.js +4 -7
  15. package/dist/cjs/src/components/overlays/notification/FullWidthNotification.js +13 -8
  16. package/dist/cjs/src/components/overlays/notification/MessageNotification.js +20 -14
  17. package/dist/cjs/src/components/overlays/notification/MessageNotificationParts.js +22 -15
  18. package/dist/cjs/src/components/overlays/notification/Notification.js +6 -0
  19. package/dist/cjs/src/components/overlays/notification/NotificationActionButtons.js +27 -0
  20. package/dist/cjs/src/components/overlays/notification/__tests__/supportTextLink.test.js +58 -0
  21. package/dist/cjs/src/components/overlays/notification/linkTarget.js +18 -0
  22. package/dist/cjs/src/generated/scoped-css.js +1 -1
  23. package/dist/cjs/src/utils/index.js +11 -0
  24. package/dist/cjs/src/utils/url/__tests__/isSafeUrl.test.js +49 -0
  25. package/dist/cjs/src/utils/url/index.js +16 -0
  26. package/dist/cjs/src/utils/url/isSafeUrl.js +32 -0
  27. package/dist/esm/assets/scripts/notification/FullWidthNotification.js +3 -1
  28. package/dist/esm/assets/scripts/notification/MessageNotification.js +32 -25
  29. package/dist/esm/assets/scripts/notification/const/classNames.js +3 -0
  30. package/dist/esm/assets/scripts/notification/const/icons.js +10 -1
  31. package/dist/esm/assets/scripts/notification/const/index.js +2 -3
  32. package/dist/esm/assets/scripts/notification/const/sizes.js +5 -0
  33. package/dist/esm/assets/scripts/notification/const/types.js +1 -8
  34. package/dist/esm/assets/scripts/notification/messageTemplate.js +21 -9
  35. package/dist/esm/assets/scripts/notification/utils.js +19 -16
  36. package/dist/esm/constant/notification.js +14 -0
  37. package/dist/esm/src/components/feedback-and-status/badge/Badge.js +1 -1
  38. package/dist/esm/src/components/forms-and-input/combo-box/ComboBox.js +17 -127
  39. package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  40. package/dist/esm/src/components/overlays/notification/FloatingNotification.js +4 -7
  41. package/dist/esm/src/components/overlays/notification/FullWidthNotification.js +13 -8
  42. package/dist/esm/src/components/overlays/notification/MessageNotification.js +21 -15
  43. package/dist/esm/src/components/overlays/notification/MessageNotificationParts.js +22 -15
  44. package/dist/esm/src/components/overlays/notification/Notification.js +6 -0
  45. package/dist/esm/src/components/overlays/notification/NotificationActionButtons.js +21 -0
  46. package/dist/esm/src/components/overlays/notification/__tests__/supportTextLink.test.js +55 -0
  47. package/dist/esm/src/components/overlays/notification/linkTarget.js +12 -0
  48. package/dist/esm/src/generated/scoped-css.js +1 -1
  49. package/dist/esm/src/utils/index.js +3 -1
  50. package/dist/esm/src/utils/url/__tests__/isSafeUrl.test.js +47 -0
  51. package/dist/esm/src/utils/url/index.js +1 -0
  52. package/dist/esm/src/utils/url/isSafeUrl.js +26 -0
  53. package/dist/temp/assets/scripts/notification/FullWidthNotification.js +3 -2
  54. package/dist/temp/assets/scripts/notification/MessageNotification.d.ts +2 -0
  55. package/dist/temp/assets/scripts/notification/MessageNotification.js +30 -25
  56. package/dist/temp/assets/scripts/notification/const/classNames.d.ts +3 -0
  57. package/dist/temp/assets/scripts/notification/const/classNames.js +3 -0
  58. package/dist/temp/assets/scripts/notification/const/icons.d.ts +6 -0
  59. package/dist/temp/assets/scripts/notification/const/icons.js +9 -0
  60. package/dist/temp/assets/scripts/notification/const/index.d.ts +3 -4
  61. package/dist/temp/assets/scripts/notification/const/index.js +2 -3
  62. package/dist/temp/assets/scripts/notification/const/sizes.d.ts +4 -0
  63. package/dist/temp/assets/scripts/notification/const/sizes.js +5 -0
  64. package/dist/temp/assets/scripts/notification/const/types.d.ts +28 -1
  65. package/dist/temp/assets/scripts/notification/const/types.js +1 -8
  66. package/dist/temp/assets/scripts/notification/messageTemplate.d.ts +5 -1
  67. package/dist/temp/assets/scripts/notification/messageTemplate.js +16 -11
  68. package/dist/temp/assets/scripts/notification/utils.d.ts +10 -3
  69. package/dist/temp/assets/scripts/notification/utils.js +21 -18
  70. package/dist/temp/constant/notification.d.ts +13 -0
  71. package/dist/temp/constant/notification.js +14 -0
  72. package/dist/temp/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  73. package/dist/temp/src/components/feedback-and-status/badge/Badge.js +1 -1
  74. package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
  75. package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.js +13 -119
  76. package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  77. package/dist/temp/src/components/overlays/notification/FloatingNotification.js +2 -2
  78. package/dist/temp/src/components/overlays/notification/FullWidthNotification.d.ts +6 -1
  79. package/dist/temp/src/components/overlays/notification/FullWidthNotification.js +7 -2
  80. package/dist/temp/src/components/overlays/notification/MessageNotification.d.ts +15 -1
  81. package/dist/temp/src/components/overlays/notification/MessageNotification.js +11 -12
  82. package/dist/temp/src/components/overlays/notification/MessageNotificationParts.d.ts +10 -5
  83. package/dist/temp/src/components/overlays/notification/MessageNotificationParts.js +9 -6
  84. package/dist/temp/src/components/overlays/notification/Notification.d.ts +23 -2
  85. package/dist/temp/src/components/overlays/notification/Notification.js +3 -3
  86. package/dist/temp/src/components/overlays/notification/NotificationActionButtons.d.ts +12 -0
  87. package/dist/temp/src/components/overlays/notification/NotificationActionButtons.js +9 -0
  88. package/dist/temp/src/components/overlays/notification/__tests__/supportTextLink.test.js +73 -0
  89. package/dist/temp/src/components/overlays/notification/linkTarget.d.ts +11 -0
  90. package/dist/temp/src/components/overlays/notification/linkTarget.js +9 -0
  91. package/dist/temp/src/generated/scoped-css.js +1 -1
  92. package/dist/temp/src/utils/index.d.ts +1 -0
  93. package/dist/temp/src/utils/index.js +2 -0
  94. package/dist/temp/src/utils/url/__tests__/isSafeUrl.test.js +61 -0
  95. package/dist/temp/src/utils/url/index.d.ts +1 -0
  96. package/dist/temp/src/utils/url/index.js +1 -0
  97. package/dist/temp/src/utils/url/isSafeUrl.d.ts +8 -0
  98. package/dist/temp/src/utils/url/isSafeUrl.js +29 -0
  99. package/dist/types/assets/scripts/notification/MessageNotification.d.ts +2 -0
  100. package/dist/types/assets/scripts/notification/const/classNames.d.ts +3 -0
  101. package/dist/types/assets/scripts/notification/const/icons.d.ts +6 -0
  102. package/dist/types/assets/scripts/notification/const/index.d.ts +3 -4
  103. package/dist/types/assets/scripts/notification/const/sizes.d.ts +4 -0
  104. package/dist/types/assets/scripts/notification/const/types.d.ts +28 -1
  105. package/dist/types/assets/scripts/notification/messageTemplate.d.ts +5 -1
  106. package/dist/types/assets/scripts/notification/utils.d.ts +10 -3
  107. package/dist/types/constant/notification.d.ts +13 -0
  108. package/dist/types/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  109. package/dist/types/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
  110. package/dist/types/src/components/overlays/notification/FullWidthNotification.d.ts +6 -1
  111. package/dist/types/src/components/overlays/notification/MessageNotification.d.ts +15 -1
  112. package/dist/types/src/components/overlays/notification/MessageNotificationParts.d.ts +10 -5
  113. package/dist/types/src/components/overlays/notification/Notification.d.ts +23 -2
  114. package/dist/types/src/components/overlays/notification/NotificationActionButtons.d.ts +12 -0
  115. package/dist/types/src/components/overlays/notification/__tests__/supportTextLink.test.d.ts +1 -0
  116. package/dist/types/src/components/overlays/notification/linkTarget.d.ts +11 -0
  117. package/dist/types/src/utils/index.d.ts +1 -0
  118. package/dist/types/src/utils/url/__tests__/isSafeUrl.test.d.ts +1 -0
  119. package/dist/types/src/utils/url/index.d.ts +1 -0
  120. package/dist/types/src/utils/url/isSafeUrl.d.ts +8 -0
  121. package/dist/ui-admin/assets/styles/style.css +54 -34
  122. package/package.json +1 -1
  123. package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +0 -455
  124. package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +0 -452
  125. package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +0 -293
  126. /package/dist/temp/src/components/{forms-and-input/combo-box/__tests__/ComboBox.test.d.ts → overlays/notification/__tests__/supportTextLink.test.d.ts} +0 -0
  127. /package/dist/{types/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.d.ts → temp/src/utils/url/__tests__/isSafeUrl.test.d.ts} +0 -0
@@ -11,10 +11,10 @@ var _react = require("react");
11
11
  var _reactDom = require("react-dom");
12
12
  var _breakpoint = require("../../../constant/breakpoint");
13
13
  var _useMediaQuery = require("../../../hooks/useMediaQuery");
14
- var _button = require("../../action/button");
15
14
  var _ButtonCloseX = require("../../action/button/ButtonCloseX");
16
15
  var _FeaturedIcon = require("../../image-and-icons/featured-icon/FeaturedIcon");
17
16
  var _host = require("./host");
17
+ var _NotificationActionButtons = require("./NotificationActionButtons");
18
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
19
  // 호스트 싱글톤은 vanilla/React 양쪽이 동일한 함수를 공유한다 — host.ts 가 가까운 진입점 역할을
20
20
  // 하므로 React 컴포넌트는 deep relative path 로 vanilla internals 를 직접 import 하지 않는다.
@@ -157,12 +157,9 @@ const FloatingNotification = exports.FloatingNotification = /*#__PURE__*/(0, _re
157
157
  children: supportingText
158
158
  }), actions && (0, _jsxRuntime.jsx)("div", {
159
159
  className: "ncua-floating-notification__actions",
160
- children: actions.map(action => (0, _jsxRuntime.jsx)(_button.Button, {
161
- size: "xs",
162
- hierarchy: action.hierarchy || 'text',
163
- label: action.label,
164
- onClick: action?.onClick
165
- }, `${action.label}-${action.hierarchy}`))
160
+ children: (0, _jsxRuntime.jsx)(_NotificationActionButtons.NotificationActionButtons, {
161
+ actions: actions
162
+ })
166
163
  })]
167
164
  })]
168
165
  })
@@ -10,6 +10,9 @@ var _classnames = _interopRequireDefault(require("classnames"));
10
10
  var _react = require("react");
11
11
  var _color = require("../../../../constant/color");
12
12
  var _notification = require("../../../../constant/notification");
13
+ var _url = require("../../../utils/url");
14
+ var _linkTarget = require("./linkTarget");
15
+ var _NotificationActionButtons = require("./NotificationActionButtons");
13
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
17
  const iconMap = {
15
18
  neutral: _uiAdminIcon.MessageChatSquare,
@@ -35,11 +38,14 @@ const FullWidthNotification = exports.FullWidthNotification = /*#__PURE__*/(0, _
35
38
  actions,
36
39
  autoClose = 0,
37
40
  supportTextLink,
41
+ supportTextLinkTarget,
38
42
  onHidePermanently,
39
43
  hidePermanentlyLabel = _notification.HIDE_PERMANENTLY_LABEL.fullWidth,
40
44
  ...rest
41
45
  } = _ref;
42
46
  const [shouldRemove, setShouldRemove] = (0, _react.useState)(false);
47
+ // unsafe URL(javascript: 등)이면 링크 없이 텍스트만 렌더한다 — Vanilla `renderSupportingText` 와 같은 정책.
48
+ const safeSupportTextLink = supportTextLink && (0, _url.isSafeUrl)(supportTextLink) ? supportTextLink : undefined;
43
49
  const closeIconSize = {
44
50
  width: 20,
45
51
  height: 20
@@ -93,12 +99,13 @@ const FullWidthNotification = exports.FullWidthNotification = /*#__PURE__*/(0, _
93
99
  children: [(0, _jsxRuntime.jsx)("span", {
94
100
  className: "ncua-full-width-notification__title",
95
101
  children: title
96
- }), !supportTextLink && supportingText && (0, _jsxRuntime.jsx)("span", {
102
+ }), !safeSupportTextLink && supportingText && (0, _jsxRuntime.jsx)("span", {
97
103
  className: "ncua-full-width-notification__supporting-text",
98
104
  children: supportingText
99
- }), supportTextLink && supportingText && (0, _jsxRuntime.jsx)("a", {
100
- href: supportTextLink,
105
+ }), safeSupportTextLink && supportingText && (0, _jsxRuntime.jsx)("a", {
106
+ href: safeSupportTextLink,
101
107
  className: "ncua-full-width-notification__link",
108
+ ...(0, _linkTarget.getLinkTargetAttributes)(supportTextLinkTarget),
102
109
  children: (0, _jsxRuntime.jsx)("span", {
103
110
  className: "ncua-full-width-notification__supporting-text",
104
111
  children: supportingText
@@ -109,11 +116,9 @@ const FullWidthNotification = exports.FullWidthNotification = /*#__PURE__*/(0, _
109
116
  className: "ncua-full-width-notification__actions-container",
110
117
  children: [actions && (0, _jsxRuntime.jsx)("div", {
111
118
  className: "ncua-full-width-notification__actions",
112
- children: actions.map(action => (0, _jsxRuntime.jsx)("button", {
113
- onClick: action.onClick,
114
- className: (0, _classnames.default)('ncua-notification__action-button', `ncua-notification__action-button--${action.hierarchy || 'text'}`),
115
- children: action.label
116
- }, `${action.label}-${action.hierarchy}`))
119
+ children: (0, _jsxRuntime.jsx)(_NotificationActionButtons.NotificationActionButtons, {
120
+ actions: actions
121
+ })
117
122
  }), onHidePermanently && (0, _jsxRuntime.jsx)("button", {
118
123
  type: "button",
119
124
  className: (0, _classnames.default)('ncua-notification__action-button', 'ncua-notification__action-button--text', 'ncua-full-width-notification__link'),
@@ -8,20 +8,16 @@ var _jsxRuntime = require("react/jsx-runtime");
8
8
  var _uiAdminIcon = require("@ncds/ui-admin-icon");
9
9
  var _classnames = _interopRequireDefault(require("classnames"));
10
10
  var _react = require("react");
11
- var _color = require("../../../../constant/color");
11
+ var _notification = require("../../../../constant/notification");
12
12
  var _MessageNotificationParts = require("./MessageNotificationParts");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  const iconMap = {
15
15
  neutral: _uiAdminIcon.Pin02,
16
16
  error: _uiAdminIcon.AlertTriangle,
17
17
  warning: _uiAdminIcon.AlertCircle,
18
- success: _uiAdminIcon.CheckCircle
19
- };
20
- const iconColorMap = {
21
- neutral: 'gray700',
22
- error: 'red500',
23
- warning: 'orange500',
24
- success: 'green600'
18
+ success: _uiAdminIcon.CheckCircle,
19
+ // info 는 variant="block" 에서만 도달한다 (default 는 neutral 로 폴백).
20
+ info: _uiAdminIcon.InfoCircle
25
21
  };
26
22
  const MessageNotification = exports.MessageNotification = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
27
23
  let {
@@ -34,13 +30,21 @@ const MessageNotification = exports.MessageNotification = /*#__PURE__*/(0, _reac
34
30
  actions,
35
31
  onHidePermanently,
36
32
  hidePermanentlyLabel,
33
+ variant = 'default',
34
+ supportTextLink,
35
+ supportTextLinkTarget,
37
36
  ...rest
38
37
  } = _ref;
39
- // message 타입은 neutral, error, warning, success 4가지 색상만 지원
40
- const validColor = color === 'info' ? 'neutral' : color;
38
+ const isBlock = variant === 'block';
39
+ // default 는 neutral, error, warning, success 4가지 색상만 지원 — info 는 block 에서만 유지한다.
40
+ const validColor = !isBlock && color === 'info' ? 'neutral' : color;
41
+ // FeaturedIcon 에는 info 색이 없다. block+info 의 violet 톤은 message SCSS 가 덮어쓴다.
42
+ const featuredIconColor = validColor === 'info' ? 'neutral' : validColor;
41
43
  return (0, _jsxRuntime.jsx)("div", {
42
44
  ref: ref,
43
- className: (0, _classnames.default)('ncua-message-notification', `ncua-message-notification--${validColor}`, className),
45
+ className: (0, _classnames.default)('ncua-message-notification', `ncua-message-notification--${validColor}`, {
46
+ 'ncua-message-notification--block': isBlock
47
+ }, className),
44
48
  role: "alert",
45
49
  ...rest,
46
50
  children: (0, _jsxRuntime.jsx)("div", {
@@ -50,15 +54,17 @@ const MessageNotification = exports.MessageNotification = /*#__PURE__*/(0, _reac
50
54
  children: [(0, _jsxRuntime.jsx)(_MessageNotificationParts.MessageNotificationContent, {
51
55
  title: title,
52
56
  supportingText: supportingText,
57
+ supportTextLink: isBlock ? supportTextLink : undefined,
58
+ supportTextLinkTarget: supportTextLinkTarget,
53
59
  icon: Icon || iconMap[validColor],
54
- iconColor: validColor,
55
- showIcon: Boolean(iconMap[validColor])
60
+ iconColor: featuredIconColor,
61
+ iconSize: isBlock ? 'sm' : 'md'
56
62
  }), (0, _jsxRuntime.jsx)(_MessageNotificationParts.MessageNotificationActions, {
57
63
  actions: actions,
58
64
  onClose: onClose,
59
65
  onHidePermanently: onHidePermanently,
60
66
  hidePermanentlyLabel: hidePermanentlyLabel,
61
- closeIconColor: _color.COLOR[iconColorMap[validColor] || 'gray700']
67
+ closeIconColor: _notification.MESSAGE_CLOSE_ICON_COLOR[validColor]
62
68
  })]
63
69
  })
64
70
  })
@@ -7,26 +7,34 @@ exports.MessageNotificationContent = exports.MessageNotificationActions = void 0
7
7
  var _jsxRuntime = require("react/jsx-runtime");
8
8
  var _uiAdminIcon = require("@ncds/ui-admin-icon");
9
9
  var _notification = require("../../../../constant/notification");
10
- var _button = require("../../action/button");
10
+ var _url = require("../../../utils/url");
11
11
  var _FeaturedIcon = require("../../image-and-icons/featured-icon/FeaturedIcon");
12
- /** 아이콘 + 제목/서포팅 텍스트 영역. */
12
+ var _linkTarget = require("./linkTarget");
13
+ var _NotificationActionButtons = require("./NotificationActionButtons");
14
+ /** 아이콘 + 제목/서포팅 텍스트(또는 텍스트 링크) 영역. */
13
15
  const MessageNotificationContent = _ref => {
14
16
  let {
15
17
  title,
16
18
  supportingText,
19
+ supportTextLink,
20
+ supportTextLinkTarget,
17
21
  icon,
18
22
  iconColor,
19
- showIcon
23
+ iconSize
20
24
  } = _ref;
21
25
  const featuredIconProps = {
22
26
  icon: icon || _uiAdminIcon.Pin02,
23
- size: 'md',
27
+ size: iconSize,
24
28
  color: iconColor,
25
29
  theme: 'light-circle'
26
30
  };
31
+ const supportingTextNode = supportingText && (0, _jsxRuntime.jsx)("span", {
32
+ className: "ncua-message-notification__supporting-text",
33
+ children: supportingText
34
+ });
27
35
  return (0, _jsxRuntime.jsxs)("div", {
28
36
  className: "ncua-message-notification__content-wrapper",
29
- children: [showIcon && (0, _jsxRuntime.jsx)(_FeaturedIcon.FeaturedIcon, {
37
+ children: [(0, _jsxRuntime.jsx)(_FeaturedIcon.FeaturedIcon, {
30
38
  ...featuredIconProps,
31
39
  className: "ncua-message-notification__icon"
32
40
  }), (0, _jsxRuntime.jsxs)("div", {
@@ -34,10 +42,12 @@ const MessageNotificationContent = _ref => {
34
42
  children: [(0, _jsxRuntime.jsx)("span", {
35
43
  className: "ncua-message-notification__title",
36
44
  children: title
37
- }), supportingText && (0, _jsxRuntime.jsx)("span", {
38
- className: "ncua-message-notification__supporting-text",
39
- children: supportingText
40
- })]
45
+ }), supportTextLink && (0, _url.isSafeUrl)(supportTextLink) && supportingTextNode ? (0, _jsxRuntime.jsx)("a", {
46
+ href: supportTextLink,
47
+ className: "ncua-message-notification__link",
48
+ ...(0, _linkTarget.getLinkTargetAttributes)(supportTextLinkTarget),
49
+ children: supportingTextNode
50
+ }) : supportingTextNode]
41
51
  })]
42
52
  });
43
53
  };
@@ -62,12 +72,9 @@ const MessageNotificationActions = _ref2 => {
62
72
  className: "ncua-message-notification__actions-container",
63
73
  children: [hasActions && (0, _jsxRuntime.jsx)("div", {
64
74
  className: "ncua-message-notification__actions",
65
- children: actions?.map(action => (0, _jsxRuntime.jsx)(_button.Button, {
66
- size: "xs",
67
- hierarchy: action.hierarchy || 'text',
68
- label: action.label,
69
- onClick: action?.onClick
70
- }, `${action.label}-${action.hierarchy}`))
75
+ children: (0, _jsxRuntime.jsx)(_NotificationActionButtons.NotificationActionButtons, {
76
+ actions: actions ?? []
77
+ })
71
78
  }), hasFooter && (0, _jsxRuntime.jsxs)("div", {
72
79
  className: "ncua-message-notification__footer-container",
73
80
  children: [onHidePermanently && (0, _jsxRuntime.jsx)("button", {
@@ -19,6 +19,8 @@ const Notification = exports.Notification = /*#__PURE__*/(0, _react.forwardRef)(
19
19
  color = 'neutral',
20
20
  width,
21
21
  supportTextLink,
22
+ supportTextLinkTarget,
23
+ variant,
22
24
  ...rest
23
25
  } = _ref;
24
26
  if (type === 'floating') {
@@ -32,6 +34,7 @@ const Notification = exports.Notification = /*#__PURE__*/(0, _react.forwardRef)(
32
34
  return (0, _jsxRuntime.jsx)(_FullWidthNotification.FullWidthNotification, {
33
35
  color: color,
34
36
  supportTextLink: supportTextLink,
37
+ supportTextLinkTarget: supportTextLinkTarget,
35
38
  ...rest,
36
39
  ref: ref
37
40
  });
@@ -39,6 +42,9 @@ const Notification = exports.Notification = /*#__PURE__*/(0, _react.forwardRef)(
39
42
  if (type === 'message') {
40
43
  return (0, _jsxRuntime.jsx)(_MessageNotification.MessageNotification, {
41
44
  color: color,
45
+ variant: variant,
46
+ supportTextLink: supportTextLink,
47
+ supportTextLinkTarget: supportTextLinkTarget,
42
48
  ...rest,
43
49
  ref: ref
44
50
  });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NotificationActionButtons = void 0;
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ var _button = require("../../action/button");
9
+ /**
10
+ * 알림 액션 버튼 목록. 모든 type 이 같은 규격(`ncua-btn--xs` + hierarchy, 기본 `text`)을 쓴다(#535).
11
+ * Vanilla `renderActions`(assets/scripts/notification/utils.ts)와 같은 클래스를 산출해야 한다.
12
+ * 감싸는 래퍼(`__actions`)는 type 마다 클래스가 달라 호출부가 담당한다.
13
+ */
14
+ const NotificationActionButtons = _ref => {
15
+ let {
16
+ actions
17
+ } = _ref;
18
+ return (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
19
+ children: actions.map(action => (0, _jsxRuntime.jsx)(_button.Button, {
20
+ size: "xs",
21
+ hierarchy: action.hierarchy || 'text',
22
+ label: action.label,
23
+ onClick: action.onClick
24
+ }, `${action.label}-${action.hierarchy}`))
25
+ });
26
+ };
27
+ exports.NotificationActionButtons = NotificationActionButtons;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ var _react = require("react");
4
+ var _client = require("react-dom/client");
5
+ var _testUtils = require("react-dom/test-utils");
6
+ var _vitest = require("vitest");
7
+ var _FullWidthNotification = require("../FullWidthNotification");
8
+ var _MessageNotification = require("../MessageNotification");
9
+ // @vitest-environment jsdom
10
+
11
+ /**
12
+ * React 텍스트 링크(`supportTextLink`)의 프로토콜 검사 (#538 리뷰 H2).
13
+ * Vanilla `renderSupportingText` 와 같은 정책 — unsafe URL 이면 링크 없이 텍스트만 렌더한다.
14
+ */
15
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
16
+ const cleanups = [];
17
+ (0, _vitest.afterEach)(() => {
18
+ for (const cleanup of cleanups.splice(0)) cleanup();
19
+ });
20
+ function mount(element) {
21
+ const container = document.createElement('div');
22
+ document.body.appendChild(container);
23
+ const root = (0, _client.createRoot)(container);
24
+ (0, _testUtils.act)(() => {
25
+ root.render(element);
26
+ });
27
+ cleanups.push(() => {
28
+ (0, _testUtils.act)(() => root.unmount());
29
+ container.remove();
30
+ });
31
+ return container;
32
+ }
33
+ const IMPLEMENTATIONS = [['MessageNotification(block)', supportTextLink => mount(/*#__PURE__*/(0, _react.createElement)(_MessageNotification.MessageNotification, {
34
+ title: '공지',
35
+ variant: 'block',
36
+ supportingText: '자세히 보기',
37
+ supportTextLink
38
+ })), '.ncua-message-notification__supporting-text'], ['FullWidthNotification', supportTextLink => mount(/*#__PURE__*/(0, _react.createElement)(_FullWidthNotification.FullWidthNotification, {
39
+ title: '공지',
40
+ supportingText: '자세히 보기',
41
+ supportTextLink
42
+ })), '.ncua-full-width-notification__supporting-text']];
43
+ const UNSAFE = ['javascript:alert(1)', ' JavaScript:alert(1)', 'JAVASCRIPT:alert(1)', '\tjavascript:alert(1)', 'data:text/html,<script>alert(1)</script>'];
44
+ const SAFE = ['https://example.com/notice/1', 'http://example.com/notice/1', '/notice/1', 'notice/1'];
45
+ _vitest.describe.each(IMPLEMENTATIONS)('%s — supportTextLink 프로토콜 검사', (_, render, supportingTextSelector) => {
46
+ _vitest.it.each(UNSAFE)('unsafe %j → 링크 없이 텍스트만 렌더한다', url => {
47
+ const container = render(url);
48
+ (0, _vitest.expect)(container.querySelector('a')).toBeNull();
49
+ (0, _vitest.expect)(container.querySelector(supportingTextSelector)?.textContent).toBe('자세히 보기');
50
+ });
51
+ _vitest.it.each(SAFE)('safe %j → 그대로 링크로 렌더한다', url => {
52
+ const container = render(url);
53
+ const anchors = container.querySelectorAll('a');
54
+ (0, _vitest.expect)(anchors).toHaveLength(1);
55
+ (0, _vitest.expect)(anchors[0].getAttribute('href')).toBe(url);
56
+ (0, _vitest.expect)(anchors[0].querySelector(supportingTextSelector)?.textContent).toBe('자세히 보기');
57
+ });
58
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getLinkTargetAttributes = getLinkTargetAttributes;
7
+ /**
8
+ * 텍스트 링크(`supportTextLink`)의 `<a>`에 붙일 target·rel 속성.
9
+ *
10
+ * `'_blank'`일 때만 새 탭 + `rel="noopener noreferrer"`를 반환하고, `'_self'`(기본)는 아무 속성도 붙이지 않는다.
11
+ * Vanilla `applySupportTextLinkTarget`과 같은 마크업을 산출해야 한다.
12
+ */
13
+ function getLinkTargetAttributes(target) {
14
+ return target === '_blank' ? {
15
+ target: '_blank',
16
+ rel: 'noopener noreferrer'
17
+ } : undefined;
18
+ }