@ncds/ui-admin 1.4.1 → 1.5.1

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 (82) 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/ButtonGroup.js +1 -2
  15. package/dist/cjs/src/components/button/ButtonStepper.js +23 -0
  16. package/dist/cjs/src/components/button/index.js +22 -0
  17. package/dist/cjs/src/components/date-picker/DatePicker.js +45 -6
  18. package/dist/cjs/src/components/date-picker/RangeDatePicker.js +3 -1
  19. package/dist/cjs/src/components/date-picker/RangeDatePickerWithButtons.js +7 -3
  20. package/dist/cjs/src/components/index.js +11 -0
  21. package/dist/cjs/src/components/input/InputBase.js +1 -1
  22. package/dist/cjs/src/components/input/NumberInput.js +130 -0
  23. package/dist/cjs/src/components/input/PasswordInput.js +3 -2
  24. package/dist/cjs/src/components/input/index.js +11 -0
  25. package/dist/cjs/src/components/notification/MessageNotification.js +137 -0
  26. package/dist/cjs/src/components/notification/Notification.js +23 -9
  27. package/dist/cjs/src/components/notification/index.js +11 -0
  28. package/dist/cjs/src/components/tooltip/Tooltip.js +32 -21
  29. package/dist/esm/assets/scripts/comboBox.js +18 -0
  30. package/dist/esm/assets/scripts/datePicker.js +60 -7
  31. package/dist/esm/assets/scripts/imageFileInput/ImageFileInputModel.js +6 -19
  32. package/dist/esm/assets/scripts/notification/MessageNotification.js +141 -0
  33. package/dist/esm/assets/scripts/notification/Notification.js +6 -3
  34. package/dist/esm/assets/scripts/notification/const/classNames.js +14 -0
  35. package/dist/esm/assets/scripts/notification/const/index.js +2 -1
  36. package/dist/esm/assets/scripts/notification/const/sizes.js +6 -0
  37. package/dist/esm/assets/scripts/notification/const/types.js +8 -1
  38. package/dist/esm/assets/scripts/notification/index.js +1 -0
  39. package/dist/esm/assets/scripts/notification/utils.js +3 -3
  40. package/dist/esm/assets/scripts/utils/selectbox/DropdownModel.js +7 -0
  41. package/dist/esm/assets/scripts/utils/selectbox/UnifiedSelectBox.js +77 -43
  42. package/dist/esm/src/components/button/ButtonStepper.js +15 -0
  43. package/dist/esm/src/components/button/index.js +3 -1
  44. package/dist/esm/src/components/date-picker/DatePicker.js +46 -7
  45. package/dist/esm/src/components/date-picker/RangeDatePicker.js +3 -1
  46. package/dist/esm/src/components/date-picker/RangeDatePickerWithButtons.js +7 -3
  47. package/dist/esm/src/components/index.js +2 -1
  48. package/dist/esm/src/components/input/InputBase.js +1 -1
  49. package/dist/esm/src/components/input/NumberInput.js +124 -0
  50. package/dist/esm/src/components/input/PasswordInput.js +4 -3
  51. package/dist/esm/src/components/input/index.js +1 -0
  52. package/dist/esm/src/components/notification/MessageNotification.js +130 -0
  53. package/dist/esm/src/components/notification/Notification.js +23 -9
  54. package/dist/esm/src/components/notification/index.js +2 -1
  55. package/dist/esm/src/components/tooltip/Tooltip.js +33 -22
  56. package/dist/types/assets/scripts/comboBox.d.ts +12 -0
  57. package/dist/types/assets/scripts/datePicker.d.ts +1 -0
  58. package/dist/types/assets/scripts/notification/MessageNotification.d.ts +23 -0
  59. package/dist/types/assets/scripts/notification/Notification.d.ts +1 -1
  60. package/dist/types/assets/scripts/notification/const/classNames.d.ts +14 -0
  61. package/dist/types/assets/scripts/notification/const/index.d.ts +2 -1
  62. package/dist/types/assets/scripts/notification/const/sizes.d.ts +5 -0
  63. package/dist/types/assets/scripts/notification/const/types.d.ts +1 -0
  64. package/dist/types/assets/scripts/notification/index.d.ts +1 -0
  65. package/dist/types/assets/scripts/utils/selectbox/DropdownModel.d.ts +4 -0
  66. package/dist/types/assets/scripts/utils/selectbox/UnifiedSelectBox.d.ts +20 -1
  67. package/dist/types/src/components/button/ButtonGroup.d.ts +1 -3
  68. package/dist/types/src/components/button/ButtonStepper.d.ts +10 -0
  69. package/dist/types/src/components/button/index.d.ts +2 -0
  70. package/dist/types/src/components/date-picker/DatePicker.d.ts +1 -0
  71. package/dist/types/src/components/date-picker/RangeDatePickerWithButtons.d.ts +4 -4
  72. package/dist/types/src/components/index.d.ts +1 -0
  73. package/dist/types/src/components/input/NumberInput.d.ts +10 -0
  74. package/dist/types/src/components/input/index.d.ts +1 -0
  75. package/dist/types/src/components/modal/Modal.d.ts +2 -2
  76. package/dist/types/src/components/notification/MessageNotification.d.ts +40 -0
  77. package/dist/types/src/components/notification/Notification.d.ts +6 -1
  78. package/dist/types/src/components/notification/index.d.ts +1 -0
  79. package/dist/types/src/components/selectbox/SelectBox.d.ts +1 -1
  80. package/dist/types/src/components/tooltip/Tooltip.d.ts +4 -2
  81. package/dist/ui-admin/assets/styles/style.css +298 -18
  82. package/package.json +1 -1
