@ncds/ui-admin 1.8.25-alpha.2 → 1.8.25

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 (42) hide show
  1. package/dist/cjs/src/components/feedback-and-status/badge/Badge.js +1 -1
  2. package/dist/cjs/src/components/forms-and-input/combo-box/ComboBox.js +122 -54
  3. package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  4. package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +455 -0
  5. package/dist/cjs/src/components/forms-and-input/combo-box/utils.js +51 -0
  6. package/dist/cjs/src/generated/scoped-css.js +1 -1
  7. package/dist/cjs/src/hooks/__tests__/useFloatingPosition.test.js +32 -0
  8. package/dist/cjs/src/hooks/useFloatingPosition.js +2 -1
  9. package/dist/cjs/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +21 -0
  10. package/dist/cjs/src/utils/portal-position/portalPosition.js +7 -3
  11. package/dist/esm/src/components/feedback-and-status/badge/Badge.js +1 -1
  12. package/dist/esm/src/components/forms-and-input/combo-box/ComboBox.js +121 -53
  13. package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  14. package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +452 -0
  15. package/dist/esm/src/components/forms-and-input/combo-box/utils.js +43 -0
  16. package/dist/esm/src/generated/scoped-css.js +1 -1
  17. package/dist/esm/src/hooks/__tests__/useFloatingPosition.test.js +32 -0
  18. package/dist/esm/src/hooks/useFloatingPosition.js +2 -1
  19. package/dist/esm/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +21 -0
  20. package/dist/esm/src/utils/portal-position/portalPosition.js +7 -3
  21. package/dist/temp/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  22. package/dist/temp/src/components/feedback-and-status/badge/Badge.js +1 -1
  23. package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
  24. package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.js +114 -32
  25. package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
  26. package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.d.ts +1 -0
  27. package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +293 -0
  28. package/dist/temp/src/components/forms-and-input/combo-box/utils.d.ts +27 -0
  29. package/dist/temp/src/components/forms-and-input/combo-box/utils.js +25 -0
  30. package/dist/temp/src/generated/scoped-css.js +1 -1
  31. package/dist/temp/src/hooks/__tests__/useFloatingPosition.test.js +24 -0
  32. package/dist/temp/src/hooks/useFloatingPosition.js +3 -2
  33. package/dist/temp/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +13 -0
  34. package/dist/temp/src/utils/portal-position/portalPosition.d.ts +11 -14
  35. package/dist/temp/src/utils/portal-position/portalPosition.js +9 -4
  36. package/dist/types/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  37. package/dist/types/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
  38. package/dist/types/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.d.ts +1 -0
  39. package/dist/types/src/components/forms-and-input/combo-box/utils.d.ts +27 -0
  40. package/dist/types/src/utils/portal-position/portalPosition.d.ts +11 -14
  41. package/dist/ui-admin/assets/styles/style.css +14 -12
  42. package/package.json +1 -1
@@ -203,3 +203,27 @@ describe('useFloatingPosition — 프롭 변경 재구독 (E-5)', () => {
203
203
  hook.unmount();
204
204
  });
205
205
  });
206
+ describe('useFloatingPosition — 좌표 불변 갱신', () => {
207
+ it('scroll 뒤에도 top·left·minWidth 가 같으면 이전 style 참조를 유지해 하위 트리 리렌더를 건너뛴다', () => {
208
+ installResizeObserverStub();
209
+ const hook = renderHook(baseParams({
210
+ triggerRef: makeRef(createAnchor()),
211
+ floatingRef: makeRef(createPanel()),
212
+ matchTriggerWidth: true,
213
+ }));
214
+ const styleBeforeScroll = hook.latest();
215
+ dispatchScroll();
216
+ expect(hook.latest()).toBe(styleBeforeScroll);
217
+ hook.unmount();
218
+ });
219
+ it('scroll 로 좌표가 바뀌면 새 style 로 다시 렌더링한다', () => {
220
+ installResizeObserverStub();
221
+ const anchor = createAnchor();
222
+ const hook = renderHook(baseParams({ triggerRef: makeRef(anchor), floatingRef: makeRef(createPanel()) }));
223
+ const moved = makeAnchorRect({ top: 300, bottom: 340 });
224
+ vi.spyOn(anchor, 'getBoundingClientRect').mockReturnValue(toDomRect(moved));
225
+ dispatchScroll();
226
+ expect(hook.latest()).toMatchObject({ top: moved.bottom + DEFAULT_OFFSET });
227
+ hook.unmount();
228
+ });
229
+ });
@@ -1,6 +1,7 @@
1
1
  import { useState } from 'react';
