@ncds/ui-admin 1.4.1 → 1.5.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 (74) hide show
  1. package/dist/cjs/assets/scripts/comboBox.js +18 -0
  2. package/dist/cjs/assets/scripts/datePicker.js +60 -7
  3. package/dist/cjs/assets/scripts/imageFileInput/ImageFileInputModel.js +6 -19
  4. package/dist/cjs/assets/scripts/notification/MessageNotification.js +146 -0
  5. package/dist/cjs/assets/scripts/notification/Notification.js +6 -3
  6. package/dist/cjs/assets/scripts/notification/const/classNames.js +14 -0
  7. package/dist/cjs/assets/scripts/notification/const/index.js +14 -1
  8. package/dist/cjs/assets/scripts/notification/const/sizes.js +7 -1
  9. package/dist/cjs/assets/scripts/notification/const/types.js +10 -1
  10. package/dist/cjs/assets/scripts/notification/index.js +8 -0
  11. package/dist/cjs/assets/scripts/notification/utils.js +3 -3
  12. package/dist/cjs/assets/scripts/utils/selectbox/DropdownModel.js +7 -0
  13. package/dist/cjs/assets/scripts/utils/selectbox/UnifiedSelectBox.js +77 -43
  14. package/dist/cjs/src/components/button/ButtonStepper.js +22 -0
  15. package/dist/cjs/src/components/button/index.js +22 -0
  16. package/dist/cjs/src/components/date-picker/DatePicker.js +45 -6
  17. package/dist/cjs/src/components/date-picker/RangeDatePicker.js +3 -1
  18. package/dist/cjs/src/components/date-picker/RangeDatePickerWithButtons.js +7 -3
  19. package/dist/cjs/src/components/input/InputBase.js +1 -1
  20. package/dist/cjs/src/components/input/NumberInput.js +130 -0
  21. package/dist/cjs/src/components/input/index.js +11 -0
  22. package/dist/cjs/src/components/notification/MessageNotification.js +137 -0
  23. package/dist/cjs/src/components/notification/Notification.js +23 -9
  24. package/dist/cjs/src/components/notification/index.js +11 -0
  25. package/dist/cjs/src/components/tooltip/Tooltip.js +32 -21
  26. package/dist/esm/assets/scripts/comboBox.js +18 -0
  27. package/dist/esm/assets/scripts/datePicker.js +60 -7
  28. package/dist/esm/assets/scripts/imageFileInput/ImageFileInputModel.js +6 -19
  29. package/dist/esm/assets/scripts/notification/MessageNotification.js +141 -0
  30. package/dist/esm/assets/scripts/notification/Notification.js +6 -3
  31. package/dist/esm/assets/scripts/notification/const/classNames.js +14 -0
  32. package/dist/esm/assets/scripts/notification/const/index.js +2 -1
  33. package/dist/esm/assets/scripts/notification/const/sizes.js +6 -0
  34. package/dist/esm/assets/scripts/notification/const/types.js +8 -1
  35. package/dist/esm/assets/scripts/notification/index.js +1 -0
  36. package/dist/esm/assets/scripts/notification/utils.js +3 -3
  37. package/dist/esm/assets/scripts/utils/selectbox/DropdownModel.js +7 -0
  38. package/dist/esm/assets/scripts/utils/selectbox/UnifiedSelectBox.js +77 -43
  39. package/dist/esm/src/components/button/ButtonStepper.js +14 -0
  40. package/dist/esm/src/components/button/index.js +3 -1
  41. package/dist/esm/src/components/date-picker/DatePicker.js +46 -7
  42. package/dist/esm/src/components/date-picker/RangeDatePicker.js +3 -1
  43. package/dist/esm/src/components/date-picker/RangeDatePickerWithButtons.js +7 -3
  44. package/dist/esm/src/components/input/InputBase.js +1 -1
  45. package/dist/esm/src/components/input/NumberInput.js +124 -0
  46. package/dist/esm/src/components/input/index.js +1 -0
  47. package/dist/esm/src/components/notification/MessageNotification.js +130 -0
  48. package/dist/esm/src/components/notification/Notification.js +23 -9
  49. package/dist/esm/src/components/notification/index.js +2 -1
  50. package/dist/esm/src/components/tooltip/Tooltip.js +33 -22
  51. package/dist/types/assets/scripts/comboBox.d.ts +12 -0
  52. package/dist/types/assets/scripts/datePicker.d.ts +1 -0
  53. package/dist/types/assets/scripts/notification/MessageNotification.d.ts +23 -0
  54. package/dist/types/assets/scripts/notification/Notification.d.ts +1 -1
  55. package/dist/types/assets/scripts/notification/const/classNames.d.ts +14 -0
  56. package/dist/types/assets/scripts/notification/const/index.d.ts +2 -1
  57. package/dist/types/assets/scripts/notification/const/sizes.d.ts +5 -0
  58. package/dist/types/assets/scripts/notification/const/types.d.ts +1 -0
  59. package/dist/types/assets/scripts/notification/index.d.ts +1 -0
  60. package/dist/types/assets/scripts/utils/selectbox/DropdownModel.d.ts +4 -0
  61. package/dist/types/assets/scripts/utils/selectbox/UnifiedSelectBox.d.ts +20 -1
  62. package/dist/types/src/components/button/ButtonStepper.d.ts +10 -0
  63. package/dist/types/src/components/button/index.d.ts +2 -0
  64. package/dist/types/src/components/date-picker/DatePicker.d.ts +1 -0
  65. package/dist/types/src/components/date-picker/RangeDatePickerWithButtons.d.ts +4 -4
  66. package/dist/types/src/components/input/NumberInput.d.ts +10 -0
  67. package/dist/types/src/components/input/index.d.ts +1 -0
  68. package/dist/types/src/components/notification/MessageNotification.d.ts +40 -0
  69. package/dist/types/src/components/notification/Notification.d.ts +6 -1
  70. package/dist/types/src/components/notification/index.d.ts +1 -0
  71. package/dist/types/src/components/selectbox/SelectBox.d.ts +1 -1
  72. package/dist/types/src/components/tooltip/Tooltip.d.ts +4 -2
  73. package/dist/ui-admin/assets/styles/style.css +292 -10
  74. package/package.json +1 -1