@@ -336,30 +336,27 @@ var UnifiedSelectBox = /** @class */function () {
336
336
  };
337
337
  this.controller = new SelectBoxController(controllerConfig);
338
338
  };
339
- // 이벤트 핸들러들
340
- UnifiedSelectBox.prototype.handleInput = function (value) {
341
- var _this = this;
342
- var _a, _b;
343
- // 기존 디바운스 타이머 제거
339
+ /**
340
+ * 디바운싱 타이머 취소
341
+ */
342
+ UnifiedSelectBox.prototype.cancelDebounceTimer = function () {
344
343
  if (this.searchDebounceTimer) {
345
344
  clearTimeout(this.searchDebounceTimer);
346
345
  this.searchDebounceTimer = undefined;
346
+ this.currentDebounceTimerId = undefined;
347
347
  }
348
+ };
349
+ // 이벤트 핸들러들
350
+ UnifiedSelectBox.prototype.handleInput = function (value) {
351
+ var _this = this;
352
+ var _a, _b;
353
+ this.cancelDebounceTimer();
348
354
  // 필터링은 즉시 업데이트 (사용자가 입력하는 동안 필터링 결과를 즉시 보여줌)
349
355
  // 하지만 onSearch 콜백은 디바운싱 적용
350
356
  var isApiMode = this.config.type === 'combobox' && !this.hasInitialOptions;
351
- if (isApiMode) {
352
- // 텍스트가 변경되었거나 비워졌으면 즉시 옵션 완전히 제거
353
- if (this.lastSearchValue !== value) {
354
- if (!value.trim()) {
355
- // 검색어가 비워졌으면 옵션 완전히 비우기
356
- this.model.updateOptions([]);
357
- } else {
358
- // 검색어가 변경되었으면 이전 옵션 즉시 제거
359
- this.model.updateOptions([]);
360
- }
361
- this.lastSearchValue = value;
362
- }
357
+ // API 모드에서는 검색어 변경 추적만 하고, 옵션은 디바운싱 후 비우기
358
+ if (isApiMode && this.lastSearchValue !== value) {
359
+ this.lastSearchValue = value;
363
360
  }
364
361
  // 디바운싱이 설정되어 있으면 입력이 멈춘 후 onSearch 콜백만 실행
365
362
  if (this.config.searchDebounceMs > 0) {
@@ -367,26 +364,40 @@ var UnifiedSelectBox = /** @class */function () {
367
364
  var timerId_1 = Date.now() + Math.random();
368
365
  this.currentDebounceTimerId = timerId_1;
369
366
  this.searchDebounceTimer = window.setTimeout(function () {
370
- var _a, _b;
371
- // 타이머가 취소되었는지 확인 (다른 타이머가 시작되었으면 현재 타이머는 무시)
372
- if (_this.currentDebounceTimerId !== timerId_1) {
373
- return; // 이 타이머는 취소되었으므로 실행하지 않음
374
- }
375
- // 타이머가 여전히 유효하면 실행
376
- _this.searchDebounceTimer = undefined;
377
- _this.currentDebounceTimerId = undefined;
378
- // API 모드인 경우 필터링 업데이트 (디바운싱 후 실행)
379
- if (isApiMode) {
380
- _this.model.updateSearchAndFilter(value);
381
- }
382
- // 텍스트가 있을 때만 드롭다운 열기
383
- if (value.trim()) {
384
- _this.controller.open();
385
- } else if (!_this.model.getState().showAllItems) {
386
- _this.controller.close();
387
- }
388
- // onSearch 콜백 호출 (디바운싱 적용, 최종 타이머만 실행)
389
- (_b = (_a = _this.config).onSearch) === null || _b === void 0 ? void 0 : _b.call(_a, value);
367
+ return __awaiter(_this, void 0, void 0, function () {
368
+ var _a, _b;
369
+ return __generator(this, function (_c) {
370
+ switch (_c.label) {
371
+ case 0:
372
+ // 타이머가 취소되었는지 확인 (다른 타이머가 시작되었으면 현재 타이머는 무시)
373
+ if (this.currentDebounceTimerId !== timerId_1) {
374
+ return [2 /*return*/]; // 이 타이머는 취소되었으므로 실행하지 않음
375
+ }
376
+ // 타이머가 여전히 유효하면 실행
377
+ this.searchDebounceTimer = undefined;
378
+ this.currentDebounceTimerId = undefined;
379
+ // API 모드: 검색어만 업데이트 (필터링은 하지 않음, 서버에서 필터링된 결과를 받음)
380
+ // 일반 모드: 검색어 업데이트 + 로컬 필터링
381
+ if (isApiMode) {
382
+ this.model.updateSearchValue(value);
383
+ } else {
384
+ this.model.updateSearchAndFilter(value);
385
+ }
386
+ // onSearch 콜백 호출 완료 대기 (디바운싱 적용, 최종 타이머만 실행)
387
+ return [4 /*yield*/, (_b = (_a = this.config).onSearch) === null || _b === void 0 ? void 0 : _b.call(_a, value)];
388
+ case 1:
389
+ // onSearch 콜백 호출 및 완료 대기 (디바운싱 적용, 최종 타이머만 실행)
390
+ _c.sent();
391
+ // 텍스트가 있을 때만 드롭다운 열기
392
+ if (value.trim()) {
393
+ this.controller.open();
394
+ } else if (!this.model.getState().showAllItems) {
395
+ this.controller.close();
396
+ }
397
+ return [2 /*return*/];
398
+ }
399
+ });
400
+ });
390
401
  }, this.config.searchDebounceMs);
391
402
  } else {
392
403
  // 디바운싱이 0으로 명시적으로 설정되었으면 즉시 실행
@@ -415,6 +426,7 @@ var UnifiedSelectBox = /** @class */function () {
415
426
  }
416
427
  };
417
428
  UnifiedSelectBox.prototype.handleClearInput = function () {
429
+ this.cancelDebounceTimer();
418
430
  // input 필드 텍스트 지우기
419
431
  if (this.inputField) {
420
432
  this.inputField.setValue('');
@@ -459,6 +471,7 @@ var UnifiedSelectBox = /** @class */function () {
459
471
  };
460
472
  UnifiedSelectBox.prototype.handleSelectionChange = function (selectedValues) {
461
473
  var _a, _b;
474
+ this.cancelDebounceTimer();
462
475
  var result = this.config.multiple ? selectedValues : selectedValues[0] || '';
463
476
  (_b = (_a = this.config).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, result);
464
477
  // UI 업데이트
@@ -616,12 +629,7 @@ var UnifiedSelectBox = /** @class */function () {
616
629
  }
617
630
  };
618
631
  UnifiedSelectBox.prototype.destroy = function () {
619
- // 디바운스 타이머 정리
620
- if (this.searchDebounceTimer) {
621
- clearTimeout(this.searchDebounceTimer);
622
- this.searchDebounceTimer = undefined;
623
- }
624
- this.currentDebounceTimerId = undefined;
632
+ this.cancelDebounceTimer();
625
633
  this.controller.destroy();
626
634
  this.renderer.clearCache();
627
635
  this.inputField = undefined;
@@ -667,6 +675,32 @@ var UnifiedSelectBox = /** @class */function () {
667
675
  isOpen: this.model.getState().isOpen
668
676
  };
669
677
  };
678
+ /**
679
+ * 드롭다운을 스크롤의 바닥으로 이동
680
+ * 전체 선택 시 추가 데이터 로드를 트리거하기 위해 사용
681
+ */
682
+ UnifiedSelectBox.prototype.scrollToBottom = function () {
683
+ if (!this.dropdownElement) return;
684
+ var optionsList = this.dropdownElement.querySelector('.ncua-select-dropdown__options');
685
+ if (!optionsList) return;
686
+ // 스크롤을 바닥으로 이동
687
+ optionsList.scrollTop = optionsList.scrollHeight;
688
+ };
689
+ /**
690
+ * 전체 선택 버튼의 텍스트를 외부에서 변경
691
+ * @param text 버튼에 표시할 텍스트
692
+ */
693
+ UnifiedSelectBox.prototype.setSelectAllButtonText = function (text) {
694
+ if (!this.config.multiple || !this.footerElement) return;
695
+ this.renderer.updateSelectAllButtonText(this.footerElement, text);
696
+ };
697
+ /**
698
+ * 특정 인덱스의 옵션으로 포커스 이동
699
+ * @param index 포커스를 이동할 옵션의 인덱스
700
+ */
701
+ UnifiedSelectBox.prototype.setFocusIndex = function (index) {
702
+ this.controller.setFocus(index);
703
+ };
670
704
  return UnifiedSelectBox;
671
705
  }();
672
706
  export { UnifiedSelectBox };
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import classnames from 'classnames';
3
+ export var ButtonStepper = function (_a) {
4
+ var size = _a.size,
5
+ direction = _a.direction,
6
+ disabled = _a.disabled,
7
+ onClick = _a.onClick,
8
+ className = _a.className;
9
+ return _jsx("button", {
10
+ className: classnames('ncua-button-stepper', "ncua-button-stepper--".concat(size), "ncua-button-stepper--".concat(direction), className),
11
+ type: "button",
12
+ disabled: disabled,
13
+ onClick: onClick
14
+ });
15
+ };
@@ -1,2 +1,4 @@
1
1
  export * from './Button';
2
- export * from './ButtonGroup';
2
+ export * from './ButtonCloseX';
3
+ export * from './ButtonGroup';
4
+ export * from './ButtonStepper';
@@ -19,10 +19,11 @@ var __rest = this && this.__rest || function (s, e) {
19
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
20
  import classNames from 'classnames';
21
21
  import { Korean } from 'flatpickr/dist/l10n/ko';
22
- import { forwardRef, useId } from 'react';
22
+ import moment from 'moment';
23
+ import { forwardRef, useId, useMemo } from 'react';
23
24
  import Flatpickr from 'react-flatpickr';
24
- import { CustomInput } from './CustomInput';
25
25
  import { formatDateInput, formatHourInput, formatMinuteInput } from '../../utils/date-picker';
26
+ import { CustomInput } from './CustomInput';
26
27
  var isValidDate = function (dateString) {
27
28
  var date = new Date(dateString);
28
29
  return date instanceof Date && !isNaN(date.getTime());
@@ -35,7 +36,9 @@ export var DatePicker = /*#__PURE__*/forwardRef(function (_a, ref) {
35
36
  size = _c === void 0 ? 'xs' : _c,
36
37
  onChangeDate = _a.onChangeDate,
37
38
  datePickerOptions = _a.datePickerOptions,
38
- attrs = __rest(_a, ["shouldFocus", "currentDate", "size", "onChangeDate", "datePickerOptions"]);
39
+ _d = _a.isEndDate,
40
+ isEndDate = _d === void 0 ? false : _d,
41
+ attrs = __rest(_a, ["shouldFocus", "currentDate", "size", "onChangeDate", "datePickerOptions", "isEndDate"]);
39
42
  var onChangeDateHandler = function (dateTimeStamp, dateStr) {
40
43
  var formattedDate = formatDateInput(dateStr);
41
44
  isValidDate(formattedDate) ? onChangeDate(formattedDate) : onChangeDate(dateStr);
@@ -83,27 +86,63 @@ export var DatePicker = /*#__PURE__*/forwardRef(function (_a, ref) {
83
86
  if (!hourInput || !minuteInput) return;
84
87
  hourInput.addEventListener('input', onHourInputHandler);
85
88
  minuteInput.addEventListener('input', onMinuteInputHandler);
89
+ var handleMouseDown = function (e) {
90
+ var _a;
91
+ var flatpickrCalendar = (_a = input.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector('.flatpickr-calendar.open');
92
+ if (flatpickrCalendar && !flatpickrCalendar.contains(e.target)) {
93
+ var timeInputs = flatpickrCalendar.querySelectorAll('.flatpickr-time input');
94
+ timeInputs.forEach(function (timeInput) {
95
+ if (document.activeElement === timeInput) {
96
+ timeInput.blur();
97
+ }
98
+ });
99
+ }
100
+ };
101
+ document.addEventListener('mousedown', handleMouseDown, true);
102
+ instance._handleMouseDown = handleMouseDown;
86
103
  },
87
104
  onDestroy: function (selectedDates, dateStr, instance) {
88
- var _a, _b;
105
+ var _a;
89
106
  var input = instance.input;
90
107
  if (!input) return;
91
108
  // 메인 input 이벤트 리스너 제거
92
109
  input.removeEventListener('input', onInputHandler);
110
+ var timeInputWrapper = (_a = input.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector('.flatpickr-time');
111
+ if (!timeInputWrapper) return;
93
112
  // 시간 input 이벤트 리스너 제거
94
- var hourInput = (_a = input.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector('.flatpickr-hour');
113
+ var hourInput = timeInputWrapper.querySelector('.flatpickr-hour');
95
114
  if (hourInput) {
96
115
  hourInput.removeEventListener('input', onHourInputHandler);
97
116
  }
98
117
  // 분 input 이벤트 리스너 제거
99
- var minuteInput = (_b = input.parentElement) === null || _b === void 0 ? void 0 : _b.querySelector('.flatpickr-min');
118
+ var minuteInput = timeInputWrapper.querySelector('.flatpickr-minute');
100
119
  if (minuteInput) {
101
120
  minuteInput.removeEventListener('input', onMinuteInputHandler);
102
121
  }
122
+ var handleMouseDown = instance._handleMouseDown;
123
+ if (handleMouseDown) {
124
+ document.removeEventListener('mousedown', handleMouseDown, true);
125
+ }
103
126
  }
104
127
  }, datePickerOptions);
105
128
  var hasTimeOption = datePickerOptions === null || datePickerOptions === void 0 ? void 0 : datePickerOptions.hasOwnProperty('enableTime');
106
129
  var iconName = hasTimeOption && (datePickerOptions === null || datePickerOptions === void 0 ? void 0 : datePickerOptions.hasOwnProperty('noCalendar')) ? 'clock' : 'calendar';
130
+ var processedCurrentDate = useMemo(function () {
131
+ var hasTime = options.enableTime;
132
+ var isTimeOnly = options.noCalendar;
133
+ var hasSeconds = options.enableSeconds;
134
+ if (!hasTime && !isTimeOnly) return currentDate;
135
+ if (currentDate === null || currentDate === void 0 ? void 0 : currentDate.includes(':')) return currentDate;
136
+ if (isTimeOnly) {
137
+ var endTime = hasSeconds ? '23:59:59' : '23:59';
138
+ var startTime = hasSeconds ? '00:00:00' : '00:00';
139
+ return isEndDate ? endTime : startTime;
140
+ }
141
+ if (!currentDate) return '';
142
+ var format = hasSeconds ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm';
143
+ var momentDate = moment(currentDate);
144
+ return isEndDate ? momentDate.endOf('day').format(format) : momentDate.startOf('day').format(format);
145
+ }, [currentDate, isEndDate, options.enableSeconds, options.enableTime, options.noCalendar]);
107
146
  return _jsxs("div", __assign({
108
147
  className: classNames('ncua-date-picker', "ncua-date-picker--".concat(size), {
109
148
  'ncua-date-picker--disabled': attrs.disabled,
@@ -115,7 +154,7 @@ export var DatePicker = /*#__PURE__*/forwardRef(function (_a, ref) {
115
154
  ref: ref || undefined,
116
155
  className: classNames('ncua-date-picker__input'),
117
156
  options: options,
118
- value: currentDate,
157
+ value: processedCurrentDate,
119
158
  render: function (_a, ref) {
120
159
  var defaultValue = _a.defaultValue,
121
160
  value = _a.value,
@@ -127,7 +127,9 @@ export var RangeDatePicker = /*#__PURE__*/forwardRef(function (_a, ref) {
127
127
  children: [_jsx(DatePicker, __assign({}, startDateOptions, {
128
128
  ref: undefined,
129
129
  size: size
130
- })), "~", _jsx(DatePicker, __assign({}, endDateOptions, {
130
+ })), "~", _jsx(DatePicker, __assign({
131
+ isEndDate: true
132
+ }, endDateOptions, {
131
133
  ref: undefined,
132
134
  size: size
133
135
  }))]
@@ -15,8 +15,8 @@ import { getDateFormat, getSubtractDate } from '../../utils/date-picker';
15
15
  import { ButtonGroup } from '../button';
16
16
  import { RangeDatePicker } from './RangeDatePicker';
17
17
  export var RangeDatePickerWithButtons = function (_a) {
18
- var _b = _a.fixedEndDate,
19
- fixedEndDate = _b === void 0 ? getDateFormat() : _b,
18
+ var _b = _a.useYesterdayAsEndDate,
19
+ useYesterdayAsEndDate = _b === void 0 ? false : _b,
20
20
  _c = _a.size,
21
21
  size = _c === void 0 ? 'xs' : _c,
22
22
  currentButtonId = _a.currentButtonId,
@@ -41,7 +41,11 @@ export var RangeDatePickerWithButtons = function (_a) {
41
41
  unit: currentPeriodItem.unit
42
42
  }));
43
43
  startDateOptions.onChangeDate(startDate);
44
- endDateOptions.onChangeDate(fixedEndDate);
44
+ var endDate = useYesterdayAsEndDate ? getDateFormat(getSubtractDate({
45
+ period: 1,
46
+ unit: 'days'
47
+ })) : getDateFormat();
48
+ endDateOptions.onChangeDate(endDate);
45
49
  };
46
50
  var handleOnChangeDate = function (date, type) {
47
51
  type === 'START' ? startDateOptions.onChangeDate(date) : endDateOptions.onChangeDate(date);
@@ -27,4 +27,5 @@ export * from './switch';
27
27
  export * from './tab';
28
28
  export * from './tag';
29
29
  export * from './toggle';
30
- export * from './tooltip';
30
+ export * from './tooltip';
31
+ export * from './image-file-input';
@@ -198,7 +198,7 @@ export var InputBase = /*#__PURE__*/forwardRef(function (_a, ref) {
198
198
  type: "text",
199
199
  disabled: disabled,
200
200
  maxLength: maxLength
201
- }, props)), renderClearButton(), trailingElement && renderInsideSlot(trailingElement, 'right'), renderStatusIcon()]
201
+ }, props)), renderClearButton(), renderStatusIcon(), trailingElement && renderInsideSlot(trailingElement, 'right')]
202
202
  })), trailingElement && renderOutsideSlot(trailingElement)]
203
203
  })), showTextCount && maxLength && _jsxs("div", __assign({
204
204
  className: "ncua-input__field-text-count"
@@ -0,0 +1,124 @@
1
+ var __assign = this && this.__assign || function () {
2
+ __assign = Object.assign || function (t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6
+ }
7
+ return t;
8
+ };
9
+ return __assign.apply(this, arguments);
10
+ };
11
+ var __rest = this && this.__rest || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
15
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
16
+ }
17
+ return t;
18
+ };
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ import { forwardRef, useCallback, useRef } from 'react';
21
+ import { useMergeRefs } from '../../hooks';
22
+ import { ButtonStepper } from '../button';
23
+ import { InputBase } from './InputBase';
24
+ export var NumberInput = /*#__PURE__*/forwardRef(function (_a, ref) {
25
+ var _b = _a.size,
26
+ size = _b === void 0 ? 'xs' : _b,
27
+ minValue = _a.minValue,
28
+ maxValue = _a.maxValue,
29
+ _c = _a.step,
30
+ step = _c === void 0 ? 1 : _c,
31
+ stepperPosition = _a.stepperPosition,
32
+ disabled = _a.disabled,
33
+ props = __rest(_a, ["size", "minValue", "maxValue", "step", "stepperPosition", "disabled"]);
34
+ var inputRef = useRef(null);
35
+ var mergedRef = useMergeRefs([ref, inputRef]);
36
+ var getCurrentValue = useCallback(function () {
37
+ var _a;
38
+ var value = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value;
39
+ return value ? parseFloat(value) : 0;
40
+ }, []);
41
+ var updateValue = useCallback(function (newValue) {
42
+ if (!inputRef.current) return;
43
+ // min/max 범위 체크
44
+ var clampedValue = newValue;
45
+ if (minValue !== undefined && clampedValue < minValue) {
46
+ clampedValue = minValue;
47
+ }
48
+ if (maxValue !== undefined && clampedValue > maxValue) {
49
+ clampedValue = maxValue;
50
+ }
51
+ inputRef.current.value = clampedValue.toString();
52
+ // onChange 이벤트 트리거
53
+ var event = new Event('input', {
54
+ bubbles: true
55
+ });
56
+ inputRef.current.dispatchEvent(event);
57
+ }, [minValue, maxValue]);
58
+ var handleIncrement = useCallback(function () {
59
+ var currentValue = getCurrentValue();
60
+ var newValue = currentValue + step;
61
+ if (maxValue === undefined || newValue <= maxValue) {
62
+ updateValue(newValue);
63
+ }
64
+ }, [getCurrentValue, step, maxValue, updateValue]);
65
+ var handleDecrement = useCallback(function () {
66
+ var currentValue = getCurrentValue();
67
+ var newValue = currentValue - step;
68
+ if (minValue === undefined || newValue >= minValue) {
69
+ updateValue(newValue);
70
+ }
71
+ }, [getCurrentValue, step, minValue, updateValue]);
72
+ var handleKeyDown = useCallback(function (event) {
73
+ var _a;
74
+ if (disabled) return;
75
+ if (event.key === 'ArrowUp') {
76
+ event.preventDefault();
77
+ handleIncrement();
78
+ } else if (event.key === 'ArrowDown') {
79
+ event.preventDefault();
80
+ handleDecrement();
81
+ }
82
+ // 기존 onKeyDown prop이 있으면 호출
83
+ (_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, event);
84
+ }, [disabled, handleIncrement, handleDecrement, props]);
85
+ var renderStepperButtonGroup = function (position) {
86
+ if (position !== stepperPosition) {
87
+ return null;
88
+ }
89
+ return _jsxs("div", __assign({
90
+ className: "ncua-input__stepper-button-group"
91
+ }, {
92
+ children: [_jsx(ButtonStepper, {
93
+ size: size,
94
+ direction: "up",
95
+ onClick: handleIncrement,
96
+ disabled: disabled
97
+ }), _jsx(ButtonStepper, {
98
+ size: size,
99
+ direction: "down",
100
+ onClick: handleDecrement,
101
+ disabled: disabled
102
+ })]
103
+ }));
104
+ };
105
+ return _jsx(InputBase, __assign({
106
+ type: "number",
107
+ leadingElement: renderStepperButtonGroup('leading') ? {
108
+ type: 'custom',
109
+ children: renderStepperButtonGroup('leading')
110
+ } : props.leadingElement,
111
+ trailingElement: renderStepperButtonGroup('trailing') ? {
112
+ type: 'custom',
113
+ children: renderStepperButtonGroup('trailing')
114
+ } : props.trailingElement,
115
+ ref: mergedRef,
116
+ size: size,
117
+ disabled: disabled,
118
+ min: minValue,
119
+ max: maxValue,
120
+ step: step,
121
+ onKeyDown: handleKeyDown,
122
+ className: "ncua-input__number"
123
+ }, props));
124
+ });
@@ -17,11 +17,11 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx } from "react/jsx-runtime";
20
- import { forwardRef, useState } from 'react';
21
- import { InputBase } from './InputBase';
22
20
  import { Eye, EyeOff } from '@ncds/ui-admin-icon';
23
21
  import classNames from 'classnames';
24
- import { useMergeRefs, useCallbackRef } from '../../hooks';
22
+ import { forwardRef, useState } from 'react';
23
+ import { useCallbackRef, useMergeRefs } from '../../hooks';
24
+ import { InputBase } from './InputBase';
25
25
  var svgSize = {
26
26
  xs: 14,
27
27
  sm: 20
@@ -70,6 +70,7 @@ export var PasswordInput = /*#__PURE__*/forwardRef(function (_a, ref) {
70
70
  placement: 'inside',
71
71
  children: _jsx("button", __assign({
72
72
  className: classNames('ncua-input__icon-wrap', 'ncua-input__right-icon', 'ncua-input__password-icon'),
73
+ type: "button",
73
74
  onClick: handleVisibilityChange
74
75
  }, {
75
76
  children: isVisible ? _jsx(Eye, __assign({}, svgProps)) : _jsx(EyeOff, __assign({}, svgProps))
@@ -1,3 +1,4 @@
1
1
  export * from './InputBase';
2
+ export * from './NumberInput';
2
3
  export * from './PasswordInput';
3
4
  export * from './Textarea';
@@ -0,0 +1,130 @@
1
+ var __assign = this && this.__assign || function () {
2
+ __assign = Object.assign || function (t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6
+ }
7
+ return t;
8
+ };
9
+ return __assign.apply(this, arguments);
10
+ };
11
+ var __rest = this && this.__rest || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
15
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
16
+ }
17
+ return t;
18
+ };
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
+ import classNames from 'classnames';
22
+ import { forwardRef } from 'react';
23
+ import { COLOR } from '../../../constant/color';
24
+ import { Button } from '../button';
25
+ import { FeaturedIcon } from '../featured-icon/FeaturedIcon';
26
+ var iconNameMap = {
27
+ neutral: 'pin-02',
28
+ error: 'alert-triangle',
29
+ warning: 'alert-circle',
30
+ success: 'check-circle'
31
+ };
32
+ var iconColorMap = {
33
+ neutral: 'gray700',
34
+ error: 'red500',
35
+ warning: 'orange500',
36
+ success: 'green600'
37
+ };
38
+ export var MessageNotification = /*#__PURE__*/forwardRef(function (_a, ref) {
39
+ var title = _a.title,
40
+ supportingText = _a.supportingText,
41
+ icon = _a.icon,
42
+ _b = _a.color,
43
+ color = _b === void 0 ? 'neutral' : _b,
44
+ onClose = _a.onClose,
45
+ className = _a.className,
46
+ actions = _a.actions,
47
+ onHidePermanently = _a.onHidePermanently,
48
+ rest = __rest(_a, ["title", "supportingText", "icon", "color", "onClose", "className", "actions", "onHidePermanently"]);
49
+ // message 타입은 neutral, error, warning, success 4가지 색상만 지원
50
+ var validColor = color === 'info' ? 'neutral' : color;
51
+ var iconColor = validColor;
52
+ var featuredIconProps = {
53
+ name: icon || iconNameMap[validColor] || 'pin-02',
54
+ size: 'lg',
55
+ color: iconColor,
56
+ theme: 'light-circle'
57
+ };
58
+ var closeIconColor = COLOR[iconColorMap[validColor] || 'gray700'];
59
+ return _jsx("div", __assign({
60
+ ref: ref,
61
+ className: classNames('ncua-message-notification', "ncua-message-notification--".concat(validColor), className),
62
+ role: "alert"
63
+ }, rest, {
64
+ children: _jsx("div", __assign({
65
+ className: "ncua-message-notification__container"
66
+ }, {
67
+ children: _jsxs("div", __assign({
68
+ className: "ncua-message-notification__content"
69
+ }, {
70
+ children: [_jsxs("div", __assign({
71
+ className: "ncua-message-notification__content-wrapper"
72
+ }, {
73
+ children: [iconNameMap[validColor] && _jsx(FeaturedIcon, __assign({}, featuredIconProps, {
74
+ className: "ncua-message-notification__icon"
75
+ })), _jsxs("div", __assign({
76
+ className: "ncua-message-notification__text-container"
77
+ }, {
78
+ children: [_jsx("span", __assign({
79
+ className: "ncua-message-notification__title"
80
+ }, {
81
+ children: title
82
+ })), supportingText && _jsx("span", __assign({
83
+ className: "ncua-message-notification__supporting-text"
84
+ }, {
85
+ children: supportingText
86
+ }))]
87
+ }))]
88
+ })), _jsx("div", __assign({
89
+ className: "ncua-message-notification__actions-container"
90
+ }, {
91
+ children: actions && _jsx("div", __assign({
92
+ className: "ncua-message-notification__actions"
93
+ }, {
94
+ children: actions.map(function (action) {
95
+ return _jsx(Button, {
96
+ size: "xs",
97
+ hierarchy: action.hierarchy || 'text',
98
+ label: action.label,
99
+ onClick: action === null || action === void 0 ? void 0 : action.onClick
100
+ }, "".concat(action.label, "-").concat(action.hierarchy));
101
+ })
102
+ }))
103
+ })), _jsxs("div", __assign({
104
+ className: "ncua-message-notification__footer-container"
105
+ }, {
106
+ children: [onHidePermanently && _jsx("button", __assign({
107
+ type: "button",
108
+ className: classNames('ncua-notification__action-button', 'ncua-notification__action-button--text', 'ncua-message-notification__hide-link'),
109
+ onClick: onHidePermanently
110
+ }, {
111
+ children: "\uB2E4\uC2DC \uBCF4\uC9C0 \uC54A\uAE30"
112
+ })), onClose && _jsx("button", __assign({
113
+ type: "button",
114
+ className: "ncua-message-notification__close-button",
115
+ onClick: onClose,
116
+ "aria-label": "\uC54C\uB9BC \uB2EB\uAE30"
117
+ }, {
118
+ children: _jsx(Icon, {
119
+ name: "x-close",
120
+ width: 20,
121
+ height: 20,
122
+ color: closeIconColor
123
+ })
124
+ }))]
125
+ }))]
126
+ }))
127
+ }))
128
+ }));
129
+ });
130
+ MessageNotification.displayName = 'MessageNotification';