@ncds/ui-admin 1.8.14 → 1.8.15

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 (58) hide show
  1. package/dist/cjs/src/components/forms-and-input/checkbox/CheckboxInput.js +3 -2
  2. package/dist/cjs/src/components/forms-and-input/range-date-picker/RangeDatePicker.js +22 -0
  3. package/dist/cjs/src/components/forms-and-input/range-date-picker/__tests__/RangeDatePicker.test.js +95 -0
  4. package/dist/cjs/src/components/forms-and-input/range-date-picker-with-buttons/RangeDatePickerWithButtons.js +7 -1
  5. package/dist/cjs/src/components/forms-and-input/range-date-picker-with-buttons/__tests__/RangeDatePickerWithButtons.test.js +57 -0
  6. package/dist/cjs/src/components/forms-and-input/slider/Slider.js +7 -1
  7. package/dist/cjs/src/components/navigation/pagination/Pagination.js +12 -2
  8. package/dist/cjs/src/components/navigation/pagination/__tests__/Pagination.test.js +62 -0
  9. package/dist/cjs/src/components/overlays/tooltip/Tooltip.js +15 -2
  10. package/dist/cjs/src/components/overlays/tooltip/__tests__/utils.test.js +40 -0
  11. package/dist/cjs/src/components/overlays/tooltip/utils.js +20 -0
  12. package/dist/cjs/src/hooks/index.js +11 -0
  13. package/dist/cjs/src/hooks/useIsomorphicLayoutEffect.js +8 -0
  14. package/dist/cjs/src/hooks/useMediaQuery.js +3 -0
  15. package/dist/esm/src/components/forms-and-input/checkbox/CheckboxInput.js +4 -3
  16. package/dist/esm/src/components/forms-and-input/range-date-picker/RangeDatePicker.js +22 -0
  17. package/dist/esm/src/components/forms-and-input/range-date-picker/__tests__/RangeDatePicker.test.js +92 -0
  18. package/dist/esm/src/components/forms-and-input/range-date-picker-with-buttons/RangeDatePickerWithButtons.js +7 -1
  19. package/dist/esm/src/components/forms-and-input/range-date-picker-with-buttons/__tests__/RangeDatePickerWithButtons.test.js +54 -0
  20. package/dist/esm/src/components/forms-and-input/slider/Slider.js +7 -1
  21. package/dist/esm/src/components/navigation/pagination/Pagination.js +12 -2
  22. package/dist/esm/src/components/navigation/pagination/__tests__/Pagination.test.js +59 -0
  23. package/dist/esm/src/components/overlays/tooltip/Tooltip.js +15 -2
  24. package/dist/esm/src/components/overlays/tooltip/__tests__/utils.test.js +38 -0
  25. package/dist/esm/src/components/overlays/tooltip/utils.js +13 -0
  26. package/dist/esm/src/hooks/index.js +1 -0
  27. package/dist/esm/src/hooks/useIsomorphicLayoutEffect.js +2 -0
  28. package/dist/esm/src/hooks/useMediaQuery.js +3 -0
  29. package/dist/temp/src/components/forms-and-input/checkbox/CheckboxInput.js +4 -3
  30. package/dist/temp/src/components/forms-and-input/range-date-picker/RangeDatePicker.js +22 -0
  31. package/dist/temp/src/components/forms-and-input/range-date-picker/__tests__/RangeDatePicker.test.d.ts +1 -0
  32. package/dist/temp/src/components/forms-and-input/range-date-picker/__tests__/RangeDatePicker.test.js +60 -0
  33. package/dist/temp/src/components/forms-and-input/range-date-picker-with-buttons/RangeDatePickerWithButtons.js +9 -1
  34. package/dist/temp/src/components/forms-and-input/range-date-picker-with-buttons/__tests__/RangeDatePickerWithButtons.test.d.ts +1 -0
  35. package/dist/temp/src/components/forms-and-input/range-date-picker-with-buttons/__tests__/RangeDatePickerWithButtons.test.js +42 -0
  36. package/dist/temp/src/components/forms-and-input/slider/Slider.js +7 -1
  37. package/dist/temp/src/components/navigation/pagination/Pagination.js +12 -2
  38. package/dist/temp/src/components/navigation/pagination/__tests__/Pagination.test.d.ts +1 -0
  39. package/dist/temp/src/components/navigation/pagination/__tests__/Pagination.test.js +59 -0
  40. package/dist/temp/src/components/overlays/tooltip/Tooltip.js +21 -4
  41. package/dist/temp/src/components/overlays/tooltip/__tests__/utils.test.d.ts +1 -0
  42. package/dist/temp/src/components/overlays/tooltip/__tests__/utils.test.js +38 -0
  43. package/dist/temp/src/components/overlays/tooltip/utils.d.ts +9 -0
  44. package/dist/temp/src/components/overlays/tooltip/utils.js +13 -0
  45. package/dist/temp/src/hooks/index.d.ts +1 -0
  46. package/dist/temp/src/hooks/index.js +1 -0
  47. package/dist/temp/src/hooks/useIsomorphicLayoutEffect.d.ts +2 -0
  48. package/dist/temp/src/hooks/useIsomorphicLayoutEffect.js +2 -0
  49. package/dist/temp/src/hooks/useMediaQuery.js +3 -0
  50. package/dist/types/src/components/forms-and-input/range-date-picker/__tests__/RangeDatePicker.test.d.ts +1 -0
  51. package/dist/types/src/components/forms-and-input/range-date-picker-with-buttons/__tests__/RangeDatePickerWithButtons.test.d.ts +1 -0
  52. package/dist/types/src/components/navigation/pagination/__tests__/Pagination.test.d.ts +1 -0
  53. package/dist/types/src/components/overlays/tooltip/__tests__/utils.test.d.ts +1 -0
  54. package/dist/types/src/components/overlays/tooltip/utils.d.ts +9 -0
  55. package/dist/types/src/hooks/index.d.ts +1 -0
  56. package/dist/types/src/hooks/useIsomorphicLayoutEffect.d.ts +2 -0
  57. package/dist/ui-admin/assets/styles/style.css +15 -19
  58. package/package.json +1 -1