@@ -258,5 +258,23 @@ var ComboBox = exports.ComboBox = /** @class */function () {
258
258
  ComboBox.prototype.toggleSelectAll = function () {
259
259
  this.unifiedSelectBox.toggleSelectAll();
260
260
  };
261
+ /**
262
+ * 드롭다운을 스크롤의 바닥으로 이동
263
+ */
264
+ ComboBox.prototype.scrollToBottom = function () {
265
+ this.unifiedSelectBox.scrollToBottom();
266
+ };
267
+ /**
268
+ * 전체 선택 버튼의 텍스트를 외부에서 변경
269
+ */
270
+ ComboBox.prototype.setSelectAllButtonText = function (text) {
271
+ this.unifiedSelectBox.setSelectAllButtonText(text);
272
+ };
273
+ /**
274
+ * 특정 인덱스의 옵션으로 포커스 이동
275
+ */
276
+ ComboBox.prototype.setFocusIndex = function (index) {
277
+ this.unifiedSelectBox.setFocusIndex(index);
278
+ };
261
279
  return ComboBox;
262
280
  }();
@@ -252,6 +252,19 @@ var DatePicker = exports.DatePicker = /** @class */function () {
252
252
  if (formattedInput === input) return;
253
253
  target.value = formattedInput;
254
254
  };
255
+ // 외부 클릭 시 시간 입력 강제 blur 처리
256
+ var handleMouseDown = function (e) {
257
+ var flatpickrCalendar = wrapper.querySelector('.flatpickr-calendar.open');
258
+ if (flatpickrCalendar && !flatpickrCalendar.contains(e.target)) {
259
+ var timeInputs = flatpickrCalendar.querySelectorAll('.flatpickr-time input');
260
+ timeInputs.forEach(function (input) {
261
+ if (document.activeElement === input) {
262
+ input.blur();
263
+ }
264
+ });
265
+ }
266
+ };
267
+ document.addEventListener('mousedown', handleMouseDown, true);
255
268
  return (0, _flatpickr.default)(input, __assign(__assign({}, options), {
256
269
  allowInput: (_b = options.allowInput) !== null && _b !== void 0 ? _b : true,
257
270
  appendTo: wrapper,
@@ -278,6 +291,7 @@ var DatePicker = exports.DatePicker = /** @class */function () {
278
291
  input.removeEventListener('input', onInputHandler);
279
292
  input.removeEventListener('input', onHourInputHandler);
280
293
  input.removeEventListener('input', onMinuteInputHandler);
294
+ document.removeEventListener('mousedown', handleMouseDown, true);
281
295
  }
282
296
  }));
283
297
  };
@@ -336,19 +350,58 @@ var DatePicker = exports.DatePicker = /** @class */function () {
336
350
  var startDate = dates[0],
337
351
  endDate = dates[1];
338
352
  var datesToSet = this.datePickerOptions.map(function (option, index) {
339
- var _a;
353
+ var _a, _b;
340
354
  var date = index === 0 ? startDate : endDate;
341
- if (!date) return '';
355
+ if (!date || date === '0000-00-00') return '';
342
356
  var hasTime = (_a = option.options) === null || _a === void 0 ? void 0 : _a.enableTime;
343
- if (!hasTime) return date;
344
- if (date.includes(':')) return date;
345
- var momentDate = (0, _moment.default)(date);
346
- return index === 0 ? momentDate.startOf('day').format(_this.dateFormat) : momentDate.endOf('day').format(_this.dateFormat);
357
+ var flatpickrFormat = ((_b = option.options) === null || _b === void 0 ? void 0 : _b.dateFormat) || (hasTime ? 'Y-m-d H:i' : 'Y-m-d');
358
+ // dateFormat이 설정되어 있지 않을 때만 hasTime에 따라 기본값 설정
359
+ // dateFormat이 설정되어 있으면 그 형식을 그대로 사용 (enableTime과 무관하게)
360
+ var momentFormat = _this.convertFlatpickrFormatToMoment(flatpickrFormat);
361
+ var momentDate;
362
+ if (hasTime && !date.includes(':')) {
363
+ // 시간이 없는 날짜 형식으로 파싱
364
+ momentDate = (0, _moment.default)(date);
365
+ if (!momentDate.isValid()) return '';
366
+ return index === 0 ? momentDate.startOf('day').format(momentFormat) : momentDate.endOf('day').format(momentFormat);
367
+ }
368
+ if (hasTime && date.includes(':')) {
369
+ momentDate = (0, _moment.default)(date);
370
+ if (!momentDate.isValid()) return '';
371
+ return momentDate.format(momentFormat);
372
+ }
373
+ // 시간이 없는 경우 (hasTime이 false이거나 date에 시간이 없는 경우)
374
+ momentDate = (0, _moment.default)(date);
375
+ if (!momentDate.isValid()) {
376
+ momentDate = (0, _moment.default)(date, momentFormat, true);
377
+ }
378
+ // 둘 다 실패하면 다른 일반적인 형식들로 시도
379
+ if (!momentDate.isValid()) {
380
+ momentDate = (0, _moment.default)(date, [momentFormat, 'YYYY-MM-DD', 'YYYY/MM/DD', 'MM/DD/YYYY'], true);
381
+ }
382
+ if (!momentDate.isValid()) return '';
383
+ // dateFormat 형식으로 포맷팅하여 반환 (flatpickr가 표시하는 형식과 일치)
384
+ return momentDate.format(momentFormat);
347
385
  });
348
- var period = (0, _moment.default)(endDate).diff((0, _moment.default)(startDate), 'days');
386
+ var period = datesToSet[0] && datesToSet[1] ? (0, _moment.default)(datesToSet[1]).diff((0, _moment.default)(datesToSet[0]), 'days') : null;
349
387
  this.updateButtonsByPeriod(period);
350
388
  this.setMultipleDates(datesToSet);
351
389
  };
