@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.
- package/dist/cjs/src/components/feedback-and-status/badge/Badge.js +1 -1
- package/dist/cjs/src/components/forms-and-input/combo-box/ComboBox.js +122 -54
- package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
- package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +455 -0
- package/dist/cjs/src/components/forms-and-input/combo-box/utils.js +51 -0
- package/dist/cjs/src/generated/scoped-css.js +1 -1
- package/dist/cjs/src/hooks/__tests__/useFloatingPosition.test.js +32 -0
- package/dist/cjs/src/hooks/useFloatingPosition.js +2 -1
- package/dist/cjs/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +21 -0
- package/dist/cjs/src/utils/portal-position/portalPosition.js +7 -3
- package/dist/esm/src/components/feedback-and-status/badge/Badge.js +1 -1
- package/dist/esm/src/components/forms-and-input/combo-box/ComboBox.js +121 -53
- package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
- package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +452 -0
- package/dist/esm/src/components/forms-and-input/combo-box/utils.js +43 -0
- package/dist/esm/src/generated/scoped-css.js +1 -1
- package/dist/esm/src/hooks/__tests__/useFloatingPosition.test.js +32 -0
- package/dist/esm/src/hooks/useFloatingPosition.js +2 -1
- package/dist/esm/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +21 -0
- package/dist/esm/src/utils/portal-position/portalPosition.js +7 -3
- package/dist/temp/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
- package/dist/temp/src/components/feedback-and-status/badge/Badge.js +1 -1
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.js +114 -32
- package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +3 -3
- package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.d.ts +1 -0
- package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.js +293 -0
- package/dist/temp/src/components/forms-and-input/combo-box/utils.d.ts +27 -0
- package/dist/temp/src/components/forms-and-input/combo-box/utils.js +25 -0
- package/dist/temp/src/generated/scoped-css.js +1 -1
- package/dist/temp/src/hooks/__tests__/useFloatingPosition.test.js +24 -0
- package/dist/temp/src/hooks/useFloatingPosition.js +3 -2
- package/dist/temp/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +13 -0
- package/dist/temp/src/utils/portal-position/portalPosition.d.ts +11 -14
- package/dist/temp/src/utils/portal-position/portalPosition.js +9 -4
- package/dist/types/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
- package/dist/types/src/components/forms-and-input/combo-box/ComboBox.d.ts +1 -1
- package/dist/types/src/components/forms-and-input/combo-box/__tests__/ComboBox.test.d.ts +1 -0
- package/dist/types/src/components/forms-and-input/combo-box/utils.d.ts +27 -0
- package/dist/types/src/utils/portal-position/portalPosition.d.ts +11 -14
- package/dist/ui-admin/assets/styles/style.css +14 -12
- 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
|
|
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, }:
|
|
18
|
-
export type
|
|
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, }:
|
|
25
|
-
export type
|
|
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, }:
|
|
46
|
-
export type
|
|
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
|
|
56
|
-
export type
|
|
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 }:
|
|
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
|
-
|
|
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',
|
|
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 {
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
|
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, }:
|
|
18
|
-
export type
|
|
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, }:
|
|
25
|
-
export type
|
|
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, }:
|
|
46
|
-
export type
|
|
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
|
|
56
|
-
export type
|
|
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 }:
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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:
|
|
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:
|
|
6758
|
+
z-index: 10;
|
|
6757
6759
|
padding: 0 var(--spacing-m);
|
|
6758
6760
|
height: var(--ncua-table-header-height);
|
|
6759
6761
|
}
|