@@ -16,6 +16,13 @@ export const Pagination = ({ className = '', totalCount, itemCountPerPage = 10,
16
16
  }
17
17
  };
18
18
  useEffect(() => {
19
+ const lastGroupStart = Math.max(1, Math.floor((totalPage - 1) / pageCount) * pageCount + 1);
20
+ // totalPage/pageCount 가 줄어 start 가 마지막 그룹을 넘으면 마지막 그룹으로 보정한다.
21
+ // (예: 100→50 페이지로 축소 시 start 가 91 에 머물러 범위 밖 버튼을 표시하던 문제)
22
+ if (start > lastGroupStart) {
23
+ setStart(lastGroupStart);
24
+ return;
25
+ }
19
26
  if (currentPage === start + pageCount) {
20
27
  setStart(start + pageCount);
21
28
  }
@@ -30,10 +37,13 @@ export const Pagination = ({ className = '', totalCount, itemCountPerPage = 10,
30
37
  setStart(1);
31
38
  }
32
39
  if (currentPage === totalPage) {
33
- const lastGroupStart = Math.floor((totalPage - 1) / pageCount) * pageCount + 1;
34
40
  setStart(lastGroupStart);
35
41
  }
36
- }, [currentPage]);
42
+ // start 는 이 effect 가 setStart 로 갱신하는 대상이라 deps 에서 제외한다(넣으면 자기 갱신으로
43
+ // 재실행). currentPage 외에 totalPage/pageCount 도 추적해, 이들이 줄어 start 가 범위를 벗어나면
44
+ // 위에서 보정한다.
45
+ // eslint-disable-next-line react-hooks/exhaustive-deps
46
+ }, [currentPage, totalPage, pageCount]);
37
47
  return (_jsxs("div", { className: classNames('ncua-pagination', `ncua-pagination--${breakPoint}`, className), children: [showJumpPageButton && (_jsxs(_Fragment, { children: [NavButton({
38
48
  type: 'first',
39
49
  breakPoint,
@@ -0,0 +1,59 @@
1
+ // @vitest-environment jsdom
2
+ import { createElement } from 'react';
3
+ import { createRoot } from 'react-dom/client';
4
+ import { act } from 'react-dom/test-utils';
5
+ import { afterEach, describe, expect, it } from 'vitest';
6
+ import { Pagination } from '../Pagination';
7
+ const ITEM_COUNT_PER_PAGE = 10;
8
+ const PAGE_GROUP_SIZE = 10;
9
+ const TOTAL_COUNT_100_PAGES = 1000;
10
+ const TOTAL_COUNT_50_PAGES = 500;
11
+ const CURRENT_PAGE = 91; // 100페이지 기준 마지막 그룹(91~100)을 보던 페이지
12
+ const GROUP_START_100_PAGES = 91; // currentPage=91 일 때의 그룹 시작
13
+ const GROUP_START_50_PAGES = 41; // totalPage=50 으로 줄었을 때의 마지막 그룹 시작
14
+ const LAST_PAGE_50 = 50;
15
+ let root = null;
16
+ let container = null;
17
+ function render(props) {
18
+ if (!container) {
19
+ container = document.createElement('div');
20
+ document.body.appendChild(container);
21
+ root = createRoot(container);
22
+ }
23
+ act(() => {
24
+ root?.render(createElement(Pagination, props));
25
+ });
26
+ return container;
27
+ }
28
+ afterEach(() => {
29
+ if (root && container) {
30
+ act(() => root?.unmount());
31
+ container.remove();
32
+ }
33
+ root = null;
34
+ container = null;
35
+ });
36
+ const pageNums = (el) => Array.from(el.querySelectorAll('.ncua-pagination__page-num')).map((b) => Number(b.textContent));
37
+ describe('#332 Pagination — totalPage 축소 시 start 보정', () => {
38
+ it('totalPage 가 줄면 start 를 마지막 그룹으로 보정하고 범위 밖 페이지 버튼을 표시하지 않는다', () => {
39
+ // 1) 100 페이지에서 91 페이지 보는 중 → 91~100 그룹 표시
40
+ const el = render({
41
+ totalCount: TOTAL_COUNT_100_PAGES,
42
+ itemCountPerPage: ITEM_COUNT_PER_PAGE,
43
+ pageCount: PAGE_GROUP_SIZE,
44
+ currentPage: CURRENT_PAGE,
45
+ });
46
+ expect(pageNums(el)[0]).toBe(GROUP_START_100_PAGES);
47
+ // 2) 데이터가 50 페이지로 줄어듦 (currentPage 는 그대로 — 부모가 clamp 안 한 상황)
48
+ render({
49
+ totalCount: TOTAL_COUNT_50_PAGES,
50
+ itemCountPerPage: ITEM_COUNT_PER_PAGE,
51
+ pageCount: PAGE_GROUP_SIZE,
52
+ currentPage: CURRENT_PAGE,
53
+ });
54
+ const nums = pageNums(el);
55
+ // 마지막 그룹(41~50)으로 보정되고, totalPage(50)를 넘는 버튼은 없어야 한다
56
+ expect(nums[0]).toBe(GROUP_START_50_PAGES);
57
+ expect(Math.max(...nums)).toBeLessThanOrEqual(LAST_PAGE_50);
58
+ });
59
+ });
@@ -4,6 +4,7 @@ import classNames from 'classnames';
4
4
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import { ButtonCloseX } from '../../action/button/ButtonCloseX';
7
+ import { calculateArrowOffsetX } from './utils';
7
8
  const ICON_SIZE_SM = 14;
8
9
  const ICON_SIZE_DEFAULT = 16;
9
10
  // HTML 구현체(assets/scripts/tooltip)와 동일한 상수
@@ -72,13 +73,25 @@ const computePanelCoords = (prefer, anchor, panel) => {
72
73
  }
73
74
  left = Math.max(VIEWPORT_MARGIN, Math.min(left, window.innerWidth - panel.width - VIEWPORT_MARGIN));
74
75
  top = Math.max(VIEWPORT_MARGIN, Math.min(top, window.innerHeight - panel.height - VIEWPORT_MARGIN));
75
- return { top: Math.round(top), left: Math.round(left), calculatedPosition };
76
+ // 경계 보정으로 패널이 앵커 중심에서 밀렸을 때도 화살표(::after) 앵커를 가리키도록
77
+ // 패널 내 X 오프셋 계산 (top/bottom 계열만 — SCSS의 --top/--bottom 규칙이 소비)
78
+ let arrowX = null;
79
+ if (calculatedPosition === 'top' || calculatedPosition === 'bottom') {
80
+ arrowX = calculateArrowOffsetX(anchor.left + anchor.width / 2, left, panel.width);
81
+ }
82
+ return { top: Math.round(top), left: Math.round(left), arrowX, calculatedPosition };
76
83
  };
77
84
  const buildPanelStyle = (disablePortal, coords, visible, zIndex) => {
78
85
  const opacity = visible ? 1 : 0;
79
86
  if (disablePortal)
80
87
  return { opacity };
81
- return { top: `${coords.top}px`, left: `${coords.left}px`, opacity, ...(zIndex && { zIndex }) };
88
+ return {
89
+ top: `${coords.top}px`,
90
+ left: `${coords.left}px`,
91
+ opacity,
92
+ ...(coords.arrowX !== null && { '--ncua-tooltip-arrow-x': `${coords.arrowX}px` }),
93
+ ...(zIndex && { zIndex }),
94
+ };
82
95
  };
83
96
  const renderIcon = (iconStyle, iconType, iconSize, iconColor) => {
84
97
  if (iconStyle === 'help-circle') {
@@ -92,7 +105,11 @@ export const Tooltip = ({ tooltipType = 'white', iconType = 'stroke', position =
92
105
  const panelRef = useRef(null);
93
106
  const rafIdRef = useRef(null);
94
107
  const [mounted, setMounted] = useState(false);
95
- const [coords, setCoords] = useState({ top: OFFSCREEN, left: OFFSCREEN });
108
+ const [coords, setCoords] = useState({
109
+ top: OFFSCREEN,
110
+ left: OFFSCREEN,
111
+ arrowX: null,
112
+ });
96
113
  const [calculatedPosition, setCalculatedPosition] = useState(position === 'auto' ? 'bottom' : position);
97
114
  const [isVisible, setIsVisible] = useState(false);
98
115
  const [isManuallyClose, setIsManuallyClose] = useState(false);
@@ -112,7 +129,7 @@ export const Tooltip = ({ tooltipType = 'white', iconType = 'stroke', position =
112
129
  const anchor = anchorRef.current.getBoundingClientRect();
113
130
  const panel = panelRef.current.getBoundingClientRect();
114
131
  const next = computePanelCoords(position, anchor, panel);
115
- setCoords({ top: next.top, left: next.left });
132
+ setCoords({ top: next.top, left: next.left, arrowX: next.arrowX });
116
133
  setCalculatedPosition(next.calculatedPosition);
117
134
  }, [position, disablePortal]);
118
135
  useEffect(() => {
@@ -0,0 +1,38 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ARROW_EDGE_MARGIN, calculateArrowOffsetX } from '../utils';
3
+ // 공통 픽스처 — 너비 300px 패널이 viewport 왼쪽 여백(8px)에 클램핑된 상태를 가정
4
+ const PANEL_WIDTH = 300;
5
+ const CLAMPED_LEFT = 8;
6
+ describe('calculateArrowOffsetX — 화살표가 앵커 중심을 가리키도록 패널 내 X 오프셋 계산', () => {
7
+ it('패널이 클램핑되지 않으면(앵커 중심 = 패널 중심) 패널 너비의 절반을 반환한다', () => {
8
+ const anchorCenterX = 200;
9
+ const centeredPanelLeft = 50;
10
+ const panelHalfWidth = 150;
11
+ expect(calculateArrowOffsetX(anchorCenterX, centeredPanelLeft, PANEL_WIDTH)).toBe(panelHalfWidth);
12
+ });
13
+ it('패널이 오른쪽으로 밀린 경우(왼쪽 경계 클램핑) 화살표는 왼쪽으로 이동해 앵커를 가리킨다', () => {
14
+ const anchorCenterX = 60;
15
+ const expectedOffset = 52; // 60 - 8
16
+ expect(calculateArrowOffsetX(anchorCenterX, CLAMPED_LEFT, PANEL_WIDTH)).toBe(expectedOffset);
17
+ });
18
+ it('패널이 왼쪽으로 밀린 경우(오른쪽 경계 클램핑) 화살표는 오른쪽으로 이동해 앵커를 가리킨다', () => {
19
+ const anchorCenterX = 950;
20
+ const clampedRightPanelLeft = 692;
21
+ const expectedOffset = 258; // 950 - 692
22
+ expect(calculateArrowOffsetX(anchorCenterX, clampedRightPanelLeft, PANEL_WIDTH)).toBe(expectedOffset);
23
+ });
24
+ it('앵커가 패널 왼쪽 모서리보다 바깥이면 최소 여백(모서리 radius + 화살표)으로 클램핑한다', () => {
25
+ const outsideLeftAnchorX = 10;
26
+ expect(calculateArrowOffsetX(outsideLeftAnchorX, CLAMPED_LEFT, PANEL_WIDTH)).toBe(ARROW_EDGE_MARGIN);
27
+ });
28
+ it('앵커가 패널 오른쪽 모서리보다 바깥이면 최대 여백으로 클램핑한다', () => {
29
+ const outsideRightAnchorX = 999;
30
+ expect(calculateArrowOffsetX(outsideRightAnchorX, CLAMPED_LEFT, PANEL_WIDTH)).toBe(PANEL_WIDTH - ARROW_EDGE_MARGIN);
31
+ });
32
+ it('소수 좌표는 반올림한다', () => {
33
+ const fractionalAnchorX = 100.4;
34
+ const panelLeft = 50;
35
+ const expectedRounded = 50; // 100.4 - 50 = 50.4 → 50
36
+ expect(calculateArrowOffsetX(fractionalAnchorX, panelLeft, PANEL_WIDTH)).toBe(expectedRounded);
37
+ });
38
+ });
@@ -0,0 +1,9 @@
1
+ export declare const ARROW_EDGE_MARGIN = 12;
2
+ /**
3
+ * top/bottom 툴팁 화살표(::after)의 패널 내 X 오프셋.
4
+ * 패널이 viewport 경계 보정으로 앵커 중심에서 밀려도 화살표는 앵커를 가리키도록,
5
+ * 클램핑된 패널 left 기준으로 앵커 중심까지의 거리를 계산한다.
6
+ * 앵커가 패널 밖에 있으면 패널 모서리 여백까지만 이동한다.
7
+ * React(Tooltip.tsx)와 HTML 구현체(assets/scripts/tooltip)가 공유한다.
8
+ */
9
+ export declare function calculateArrowOffsetX(anchorCenterX: number, panelLeft: number, panelWidth: number): number;
@@ -0,0 +1,13 @@
1
+ // 화살표가 패널 모서리(border-radius 6px + 화살표 반너비 6px) 안쪽으로 파고들지 않기 위한 최소 여백
2
+ export const ARROW_EDGE_MARGIN = 12;
3
+ /**
4
+ * top/bottom 툴팁 화살표(::after)의 패널 내 X 오프셋.
5
+ * 패널이 viewport 경계 보정으로 앵커 중심에서 밀려도 화살표는 앵커를 가리키도록,
6
+ * 클램핑된 패널 left 기준으로 앵커 중심까지의 거리를 계산한다.
7
+ * 앵커가 패널 밖에 있으면 패널 모서리 여백까지만 이동한다.
8
+ * React(Tooltip.tsx)와 HTML 구현체(assets/scripts/tooltip)가 공유한다.
9
+ */
10
+ export function calculateArrowOffsetX(anchorCenterX, panelLeft, panelWidth) {
11
+ const raw = anchorCenterX - panelLeft;
12
+ return Math.round(Math.max(ARROW_EDGE_MARGIN, Math.min(raw, panelWidth - ARROW_EDGE_MARGIN)));
13
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './dropdown';
2
2
  export * from './useCallbackRef';
3
3
  export * from './useFloatingPosition';
4
+ export * from './useIsomorphicLayoutEffect';
4
5
  export * from './useMediaQuery';
5
6
  export * from './useMergeRefs';
@@ -3,5 +3,6 @@
3
3
  export * from './dropdown';
4
4
  export * from './useCallbackRef';
5
5
  export * from './useFloatingPosition';
6
+ export * from './useIsomorphicLayoutEffect';
6
7
  export * from './useMediaQuery';
7
8
  export * from './useMergeRefs';
@@ -0,0 +1,2 @@
1
+ import { useEffect } from 'react';
2
+ export declare const useIsomorphicLayoutEffect: typeof useEffect;
@@ -0,0 +1,2 @@
1
+ import { useEffect, useLayoutEffect } from 'react';
2
+ export const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
@@ -14,6 +14,9 @@ export const useMediaQuery = (query, options) => {
14
14
  return () => {
15
15
  mediaQuery.removeEventListener('change', handleChange);
16
16
  };
17
+ // options 객체 전체가 아니라 실제 사용하는 onMatched 콜백에만 의존한다. options 를 통째로
18
+ // 넣으면 매 렌더 새 객체로 간주돼 불필요하게 재구독한다.
19
+ // eslint-disable-next-line react-hooks/exhaustive-deps
17
20
  }, [query, options?.onMatched]);
18
21
  return matches;
19
22
  };
@@ -0,0 +1,9 @@
1
+ export declare const ARROW_EDGE_MARGIN = 12;
2
+ /**
3
+ * top/bottom 툴팁 화살표(::after)의 패널 내 X 오프셋.
4
+ * 패널이 viewport 경계 보정으로 앵커 중심에서 밀려도 화살표는 앵커를 가리키도록,
5
+ * 클램핑된 패널 left 기준으로 앵커 중심까지의 거리를 계산한다.
6
+ * 앵커가 패널 밖에 있으면 패널 모서리 여백까지만 이동한다.
7
+ * React(Tooltip.tsx)와 HTML 구현체(assets/scripts/tooltip)가 공유한다.
8
+ */
9
+ export declare function calculateArrowOffsetX(anchorCenterX: number, panelLeft: number, panelWidth: number): number;
@@ -1,5 +1,6 @@
1
1
  export * from './dropdown';
2
2
  export * from './useCallbackRef';
3
3
  export * from './useFloatingPosition';
4
+ export * from './useIsomorphicLayoutEffect';
4
5
  export * from './useMediaQuery';
5
6
  export * from './useMergeRefs';
@@ -0,0 +1,2 @@
1
+ import { useEffect } from 'react';
2
+ export declare const useIsomorphicLayoutEffect: typeof useEffect;
@@ -3202,7 +3202,7 @@ button {
3202
3202
  transform: translateX(50%);
3203
3203
  }
3204
3204
  .ncua-tooltip__bg--top::after {
3205
- left: 50%;
3205
+ left: var(--ncua-tooltip-arrow-x, 50%);
3206
3206
  transform: translateX(-50%);
3207
3207
  }
3208
3208
  .ncua-tooltip__bg--top-left {
@@ -3248,7 +3248,7 @@ button {
3248
3248
  transform: translateX(50%);
3249
3249
  }
3250
3250
  .ncua-tooltip__bg--bottom::after {
3251
- left: 50%;
3251
+ left: var(--ncua-tooltip-arrow-x, 50%);
3252
3252
  transform: translateX(-50%);
3253
3253
  }
3254
3254
  .ncua-tooltip__bg--bottom-left {
@@ -5924,19 +5924,12 @@ button {
5924
5924
  left: 50%;
5925
5925
  transform: translate(-50%, -50%);
5926
5926
  z-index: var(--z-index-sticky);
5927
+ margin: 0 !important;
5927
5928
  }
5928
5929
  .ncua-image-file-input__empty-slot-wrapper .ncua-tooltip svg {
5929
5930
  opacity: 0;
5930
5931
  cursor: pointer;
5931
5932
  }
5932
- .ncua-image-file-input__empty-slot-wrapper .ncua-tooltip .ncua-tooltip__bg {
5933
- left: 50%;
5934
- right: auto;
5935
- transform: translateX(-50%);
5936
- width: max-content;
5937
- max-width: 320px;
5938
- white-space: nowrap;
5939
- }
5940
5933
  .ncua-image-file-input__preview-container {
5941
5934
  position: relative;
5942
5935
  border: 1px dashed var(--gray-200);
@@ -6043,10 +6036,6 @@ button {
6043
6036
  .ncua-image-file-input--xs .ncua-image-file-input__preview-container:not(:has(.ncua-image-file-input__preview-image))[disabled], .ncua-image-file-input--xs .ncua-image-file-input__preview-container:not(:has(.ncua-image-file-input__preview-image)).is-disable {
6044
6037
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10 4.16669V15.8334M4.16669 10H15.8334' stroke='%23d3d4d8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
6045
6038
  }
6046
- .ncua-image-file-input--xs .ncua-image-file-input__empty-slot-wrapper .ncua-tooltip .ncua-tooltip__bg {
6047
- top: auto;
6048
- bottom: -20px;
6049
- }
6050
6039
  .ncua-image-file-input--sm {
6051
6040
  font-size: var(--font-size-sm);
6052
6041
  line-height: var(--line-heights-sm);
@@ -6067,10 +6056,6 @@ button {
6067
6056
  .ncua-image-file-input--sm .ncua-image-file-input__preview-container:not(:has(.ncua-image-file-input__preview-image))[disabled], .ncua-image-file-input--sm .ncua-image-file-input__preview-container:not(:has(.ncua-image-file-input__preview-image)).is-disable {
6068
6057
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10 4.16669V15.8334M4.16669 10H15.8334' stroke='%23d3d4d8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
6069
6058
  }
6070
- .ncua-image-file-input--sm .ncua-image-file-input__empty-slot-wrapper .ncua-tooltip .ncua-tooltip__bg {
6071
- top: auto;
6072
- bottom: -16px;
6073
- }
6074
6059
  .ncua-image-file-input--xs .ncua-file-input {
6075
6060
  gap: 8px;
6076
6061
  }
@@ -6078,6 +6063,10 @@ button {
6078
6063
  gap: 16px;
6079
6064
  }
6080
6065
 
6066
+ .ncua-tooltip-panel.ncua-tooltip__bg.ncua-image-file-input__slot-tooltip {
6067
+ pointer-events: none;
6068
+ }
6069
+
6081
6070
  .ncua-tooltip-panel.ncua-image-file-input__slot-tooltip--xs {
6082
6071
  transform: translateY(-19px);
6083
6072
  }
@@ -7045,11 +7034,18 @@ button {
7045
7034
  color: var(--primary-red-600);
7046
7035
  font-weight: 400;
7047
7036
  }
7037
+ .ncua-sub-title--middle {
7038
+ gap: 2px;
7039
+ }
7048
7040
  .ncua-sub-title--middle .ncua-sub-title__title {
7049
7041
  font-size: var(--font-size-md);
7050
- font-weight: 500;
7042
+ font-weight: var(--font-weights-commerce-sans-1);
7051
7043
  line-height: var(--line-heights-md);
7052
7044
  }
7045
+ .ncua-sub-title--middle .ncua-sub-title__description {
7046
+ font-size: var(--font-size-xs);
7047
+ line-height: var(--line-heights-xs);
7048
+ }
7053
7049
  .ncua-sub-title--sm .ncua-sub-title__title-area {
7054
7050
  gap: 6px;
7055
7051
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncds/ui-admin",
3
- "version": "1.8.14",
3
+ "version": "1.8.15",
4
4
  "description": "nhn-commerce의 어드민 디자인 시스템입니다.",
5
5
  "scripts": {
6
6
  "barrel": "node barrel.js",