390
+ // flatpickr 형식을 moment 형식으로 변환하는 헬퍼 메서드
391
+ DatePicker.prototype.convertFlatpickrFormatToMoment = function (flatpickrFormat) {
392
+ var map = {
393
+ Y: 'YYYY',
394
+ y: 'YY',
395
+ m: 'MM',
396
+ d: 'DD',
397
+ H: 'HH',
398
+ i: 'mm',
399
+ S: 'ss'
400
+ };
401
+ return flatpickrFormat.replace(/[YymdHiS]/g, function (matched) {
402
+ return map[matched] || matched;
403
+ });
404
+ };
352
405
  DatePicker.prototype.getDates = function () {
353
406
  var _this = this;
354
407
  return this.flatpickrInstances.map(function (instance) {
@@ -180,36 +180,23 @@ var ImageFileInputModel = exports.ImageFileInputModel = /** @class */function ()
180
180
  var validFiles = [];
181
181
  var invalidFiles = [];
182
182
  var currentFiles = this.getFiles();
183
- var _loop_1 = function (file) {
184
- // 중복 체크
185
- if (currentFiles.some(function (f) {
186
- return f.name === file.name && f.size === file.size;
187
- })) {
188
- invalidFiles.push(__assign(__assign({}, file), {
189
- errorType: _types.ImageFileInputErrorType.ALREADY_UPLOADED
190
- }));
191
- return "continue";
192
- }
183
+ for (var _i = 0, fileList_1 = fileList; _i < fileList_1.length; _i++) {
184
+ var file = fileList_1[_i];
193
185
  // 파일 크기 체크
194
- if (this_1.options.maxFileSize && file.size > this_1.options.maxFileSize) {
186
+ if (this.options.maxFileSize && file.size > this.options.maxFileSize) {
195
187
  invalidFiles.push(__assign(__assign({}, file), {
196
188
  errorType: _types.ImageFileInputErrorType.EXCEED_MAX_FILE_SIZE
197
189
  }));
198
- return "continue";
190
+ continue;
199
191
  }
200
192
  // 파일 개수 체크 (maxFileCount가 1이면 교체 가능하므로 체크하지 않음)
201
- if (this_1.options.maxFileCount && this_1.options.maxFileCount !== 1 && currentFiles.length + validFiles.length >= this_1.options.maxFileCount) {
193
+ if (this.options.maxFileCount && this.options.maxFileCount !== 1 && currentFiles.length + validFiles.length >= this.options.maxFileCount) {
202
194
  invalidFiles.push(__assign(__assign({}, file), {
203
195
  errorType: _types.ImageFileInputErrorType.EXCEED_MAX_FILE_COUNT
204
196
  }));
205
- return "continue";
197
+ continue;
206
198
  }
207
199
  validFiles.push(file);
208
- };
209
- var this_1 = this;
210
- for (var _i = 0, fileList_1 = fileList; _i < fileList_1.length; _i++) {
211
- var file = fileList_1[_i];
212
- _loop_1(file);
213
200
  }
214
201
  return {
215
202
  validFiles: validFiles,
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.MessageNotification = void 0;
7
+ var _const = require("./const");
8
+ var _featuredIcon = require("../featuredIcon");
9
+ var _utils = require("./utils");
10
+ var __assign = void 0 && (void 0).__assign || function () {
11
+ __assign = Object.assign || function (t) {
12
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
13
+ s = arguments[i];
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
15
+ }
16
+ return t;
17
+ };
18
+ return __assign.apply(this, arguments);
19
+ };
20
+ var MessageNotification = exports.MessageNotification = /** @class */function () {
21
+ function MessageNotification(options) {
22
+ this.options = __assign({
23
+ color: 'neutral',
24
+ className: '',
25
+ actions: [],
26
+ autoClose: 0,
27
+ supportingText: undefined
28
+ }, options);
29
+ this.element = this.createElement();
30
+ this.bindEvents();
31
+ this.setupAutoClose();
32
+ }
33
+ MessageNotification.prototype.createElement = function () {
34
+ var _a = this.options,
35
+ title = _a.title,
36
+ supportingText = _a.supportingText,
37
+ color = _a.color,
38
+ className = _a.className,
39
+ actions = _a.actions,
40
+ onClose = _a.onClose,
41
+ onHidePermanently = _a.onHidePermanently;
42
+ // message 타입은 neutral, error, warning, success 4가지 색상만 지원
43
+ var actualColor = color;
44
+ if (color === 'info') {
45
+ console.warn('Message notification does not support "info" color. Using "neutral" instead.');
46
+ actualColor = 'neutral';
47
+ }
48
+ var wrapper = (0, _utils.createWrapperElement)(_const.CLASS_NAMES.MESSAGE.BASE, actualColor, className);
49
+ var iconFunction = _const.FLOATING_ICON_MAP[actualColor];
50
+ // FeaturedIcon 생성
51
+ var featuredIconElement = null;
52
+ if (iconFunction) {
53
+ var iconSvg = iconFunction(_const.MESSAGE_SIZES.ICON_PIXEL);
54
+ this.featuredIcon = _featuredIcon.FeaturedIcon.create({
55
+ svgString: iconSvg,
56
+ theme: 'light-circle',
57
+ color: actualColor,
58
+ size: _const.MESSAGE_SIZES.FEATURED_ICON
59
+ });
60
+ featuredIconElement = this.featuredIcon.getElement();
61
+ }
62
+ wrapper.innerHTML = this.buildTemplate({
63
+ title: title,
64
+ supportingText: supportingText,
65
+ actions: actions,
66
+ onClose: onClose,
67
+ onHidePermanently: onHidePermanently
68
+ });
69
+ // FeaturedIcon을 content-wrapper에 추가
70
+ if (featuredIconElement) {
71
+ var contentWrapper = wrapper.querySelector(".".concat(_const.CLASS_NAMES.MESSAGE.CONTENT_WRAPPER));
72
+ if (contentWrapper) {
73
+ contentWrapper.insertBefore(featuredIconElement, contentWrapper.firstChild);
74
+ }
75
+ }
76
+ return wrapper;
77
+ };
78
+ MessageNotification.prototype.buildTemplate = function (params) {
79
+ var title = params.title,
80
+ supportingText = params.supportingText,
81
+ actions = params.actions,
82
+ onClose = params.onClose,
83
+ onHidePermanently = params.onHidePermanently;
84
+ return "\n <div class=\"".concat(_const.CLASS_NAMES.MESSAGE.CONTAINER, "\">\n <div class=\"").concat(_const.CLASS_NAMES.MESSAGE.CONTENT, "\">\n <div class=\"").concat(_const.CLASS_NAMES.MESSAGE.CONTENT_WRAPPER, "\">\n <div class=\"").concat(_const.CLASS_NAMES.MESSAGE.TEXT_CONTAINER, "\">\n <span class=\"").concat(_const.CLASS_NAMES.MESSAGE.TITLE, "\">").concat(title, "</span>\n ").concat((0, _utils.renderSupportingText)(supportingText, _const.CLASS_NAMES.MESSAGE.SUPPORTING_TEXT), "\n </div>\n </div>\n <div class=\"").concat(_const.CLASS_NAMES.MESSAGE.ACTIONS_CONTAINER, "\">\n ").concat(actions && actions.length > 0 ? (0, _utils.renderActions)(actions, _const.CLASS_NAMES.MESSAGE.ACTIONS) : '', "\n </div>\n <div class=\"").concat(_const.CLASS_NAMES.MESSAGE.ACTIONS_CONTAINER, "\">\n ").concat(this.renderHidePermanentlyButton(onHidePermanently), "\n ").concat(this.renderCloseButton(onClose), "\n </div>\n </div>\n </div>\n ");
85
+ };
86
+ MessageNotification.prototype.renderHidePermanentlyButton = function (onHidePermanently) {
87
+ if (!onHidePermanently) return '';
88
+ return "\n <button type=\"button\" class=\"".concat(_const.CLASS_NAMES.COMMON.ACTION_BUTTON, " ").concat(_const.CLASS_NAMES.COMMON.ACTION_BUTTON, "--text ").concat(_const.CLASS_NAMES.MESSAGE.HIDE_LINK, "\" data-hide-permanently=\"true\">\n \uB2E4\uC2DC \uBCF4\uC9C0 \uC54A\uAE30\n </button>\n ");
89
+ };
90
+ MessageNotification.prototype.renderCloseButton = function (onClose) {
91
+ if (!onClose) return '';
92
+ return "\n <button type=\"button\" class=\"".concat(_const.CLASS_NAMES.MESSAGE.CLOSE_BUTTON, "\" aria-label=\"\uC54C\uB9BC \uB2EB\uAE30\">\n ").concat(_const.SVG_ICONS['x-close'](_const.MESSAGE_SIZES.CLOSE_BUTTON).replace('stroke="currentColor"', "stroke=\"#2F2F30\""), "\n </button>\n ");
93
+ };
94
+ MessageNotification.prototype.bindEvents = function () {
95
+ var _this = this;
96
+ (0, _utils.bindNotificationEvents)(this.element, this.options.actions, this.options.onClose, function () {
97
+ return _this.remove();
98
+ });
99
+ // 다시보지 않기 버튼 이벤트 바인딩
100
+ if (this.options.onHidePermanently) {
101
+ var hidePermanentlyButton = this.element.querySelector('[data-hide-permanently="true"]');
102
+ if (hidePermanentlyButton) {
103
+ hidePermanentlyButton.addEventListener('click', function () {
104
+ var _a, _b;
105
+ (_b = (_a = _this.options).onHidePermanently) === null || _b === void 0 ? void 0 : _b.call(_a);
106
+ _this.remove();
107
+ });
108
+ }
109
+ }
110
+ };
111
+ MessageNotification.prototype.setupAutoClose = function () {
112
+ var _this = this;
113
+ this.autoCloseTimer = (0, _utils.setupAutoClose)(this.options.autoClose, this.options.onClose, function () {
114
+ return _this.remove();
115
+ });
116
+ };
117
+ // Public methods
118
+ MessageNotification.prototype.getElement = function () {
119
+ return this.element;
120
+ };
121
+ MessageNotification.prototype.appendTo = function (parent) {
122
+ parent.appendChild(this.element);
123
+ };
124
+ MessageNotification.prototype.remove = function () {
125
+ if (this.autoCloseTimer) {
126
+ clearTimeout(this.autoCloseTimer);
127
+ this.autoCloseTimer = undefined;
128
+ }
129
+ if (this.element && this.element.parentNode) {
130
+ this.element.parentNode.removeChild(this.element);
131
+ }
132
+ };
133
+ MessageNotification.prototype.destroy = function () {
134
+ // FeaturedIcon 정리
135
+ if (this.featuredIcon) {
136
+ this.featuredIcon.destroy();
137
+ this.featuredIcon = undefined;
138
+ }
139
+ this.remove();
140
+ };
141
+ // Static factory methods
142
+ MessageNotification.create = function (options) {
143
+ return new MessageNotification(options);
144
+ };
145
+ return MessageNotification;
146
+ }();
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.Notification = void 0;
7
7
  var _FullWidthNotification = require("./FullWidthNotification");
8
8
  var _FloatingNotification = require("./FloatingNotification");
9
+ var _MessageNotification = require("./MessageNotification");
9
10
  var __assign = void 0 && (void 0).__assign || function () {
10
11
  __assign = Object.assign || function (t) {
11
12
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -30,10 +31,12 @@ var Notification = exports.Notification = /** @class */function () {
30
31
  var _a = options.type,
31
32
  type = _a === void 0 ? 'floating' : _a,
32
33
  baseOptions = __rest(options, ["type"]);
33
- if (type === 'floating') {
34
- this.instance = new _FloatingNotification.FloatingNotification(baseOptions);
35
- } else {
34
+ if (type === 'message') {
35
+ this.instance = new _MessageNotification.MessageNotification(baseOptions);
36
+ } else if (type === 'full-width') {
36
37
  this.instance = new _FullWidthNotification.FullWidthNotification(baseOptions);
38
+ } else {
39
+ this.instance = new _FloatingNotification.FloatingNotification(baseOptions);
37
40
  }
38
41
  }
39
42
  // 모든 메서드를 instance에 위임
@@ -30,6 +30,20 @@ var CLASS_NAMES = exports.CLASS_NAMES = {
30
30
  ACTIONS: 'ncua-floating-notification__actions',
31
31
  CLOSE_BUTTON: 'ncua-floating-notification__close-button'
32
32
  },
33
+ MESSAGE: {
34
+ BASE: 'ncua-message-notification',
35
+ CONTAINER: 'ncua-message-notification__container',
36
+ CONTENT: 'ncua-message-notification__content',
37
+ CONTENT_WRAPPER: 'ncua-message-notification__content-wrapper',
38
+ ICON: 'ncua-message-notification__icon',
39
+ TEXT_CONTAINER: 'ncua-message-notification__text-container',
40
+ TITLE: 'ncua-message-notification__title',
41
+ SUPPORTING_TEXT: 'ncua-message-notification__supporting-text',
42
+ ACTIONS_CONTAINER: 'ncua-message-notification__actions-container',
43
+ ACTIONS: 'ncua-message-notification__actions',
44
+ HIDE_LINK: 'ncua-message-notification__hide-link',
45
+ CLOSE_BUTTON: 'ncua-message-notification__close-button'
46
+ },
33
47
  COMMON: {
34
48
  ACTION_BUTTON: 'ncua-notification__action-button'
35
49
  }
@@ -57,6 +57,18 @@ Object.defineProperty(exports, "ICON_PIXEL_SIZES", {
57
57
  return _sizes.ICON_PIXEL_SIZES;
58
58
  }
59
59
  });
60
+ Object.defineProperty(exports, "MESSAGE_CLOSE_ICON_COLORS", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _types.MESSAGE_CLOSE_ICON_COLORS;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "MESSAGE_SIZES", {
67
+ enumerable: true,
68
+ get: function () {
69
+ return _sizes.MESSAGE_SIZES;
70
+ }
71
+ });
60
72
  Object.defineProperty(exports, "SVG_ICONS", {
61
73
  enumerable: true,
62
74
  get: function () {
@@ -71,4 +83,5 @@ Object.defineProperty(exports, "getSizes", {
71
83
  });
72
84
  var _icons = require("./icons");
73
85
  var _classNames = require("./classNames");
74
- var _sizes = require("./sizes");
86
+ var _sizes = require("./sizes");
87
+ var _types = require("./types");
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSizes = exports.ICON_PIXEL_SIZES = exports.FULL_WIDTH_SIZES = exports.FEATURED_ICON_SIZES = exports.CLOSE_BUTTON_SVG_SIZES = exports.CLOSE_BUTTON_SIZES = void 0;
6
+ exports.getSizes = exports.MESSAGE_SIZES = exports.ICON_PIXEL_SIZES = exports.FULL_WIDTH_SIZES = exports.FEATURED_ICON_SIZES = exports.CLOSE_BUTTON_SVG_SIZES = exports.CLOSE_BUTTON_SIZES = void 0;
7
7
  // 알림 컴포넌트 사이즈 관련 상수들
8
8
  // FeaturedIcon 사이즈
9
9
  var FEATURED_ICON_SIZES = exports.FEATURED_ICON_SIZES = {
@@ -31,6 +31,12 @@ var FULL_WIDTH_SIZES = exports.FULL_WIDTH_SIZES = {
31
31
  ICON: '16',
32
32
  CLOSE_BUTTON: '20'
33
33
  };
34
+ // Message 알림 고정 사이즈
35
+ var MESSAGE_SIZES = exports.MESSAGE_SIZES = {
36
+ FEATURED_ICON: 'lg',
37
+ ICON_PIXEL: '24',
38
+ CLOSE_BUTTON: '20'
39
+ };
34
40
  // 사이즈 유틸리티 함수들
35
41
  var getSizes = exports.getSizes = {
36
42
  featuredIcon: function (isMobile) {
@@ -2,4 +2,13 @@
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
- });
5
+ });
6
+ exports.MESSAGE_CLOSE_ICON_COLORS = void 0;
7
+ // Message Notification 닫기 버튼 아이콘 색상 맵
8
+ var MESSAGE_CLOSE_ICON_COLORS = exports.MESSAGE_CLOSE_ICON_COLORS = {
9
+ neutral: '#6B7280',
10
+ error: '#EF4444',
11
+ warning: '#F97316',
12
+ success: '#16A34A',
13
+ info: '#6B7280' // info는 message 타입에서 지원하지 않지만 fallback용
14
+ };
@@ -7,6 +7,7 @@ var _exportNames = {
7
7
  Notification: true,
8
8
  FullWidthNotification: true,
9
9
  FloatingNotification: true,
10
+ MessageNotification: true,
10
11
  SVG_ICONS: true,
11
12
  CLASS_NAMES: true,
12
13
  ICON_MAP: true,
@@ -49,6 +50,12 @@ Object.defineProperty(exports, "ICON_MAP", {
49
50
  return _const.ICON_MAP;
50
51
  }
51
52
  });
53
+ Object.defineProperty(exports, "MessageNotification", {
54
+ enumerable: true,
55
+ get: function () {
56
+ return _MessageNotification.MessageNotification;
57
+ }
58
+ });
52
59
  Object.defineProperty(exports, "Notification", {
53
60
  enumerable: true,
54
61
  get: function () {
@@ -64,6 +71,7 @@ Object.defineProperty(exports, "SVG_ICONS", {
64
71
  var _Notification = require("./Notification");
65
72
  var _FullWidthNotification = require("./FullWidthNotification");
66
73
  var _FloatingNotification = require("./FloatingNotification");
74
+ var _MessageNotification = require("./MessageNotification");
67
75
  var _utils = require("./utils");
68
76
  Object.keys(_utils).forEach(function (key) {
69
77
  if (key === "default" || key === "__esModule") return;
@@ -39,7 +39,7 @@ function renderActions(actions, wrapperClass) {
39
39
  return '';
40
40
  }
41
41
  var buttonsHtml = actions.map(function (action) {
42
- var buttonHtml = "\n <button \n class=\"ncua-notification__action-button ncua-notification__action-button--".concat(action.hierarchy || 'link', "\"\n data-action=\"").concat(action.label, "-").concat(action.hierarchy, "\"\n >\n ").concat(action.label, "\n </button>");
42
+ var buttonHtml = "\n <button \n class=\"ncua-btn ncua-btn--sm ncua-btn--".concat(action.hierarchy || 'text', "\"\n data-action=\"").concat(action.label, "-").concat(action.hierarchy, "\"\n >\n ").concat(action.label, "\n </button>");
43
43
  return buttonHtml;
44
44
  }).join('');
45
45
  return "<div class=\"".concat(wrapperClass, "\">").concat(buttonsHtml, "</div>");
@@ -49,13 +49,13 @@ function bindNotificationEvents(element, actions, onClose, onRemove) {
49
49
  element.addEventListener('click', function (event) {
50
50
  var target = event.target;
51
51
  // 닫기 버튼 클릭 처리
52
- if (target.matches(".".concat(_const.CLASS_NAMES.FULL_WIDTH.CLOSE_BUTTON, ", .").concat(_const.CLASS_NAMES.FLOATING.CLOSE_BUTTON)) || target.closest(".".concat(_const.CLASS_NAMES.FULL_WIDTH.CLOSE_BUTTON, ", .").concat(_const.CLASS_NAMES.FLOATING.CLOSE_BUTTON))) {
52
+ if (target.matches(".".concat(_const.CLASS_NAMES.FULL_WIDTH.CLOSE_BUTTON, ", .").concat(_const.CLASS_NAMES.FLOATING.CLOSE_BUTTON)) || target.closest(".".concat(_const.CLASS_NAMES.FULL_WIDTH.CLOSE_BUTTON, ", .").concat(_const.CLASS_NAMES.FLOATING.CLOSE_BUTTON)) || target.closest(".".concat(_const.CLASS_NAMES.MESSAGE.CLOSE_BUTTON))) {
53
53
  onClose === null || onClose === void 0 ? void 0 : onClose();
54
54
  onRemove === null || onRemove === void 0 ? void 0 : onRemove();
55
55
  return;
56
56
  }
57
57
  // 액션 버튼 클릭 처리
58
- var actionButton = target.closest('.ncua-notification__action-button[data-action]');
58
+ var actionButton = target.closest('.ncua-btn[data-action]');
59
59
  if (actionButton && actions) {
60
60
  var actionData = actionButton.getAttribute('data-action');
61
61
  if (actionData) {
@@ -290,6 +290,13 @@ var DropdownModel = exports.DropdownModel = /** @class */function () {
290
290
  this.updateFilteredOptions();
291
291
  this.notifyListeners(['searchValue', 'filteredOptions', 'showAllItems']);
292
292
  };
293
+ /**
294
+ * 검색어만 업데이트 (필터링 없이, API 모드용)
295
+ */
296
+ DropdownModel.prototype.updateSearchValue = function (searchValue) {
297
+ this.state.searchValue = searchValue;
298
+ this.notifyListeners(['searchValue']);
299
+ };
293
300
  /**
294
301
  * 드롭다운이 열릴 수 있는지 확인 (ComboBox용)
295
302
  */
@@ -342,30 +342,27 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
342
342
  };
343
343
  this.controller = new _SelectBoxController.SelectBoxController(controllerConfig);
344
344
  };
345
- // 이벤트 핸들러들
346
- UnifiedSelectBox.prototype.handleInput = function (value) {
347
- var _this = this;
348
- var _a, _b;
349
- // 기존 디바운스 타이머 제거
345
+ /**
346
+ * 디바운싱 타이머 취소
347
+ */
348
+ UnifiedSelectBox.prototype.cancelDebounceTimer = function () {
350
349
  if (this.searchDebounceTimer) {
351
350
  clearTimeout(this.searchDebounceTimer);
352
351
  this.searchDebounceTimer = undefined;
352
+ this.currentDebounceTimerId = undefined;
353
353
  }
354
+ };
355
+ // 이벤트 핸들러들
356
+ UnifiedSelectBox.prototype.handleInput = function (value) {
357
+ var _this = this;
358
+ var _a, _b;
359
+ this.cancelDebounceTimer();
354
360
  // 필터링은 즉시 업데이트 (사용자가 입력하는 동안 필터링 결과를 즉시 보여줌)
355
361
  // 하지만 onSearch 콜백은 디바운싱 적용
356
362
  var isApiMode = this.config.type === 'combobox' && !this.hasInitialOptions;
357
- if (isApiMode) {
358
- // 텍스트가 변경되었거나 비워졌으면 즉시 옵션 완전히 제거
359
- if (this.lastSearchValue !== value) {
360
- if (!value.trim()) {
361
- // 검색어가 비워졌으면 옵션 완전히 비우기
362
- this.model.updateOptions([]);
363
- } else {
364
- // 검색어가 변경되었으면 이전 옵션 즉시 제거
365
- this.model.updateOptions([]);
366
- }
367
- this.lastSearchValue = value;
368
- }
363
+ // API 모드에서는 검색어 변경 추적만 하고, 옵션은 디바운싱 후 비우기
364
+ if (isApiMode && this.lastSearchValue !== value) {
365
+ this.lastSearchValue = value;
369
366
  }
370
367
  // 디바운싱이 설정되어 있으면 입력이 멈춘 후 onSearch 콜백만 실행
371
368
  if (this.config.searchDebounceMs > 0) {
@@ -373,26 +370,40 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
373
370
  var timerId_1 = Date.now() + Math.random();
374
371
  this.currentDebounceTimerId = timerId_1;
375
372
  this.searchDebounceTimer = window.setTimeout(function () {
376
- var _a, _b;
377
- // 타이머가 취소되었는지 확인 (다른 타이머가 시작되었으면 현재 타이머는 무시)
378
- if (_this.currentDebounceTimerId !== timerId_1) {
379
- return; // 이 타이머는 취소되었으므로 실행하지 않음
380
- }
381
- // 타이머가 여전히 유효하면 실행
382
- _this.searchDebounceTimer = undefined;
383
- _this.currentDebounceTimerId = undefined;
384
- // API 모드인 경우 필터링 업데이트 (디바운싱 후 실행)
385
- if (isApiMode) {
386
- _this.model.updateSearchAndFilter(value);
387
- }
388
- // 텍스트가 있을 때만 드롭다운 열기
389
- if (value.trim()) {
390
- _this.controller.open();
391
- } else if (!_this.model.getState().showAllItems) {
392
- _this.controller.close();
393
- }
394
- // onSearch 콜백 호출 (디바운싱 적용, 최종 타이머만 실행)
395
- (_b = (_a = _this.config).onSearch) === null || _b === void 0 ? void 0 : _b.call(_a, value);
373
+ return __awaiter(_this, void 0, void 0, function () {
374
+ var _a, _b;
375
+ return __generator(this, function (_c) {
376
+ switch (_c.label) {
377
+ case 0:
378
+ // 타이머가 취소되었는지 확인 (다른 타이머가 시작되었으면 현재 타이머는 무시)
379
+ if (this.currentDebounceTimerId !== timerId_1) {
380
+ return [2 /*return*/]; // 이 타이머는 취소되었으므로 실행하지 않음
381
+ }
382
+ // 타이머가 여전히 유효하면 실행
383
+ this.searchDebounceTimer = undefined;
384
+ this.currentDebounceTimerId = undefined;
385
+ // API 모드: 검색어만 업데이트 (필터링은 하지 않음, 서버에서 필터링된 결과를 받음)
386
+ // 일반 모드: 검색어 업데이트 + 로컬 필터링
387
+ if (isApiMode) {
388
+ this.model.updateSearchValue(value);
389
+ } else {
390
+ this.model.updateSearchAndFilter(value);
391
+ }
392
+ // onSearch 콜백 호출 완료 대기 (디바운싱 적용, 최종 타이머만 실행)
393
+ return [4 /*yield*/, (_b = (_a = this.config).onSearch) === null || _b === void 0 ? void 0 : _b.call(_a, value)];
394
+ case 1:
395
+ // onSearch 콜백 호출 및 완료 대기 (디바운싱 적용, 최종 타이머만 실행)
396
+ _c.sent();
397
+ // 텍스트가 있을 때만 드롭다운 열기
398
+ if (value.trim()) {
399
+ this.controller.open();
400
+ } else if (!this.model.getState().showAllItems) {
401
+ this.controller.close();
402
+ }
403
+ return [2 /*return*/];
404
+ }
405
+ });
406
+ });
396
407
  }, this.config.searchDebounceMs);
397
408
  } else {
398
409
  // 디바운싱이 0으로 명시적으로 설정되었으면 즉시 실행
@@ -421,6 +432,7 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
421
432
  }
422
433
  };
423
434
  UnifiedSelectBox.prototype.handleClearInput = function () {
435
+ this.cancelDebounceTimer();
424
436
  // input 필드 텍스트 지우기
425
437
  if (this.inputField) {
426
438
  this.inputField.setValue('');
@@ -465,6 +477,7 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
465
477
  };
466
478
  UnifiedSelectBox.prototype.handleSelectionChange = function (selectedValues) {
467
479
  var _a, _b;
480
+ this.cancelDebounceTimer();
468
481
  var result = this.config.multiple ? selectedValues : selectedValues[0] || '';
469
482
  (_b = (_a = this.config).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, result);
470
483
  // UI 업데이트
@@ -622,12 +635,7 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
622
635
  }
623
636
  };
624
637
  UnifiedSelectBox.prototype.destroy = function () {
625
- // 디바운스 타이머 정리
626
- if (this.searchDebounceTimer) {
627
- clearTimeout(this.searchDebounceTimer);
628
- this.searchDebounceTimer = undefined;
629
- }
630
- this.currentDebounceTimerId = undefined;
638
+ this.cancelDebounceTimer();
631
639
  this.controller.destroy();
632
640
  this.renderer.clearCache();
633
641
  this.inputField = undefined;
@@ -673,5 +681,31 @@ var UnifiedSelectBox = exports.UnifiedSelectBox = /** @class */function () {
673
681
  isOpen: this.model.getState().isOpen
674
682
  };
675
683
  };
684
+ /**
685
+ * 드롭다운을 스크롤의 바닥으로 이동
686
+ * 전체 선택 시 추가 데이터 로드를 트리거하기 위해 사용
687
+ */
688
+ UnifiedSelectBox.prototype.scrollToBottom = function () {
689
+ if (!this.dropdownElement) return;
690
+ var optionsList = this.dropdownElement.querySelector('.ncua-select-dropdown__options');
691
+ if (!optionsList) return;
692
+ // 스크롤을 바닥으로 이동
693
+ optionsList.scrollTop = optionsList.scrollHeight;
694
+ };
695
+ /**
696
+ * 전체 선택 버튼의 텍스트를 외부에서 변경
697
+ * @param text 버튼에 표시할 텍스트
698
+ */
699
+ UnifiedSelectBox.prototype.setSelectAllButtonText = function (text) {
700
+ if (!this.config.multiple || !this.footerElement) return;
701
+ this.renderer.updateSelectAllButtonText(this.footerElement, text);
702
+ };
703
+ /**
704
+ * 특정 인덱스의 옵션으로 포커스 이동
705
+ * @param index 포커스를 이동할 옵션의 인덱스
706
+ */
707
+ UnifiedSelectBox.prototype.setFocusIndex = function (index) {
708
+ this.controller.setFocus(index);
709
+ };
676
710
  return UnifiedSelectBox;
677
711
  }();