2
- import { trackPortalPosition } from '../utils/portal-position';
2
+ import { trackPortalPosition, } from '../utils/portal-position';
3
3
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
4
+ const isSamePlacement = (prev, next) => prev !== null && prev.top === next.top && prev.left === next.left && prev.minWidth === next.minWidth;
4
5
  export const useFloatingPosition = ({ enabled, isOpen, triggerRef, floatingRef, direction, offset, align, matchTriggerWidth = false, }) => {
5
6
  const [style, setStyle] = useState(null);
6
7
  useIsomorphicLayoutEffect(() => {
@@ -15,7 +16,7 @@ export const useFloatingPosition = ({ enabled, isOpen, triggerRef, floatingRef,
15
16
  align,
16
17
  offset,
17
18
  matchAnchorWidth: matchTriggerWidth,
18
- onUpdate: setStyle,
19
+ onUpdate: (next) => setStyle((prev) => (isSamePlacement(prev, next) ? prev : next)),
19
20
  });
20
21
  }, [enabled, isOpen, direction, offset, align, matchTriggerWidth, triggerRef, floatingRef]);
21
22
  return style;
@@ -71,6 +71,19 @@ describe('observeAnchorGeometry — 구독 (E-6)', () => {
71
71
  expect(onChange).toHaveBeenCalledTimes(ON_CHANGE_CALLS.afterScroll);
72
72
  cleanup();
73
73
  });
74
+ it('panel 자신과 그 내부 요소의 scroll 은 anchor 를 움직이지 않으므로 onChange 를 호출하지 않는다', () => {
75
+ installResizeObserverStub();
76
+ const anchor = createAnchor();
77
+ const panel = createPanel();
78
+ const optionList = document.createElement('ul');
79
+ panel.appendChild(optionList);
80
+ const onChange = vi.fn();
81
+ const cleanup = observeAnchorGeometry({ getAnchor: () => anchor.element, getPanel: () => panel, onChange });
82
+ panel.dispatchEvent(new Event('scroll', { bubbles: false }));
83
+ optionList.dispatchEvent(new Event('scroll', { bubbles: false }));
84
+ expect(onChange).toHaveBeenCalledTimes(ON_CHANGE_CALLS.initial);
85
+ cleanup();
86
+ });
74
87
  it('anchor 와 panel 각각에 ResizeObserver 를 붙인다', () => {
75
88
  const { instances } = installResizeObserverStub();
76
89
  const anchor = createAnchor();
@@ -2,7 +2,7 @@ export type PortalDirection = 'up' | 'down';
2
2
  export type PortalAlign = 'left' | 'right';
3
3
  export type AnchorRect = Readonly<Pick<DOMRectReadOnly, 'top' | 'bottom' | 'left' | 'right' | 'width'>>;
4
4
  export declare const PORTAL_PANEL_Z_INDEX = 1500;
5
- export type ComputePortalPositionInput = Readonly<{
5
+ export type ComputePortalPositionParams = Readonly<{
6
6
  anchorRect: AnchorRect;
7
7
  panelHeight: number;
8
8
  panelWidth: number;
@@ -14,15 +14,15 @@ export type PortalPosition = Readonly<{
14
14
  top: number;
15
15
  left: number;
16
16
  }>;
17
- export declare const computePortalPosition: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, }: ComputePortalPositionInput) => PortalPosition;
18
- export type ResolveDropdownDirectionInput = Readonly<{
17
+ export declare const computePortalPosition: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, }: ComputePortalPositionParams) => PortalPosition;
18
+ export type ResolveDropdownDirectionParams = Readonly<{
19
19
  anchorRect: Pick<AnchorRect, 'bottom'>;
20
20
  panelHeight: number;
21
21
  viewportHeight: number;
22
22
  gap?: number;
23
23
  }>;
24
- export declare const resolveDropdownDirection: ({ anchorRect, panelHeight, viewportHeight, gap, }: ResolveDropdownDirectionInput) => PortalDirection;
25
- export type BuildPortalPanelStyleInput = Readonly<{
24
+ export declare const resolveDropdownDirection: ({ anchorRect, panelHeight, viewportHeight, gap, }: ResolveDropdownDirectionParams) => PortalDirection;
25
+ export type BuildPortalPanelStyleParams = Readonly<{
26
26
  anchorRect: AnchorRect;
27
27
  panelHeight: number;
28
28
  panelWidth: number | null;
@@ -42,18 +42,15 @@ export type PortalPanelStyle = Readonly<{
42
42
  zIndex: number;
43
43
  minWidth?: number;
44
44
  }>;
45
- export declare const buildPortalPanelStyle: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, matchAnchorWidth, }: BuildPortalPanelStyleInput) => PortalPanelStyle;
46
- export type AnchorGeometryObserverOptions = Readonly<{
45
+ export declare const buildPortalPanelStyle: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, matchAnchorWidth, }: BuildPortalPanelStyleParams) => PortalPanelStyle;
46
+ export type ObserveAnchorGeometryParams = Readonly<{
47
47
  getAnchor: () => HTMLElement | null;
48
- /**
49
- * 구독 시점에 1회 호출되어 ResizeObserver 가 부착된다.
50
- * 구독 후 패널이 교체·마운트되어도 옵저버는 갱신되지 않는다.
51
- */
48
+ /** ResizeObserver 는 구독 시점의 패널에만 부착된다 — 이후 교체·마운트되어도 옵저버는 갱신되지 않는다. */
52
49
  getPanel: () => HTMLElement | null;
53
50
  onChange: () => void;
54
51
  }>;
55
- export declare const observeAnchorGeometry: ({ getAnchor, getPanel, onChange, }: AnchorGeometryObserverOptions) => (() => void);
56
- export type TrackPortalPositionOptions = Readonly<{
52
+ export declare const observeAnchorGeometry: ({ getAnchor, getPanel, onChange }: ObserveAnchorGeometryParams) => (() => void);
53
+ export type TrackPortalPositionParams = Readonly<{
57
54
  getAnchor: () => HTMLElement | null;
58
55
  getPanel: () => HTMLElement | null;
59
56
  /** 함수를 넘기면 갱신마다 다시 읽는다 — 열린 뒤 패널 높이가 변하는 소비자가 방향을 재판정할 수 있다 */
@@ -63,5 +60,5 @@ export type TrackPortalPositionOptions = Readonly<{
63
60
  matchAnchorWidth?: boolean;
64
61
  onUpdate: (style: PortalPanelStyle) => void;
65
62
  }>;
66
- export declare const trackPortalPosition: ({ onUpdate, ...measureOptions }: TrackPortalPositionOptions) => (() => void);
63
+ export declare const trackPortalPosition: ({ onUpdate, ...measureOptions }: TrackPortalPositionParams) => (() => void);
67
64
  export declare const applyPortalPanelStyle: (element: HTMLElement, style: PortalPanelStyle) => void;
@@ -47,17 +47,23 @@ export const buildPortalPanelStyle = ({ anchorRect, panelHeight, panelWidth, dir
47
47
  // 옵션이 짧으면 앵커 너비, 길면 자연 확장 — Portal 이전 absolute 모드와 동일한 UX.
48
48
  return matchAnchorWidth ? { ...base, minWidth: anchorRect.width } : base;
49
49
  };
50
- export const observeAnchorGeometry = ({ getAnchor, getPanel, onChange, }) => {
50
+ export const observeAnchorGeometry = ({ getAnchor, getPanel, onChange }) => {
51
51
  const anchor = getAnchor();
52
52
  if (anchor === null) {
53
53
  return noop;
54
54
  }
55
55
  onChange();
56
- window.addEventListener('scroll', onChange, { passive: true, capture: true });
56
+ // 패널 내부 스크롤은 anchor 를 움직이지 않는다
57
+ const onScroll = (event) => {
58
+ if (event.target instanceof Node && getPanel()?.contains(event.target))
59
+ return;
60
+ onChange();
61
+ };
62
+ window.addEventListener('scroll', onScroll, { passive: true, capture: true });
57
63
  window.addEventListener('resize', onChange);
58
64
  const observers = [observeElementResize(anchor, onChange), observeElementResize(getPanel(), onChange)];
59
65
  return () => {
60
- window.removeEventListener('scroll', onChange, { capture: true });
66
+ window.removeEventListener('scroll', onScroll, { capture: true });
61
67
  window.removeEventListener('resize', onChange);
62
68
  for (const observer of observers) {
63
69
  observer?.disconnect();
@@ -74,7 +80,6 @@ export const trackPortalPosition = ({ onUpdate, ...measureOptions }) => observeA
74
80
  }
75
81
  },
76
82
  });
77
- // TODO(#497): vanilla 어댑터 도입 시 소비
78
83
  export const applyPortalPanelStyle = (element, style) => {
79
84
  element.style.position = style.position;
80
85
  element.style.top = `${style.top}px`;
@@ -16,4 +16,4 @@ type BadgeProps = {
16
16
  };
17
17
  declare const Badge: ({ label, type, color, className, leadingIcon, trailingIcon, size, }: BadgeProps) => import("react/jsx-runtime").JSX.Element;
18
18
  export { Badge };
19
- export type { BadgeColor, BadgeProps, BadgeSize, BadgeType };
19
+ export type { BadgeType, BadgeColor, BadgeSize, BadgeProps };
@@ -10,7 +10,7 @@ interface ComboBoxProps extends Omit<ComponentPropsWithRef<'div'>, 'size' | 'onC
10
10
  destructive?: boolean;
11
11
  size?: Extract<Size, 'xs' | 'sm'>;
12
12
  optionItems?: OptionType[];
13
- value?: OptionValue;
13
+ value?: OptionValue | null;
14
14
  onChange?: OptionChangeHandler;
15
15
  onSearch?: (searchValue: string) => void;
16
16
  disabled?: boolean;
@@ -0,0 +1,27 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+ type PortalPanelBinding = {
3
+ className?: string;
4
+ style?: CSSProperties;
5
+ };
6
+ type DropdownMounts = {
7
+ inlineDropdown: ReactNode;
8
+ portaledDropdown: ReactNode;
9
+ };
10
+ type ResolveDropdownMountsParams = {
11
+ node: ReactNode;
12
+ shouldPortal: boolean;
13
+ portalContainer: HTMLElement | null;
14
+ isOpen: boolean;
15
+ };
16
+ /**
17
+ * Portal 모드에서만 패널에 `--portal` 클래스와 fixed 좌표를 얹는다.
18
+ * floatingStyle 이 null 인 초기 레이아웃 직전에는 클래스만 붙지만,
19
+ * useLayoutEffect 가 paint 전에 좌표를 채우므로 빈 fixed 가 노출되지 않는다.
20
+ */
21
+ export declare const resolvePortalPanelBinding: (shouldPortal: boolean, floatingStyle: CSSProperties | null) => PortalPanelBinding;
22
+ /**
23
+ * 패널 노드를 인라인·Portal 두 마운트 지점 중 한 곳에만 넘긴다. 양쪽에 두면 dropdownRef 가
24
+ * 나중 노드로 덮여 외부 클릭 판정과 키보드 스크롤이 유령 노드를 가리키게 된다.
25
+ */
26
+ export declare const resolveDropdownMounts: ({ node, shouldPortal, portalContainer, isOpen, }: ResolveDropdownMountsParams) => DropdownMounts;
27
+ export {};
@@ -2,7 +2,7 @@ export type PortalDirection = 'up' | 'down';
2
2
  export type PortalAlign = 'left' | 'right';
3
3
  export type AnchorRect = Readonly<Pick<DOMRectReadOnly, 'top' | 'bottom' | 'left' | 'right' | 'width'>>;
4
4
  export declare const PORTAL_PANEL_Z_INDEX = 1500;
5
- export type ComputePortalPositionInput = Readonly<{
5
+ export type ComputePortalPositionParams = Readonly<{
6
6
  anchorRect: AnchorRect;
7
7
  panelHeight: number;
8
8
  panelWidth: number;
@@ -14,15 +14,15 @@ export type PortalPosition = Readonly<{
14
14
  top: number;
15
15
  left: number;
16
16
  }>;
17
- export declare const computePortalPosition: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, }: ComputePortalPositionInput) => PortalPosition;
18
- export type ResolveDropdownDirectionInput = Readonly<{
17
+ export declare const computePortalPosition: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, }: ComputePortalPositionParams) => PortalPosition;
18
+ export type ResolveDropdownDirectionParams = Readonly<{
19
19
  anchorRect: Pick<AnchorRect, 'bottom'>;
20
20
  panelHeight: number;
21
21
  viewportHeight: number;
22
22
  gap?: number;
23
23
  }>;
24
- export declare const resolveDropdownDirection: ({ anchorRect, panelHeight, viewportHeight, gap, }: ResolveDropdownDirectionInput) => PortalDirection;
25
- export type BuildPortalPanelStyleInput = Readonly<{
24
+ export declare const resolveDropdownDirection: ({ anchorRect, panelHeight, viewportHeight, gap, }: ResolveDropdownDirectionParams) => PortalDirection;
25
+ export type BuildPortalPanelStyleParams = Readonly<{
26
26
  anchorRect: AnchorRect;
27
27
  panelHeight: number;
28
28
  panelWidth: number | null;
@@ -42,18 +42,15 @@ export type PortalPanelStyle = Readonly<{
42
42
  zIndex: number;
43
43
  minWidth?: number;
44
44
  }>;
45
- export declare const buildPortalPanelStyle: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, matchAnchorWidth, }: BuildPortalPanelStyleInput) => PortalPanelStyle;
46
- export type AnchorGeometryObserverOptions = Readonly<{
45
+ export declare const buildPortalPanelStyle: ({ anchorRect, panelHeight, panelWidth, direction, align, offset, matchAnchorWidth, }: BuildPortalPanelStyleParams) => PortalPanelStyle;
46
+ export type ObserveAnchorGeometryParams = Readonly<{
47
47
  getAnchor: () => HTMLElement | null;
48
- /**
49
- * 구독 시점에 1회 호출되어 ResizeObserver 가 부착된다.
50
- * 구독 후 패널이 교체·마운트되어도 옵저버는 갱신되지 않는다.
51
- */
48
+ /** ResizeObserver 는 구독 시점의 패널에만 부착된다 — 이후 교체·마운트되어도 옵저버는 갱신되지 않는다. */
52
49
  getPanel: () => HTMLElement | null;
53
50
  onChange: () => void;
54
51
  }>;
55
- export declare const observeAnchorGeometry: ({ getAnchor, getPanel, onChange, }: AnchorGeometryObserverOptions) => (() => void);
56
- export type TrackPortalPositionOptions = Readonly<{
52
+ export declare const observeAnchorGeometry: ({ getAnchor, getPanel, onChange }: ObserveAnchorGeometryParams) => (() => void);
53
+ export type TrackPortalPositionParams = Readonly<{
57
54
  getAnchor: () => HTMLElement | null;
58
55
  getPanel: () => HTMLElement | null;
59
56
  /** 함수를 넘기면 갱신마다 다시 읽는다 — 열린 뒤 패널 높이가 변하는 소비자가 방향을 재판정할 수 있다 */
@@ -63,5 +60,5 @@ export type TrackPortalPositionOptions = Readonly<{
63
60
  matchAnchorWidth?: boolean;
64
61
  onUpdate: (style: PortalPanelStyle) => void;
65
62
  }>;
66
- export declare const trackPortalPosition: ({ onUpdate, ...measureOptions }: TrackPortalPositionOptions) => (() => void);
63
+ export declare const trackPortalPosition: ({ onUpdate, ...measureOptions }: TrackPortalPositionParams) => (() => void);
67
64
  export declare const applyPortalPanelStyle: (element: HTMLElement, style: PortalPanelStyle) => void;
@@ -67,6 +67,9 @@
67
67
  --shadow-xs-focused-3px-primary-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 3px #ffeaee;
68
68
  --shadow-xs-focused-3px-gray-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 3px #f2f4f7;
69
69
  --shadow-xs-focused-3px-error-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 3px #fee4e2;
70
+ --shadow-xs-focused-4px-primary-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 4px #ffeaee;
71
+ --shadow-xs-focused-4px-gray-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 4px #f2f4f7;
72
+ --shadow-xs-focused-4px-error-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 4px #fee4e2;
70
73
  --shadow-sm: 0px 1px 3px 0px #1018281a, 0px 1px 2px 0px #1018280f;
71
74
  --shadow-sm-focused-4px-primary-100: 0px 1px 2px 0px #1018280d, 0px 0px 0px 4px #ffeaee;
72
75
  --shadow-sm-focused-4px-gray-100: 0px 1px 3px 0px #1018281a, 0px 1px 2px 0px #1018280f, 0px 0px 0px 4px #f2f4f7;
@@ -324,7 +327,7 @@ button {
324
327
  background-color: var(--primary-red-450);
325
328
  border: 1px solid var(--primary-red-500);
326
329
  color: var(--base-white);
327
- box-shadow: var(--shadow-sm-focused-4px-primary-100);
330
+ box-shadow: var(--shadow-xs-focused-4px-primary-100);
328
331
  }
329
332
  .ncua-btn--primary:disabled, .ncua-btn--primary.is-disable {
330
333
  background-color: var(--primary-red-100);
@@ -370,7 +373,7 @@ button {
370
373
  background-color: var(--base-white);
371
374
  border: 1px solid var(--gray-200);
372
375
  color: var(--gray-700);
373
- box-shadow: var(--shadow-sm-focused-4px-gray-100);
376
+ box-shadow: var(--shadow-xs-focused-4px-gray-100);
374
377
  }
375
378
  .ncua-btn--secondary-gray:disabled, .ncua-btn--secondary-gray.is-disable {
376
379
  background-color: var(--base-white);
@@ -956,7 +959,7 @@ button {
956
959
  }
957
960
  .ncua-checkbox-input.destructive :where(input):focus {
958
961
  border-color: var(--primary-red-600);
959
- box-shadow: var(--shadow-sm-focused-4px-error-100);
962
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
960
963
  }
961
964
  .ncua-checkbox-input:hover {
962
965
  border-color: var(--gray-600);
@@ -1739,7 +1742,7 @@ button {
1739
1742
  border-color: var(--primary-red-600);
1740
1743
  }
1741
1744
  .ncua-input.destructive:where(:focus-within) .ncua-input__field {
1742
- box-shadow: var(--shadow-sm-focused-4px-error-100);
1745
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
1743
1746
  }
1744
1747
  .ncua-input.is-disabled .ncua-input__content > :not(button) {
1745
1748
  background-color: var(--gray-50);
@@ -1929,7 +1932,7 @@ button {
1929
1932
  border-color: var(--primary-red-600);
1930
1933
  }
1931
1934
  .ncua-input--textarea.destructive textarea:focus {
1932
- box-shadow: var(--shadow-sm-focused-4px-error-100);
1935
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
1933
1936
  }
1934
1937
 
1935
1938
  .ncua-input--textarea--xs textarea {
@@ -3191,7 +3194,7 @@ button {
3191
3194
  }
3192
3195
  .ncua-radio-input.destructive :where(input):focus {
3193
3196
  border-color: var(--primary-red-600);
3194
- box-shadow: var(--shadow-sm-focused-4px-error-100);
3197
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
3195
3198
  }
3196
3199
 
3197
3200
  .ncua-radio-field {
@@ -3693,7 +3696,7 @@ button {
3693
3696
  border-color: var(--primary-red-600);
3694
3697
  }
3695
3698
  .ncua-select.destructive .ncua-select__content:focus-within {
3696
- box-shadow: var(--shadow-sm-focused-4px-error-100);
3699
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
3697
3700
  }
3698
3701
  .ncua-select--xs .ncua-select__content {
3699
3702
  height: var(--select-height-xs);
@@ -4034,7 +4037,7 @@ button {
4034
4037
  border-color: var(--primary-red-600);
4035
4038
  }
4036
4039
  .ncua-selectbox.destructive .ncua-selectbox__content:focus {
4037
- box-shadow: var(--shadow-sm-focused-4px-error-100);
4040
+ box-shadow: var(--shadow-xs-focused-4px-error-100);
4038
4041
  }
4039
4042
  .ncua-selectbox--xs .ncua-selectbox__content {
4040
4043
  height: var(--select-height-xs);
@@ -5337,16 +5340,15 @@ button {
5337
5340
  justify-content: center;
5338
5341
  color: var(--pink-600);
5339
5342
  background-color: var(--pink-200);
5343
+ border-radius: 5px;
5340
5344
  }
5341
5345
  .ncua-badge--new-badge-sm {
5342
5346
  width: 16px;
5343
5347
  height: 16px;
5344
- border-radius: 3px;
5345
5348
  }
5346
5349
  .ncua-badge--new-badge-md {
5347
5350
  width: 20px;
5348
5351
  height: 20px;
5349
- border-radius: 4px;
5350
5352
  }
5351
5353
 
5352
5354
  .ncua-badge-group {
@@ -6608,7 +6610,7 @@ button {
6608
6610
  bottom: 0;
6609
6611
  width: 3px;
6610
6612
  background: var(--base-black);
6611
- z-index: var(--z-index-1);
6613
+ z-index: 1;
6612
6614
  }
6613
6615
  .ncua-table__row--warning.ncua-table__row--selected:nth-child(n) {
6614
6616
  background: var(--orange-50);
@@ -6753,7 +6755,7 @@ button {
6753
6755
  .ncua-table--fixed-header .ncua-table__header-cell {
6754
6756
  position: sticky;
6755
6757
  top: 0;
6756
- z-index: var(--z-index-sticky);
6758
+ z-index: 10;
6757
6759
  padding: 0 var(--spacing-m);
6758
6760
  height: var(--ncua-table-header-height);
6759
6761
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncds/ui-admin",
3
- "version": "1.8.25-alpha.2",
3
+ "version": "1.8.25",
4
4
  "description": "nhn-commerce의 어드민 디자인 시스템입니다.",
5
5
  "scripts": {
6
6
  "barrel": "node barrel.js",