@ncds/ui-admin 1.8.25-alpha.0 → 1.8.25-alpha.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.
- package/dist/cjs/src/components/forms-and-input/combo-box/ComboBox.js +109 -28
- package/dist/cjs/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +581 -0
- package/dist/cjs/src/generated/scoped-css.js +1 -1
- package/dist/cjs/src/hooks/__tests__/useFloatingPosition.ssr.test.js +29 -0
- package/dist/cjs/src/hooks/__tests__/useFloatingPosition.test.js +322 -0
- package/dist/cjs/src/hooks/dropdown/useDropdown.js +2 -1
- package/dist/cjs/src/hooks/useFloatingPosition.js +14 -53
- package/dist/cjs/src/utils/dropdown/__tests__/dropdownUtils.test.js +316 -0
- package/dist/cjs/src/utils/dropdown/dropdownUtils.js +8 -12
- package/dist/cjs/src/utils/portal-position/__tests__/portalPosition.test.js +227 -0
- package/dist/cjs/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +397 -0
- package/dist/cjs/src/utils/portal-position/index.js +16 -0
- package/dist/cjs/src/utils/portal-position/portalPosition.js +162 -0
- package/dist/esm/src/components/forms-and-input/combo-box/ComboBox.js +109 -28
- package/dist/esm/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +578 -0
- package/dist/esm/src/generated/scoped-css.js +1 -1
- package/dist/esm/src/hooks/__tests__/useFloatingPosition.ssr.test.js +26 -0
- package/dist/esm/src/hooks/__tests__/useFloatingPosition.test.js +319 -0
- package/dist/esm/src/hooks/dropdown/useDropdown.js +2 -1
- package/dist/esm/src/hooks/useFloatingPosition.js +15 -54
- package/dist/esm/src/utils/dropdown/__tests__/dropdownUtils.test.js +314 -0
- package/dist/esm/src/utils/dropdown/dropdownUtils.js +8 -12
- package/dist/esm/src/utils/portal-position/__tests__/portalPosition.test.js +225 -0
- package/dist/esm/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +394 -0
- package/dist/esm/src/utils/portal-position/index.js +1 -0
- package/dist/esm/src/utils/portal-position/portalPosition.js +150 -0
- package/dist/temp/assets/scripts/notification/const/sizes.d.ts +1 -1
- package/dist/temp/src/components/action/button-group/ButtonGroup.d.ts +1 -1
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.d.ts +6 -0
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.js +54 -4
- package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.d.ts +1 -0
- package/dist/temp/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.js +418 -0
- package/dist/temp/src/generated/scoped-css.js +1 -1
- package/dist/temp/src/hooks/__tests__/useFloatingPosition.ssr.test.d.ts +1 -0
- package/dist/temp/src/hooks/__tests__/useFloatingPosition.ssr.test.js +26 -0
- package/dist/temp/src/hooks/__tests__/useFloatingPosition.test.d.ts +1 -0
- package/dist/temp/src/hooks/__tests__/useFloatingPosition.test.js +205 -0
- package/dist/temp/src/hooks/dropdown/useDropdown.d.ts +3 -1
- package/dist/temp/src/hooks/dropdown/useDropdown.js +2 -2
- package/dist/temp/src/hooks/dropdown/useDropdownPosition.d.ts +3 -3
- package/dist/temp/src/hooks/useFloatingPosition.d.ts +6 -4
- package/dist/temp/src/hooks/useFloatingPosition.js +14 -47
- package/dist/temp/src/types/dropdown/dropdown.d.ts +2 -1
- package/dist/temp/src/utils/dropdown/__tests__/dropdownUtils.test.d.ts +1 -0
- package/dist/temp/src/utils/dropdown/__tests__/dropdownUtils.test.js +174 -0
- package/dist/temp/src/utils/dropdown/dropdownUtils.js +8 -9
- package/dist/temp/src/utils/portal-position/__tests__/portalPosition.test.d.ts +1 -0
- package/dist/temp/src/utils/portal-position/__tests__/portalPosition.test.js +181 -0
- package/dist/temp/src/utils/portal-position/__tests__/portalPosition.tracking.test.d.ts +1 -0
- package/dist/temp/src/utils/portal-position/__tests__/portalPosition.tracking.test.js +301 -0
- package/dist/temp/src/utils/portal-position/index.d.ts +1 -0
- package/dist/temp/src/utils/portal-position/index.js +1 -0
- package/dist/temp/src/utils/portal-position/portalPosition.d.ts +67 -0
- package/dist/temp/src/utils/portal-position/portalPosition.js +88 -0
- package/dist/types/assets/scripts/notification/const/sizes.d.ts +1 -1
- package/dist/types/src/components/action/button-group/ButtonGroup.d.ts +1 -1
- package/dist/types/src/components/forms-and-input/combo-box/ComboBox.d.ts +6 -0
- package/dist/types/src/components/forms-and-input/combo-box/__tests__/ComboBox.portal.test.d.ts +1 -0
- package/dist/types/src/hooks/__tests__/useFloatingPosition.ssr.test.d.ts +1 -0
- package/dist/types/src/hooks/__tests__/useFloatingPosition.test.d.ts +1 -0
- package/dist/types/src/hooks/dropdown/useDropdown.d.ts +3 -1
- package/dist/types/src/hooks/dropdown/useDropdownPosition.d.ts +3 -3
- package/dist/types/src/hooks/useFloatingPosition.d.ts +6 -4
- package/dist/types/src/types/dropdown/dropdown.d.ts +2 -1
- package/dist/types/src/utils/dropdown/__tests__/dropdownUtils.test.d.ts +1 -0
- package/dist/types/src/utils/portal-position/__tests__/portalPosition.test.d.ts +1 -0
- package/dist/types/src/utils/portal-position/__tests__/portalPosition.tracking.test.d.ts +1 -0
- package/dist/types/src/utils/portal-position/index.d.ts +1 -0
- package/dist/types/src/utils/portal-position/portalPosition.d.ts +67 -0
- package/dist/ui-admin/assets/styles/style.css +13 -1
- package/package.json +1 -1
|
@@ -8,7 +8,10 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
8
8
|
var _uiAdminIcon = require("@ncds/ui-admin-icon");
|
|
9
9
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
10
10
|
var _react = require("react");
|
|
11
|
+
var _reactDom = require("react-dom");
|
|
11
12
|
var _dropdown = require("../../../hooks/dropdown");
|
|
13
|
+
var _useFloatingPosition = require("../../../hooks/useFloatingPosition");
|
|
14
|
+
var _usePortalState = require("../../../hooks/usePortalState");
|
|
12
15
|
var _multiSelect = require("../../../utils/dropdown/multiSelect");
|
|
13
16
|
var _button = require("../../action/button");
|
|
14
17
|
var _tag = require("../../feedback-and-status/tag");
|
|
@@ -27,7 +30,49 @@ const notifyFormChange = (register, multiple, newValue) => {
|
|
|
27
30
|
});
|
|
28
31
|
}
|
|
29
32
|
};
|
|
30
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Portal 모드에서만 패널에 `--portal` 클래스와 fixed 좌표를 얹는다.
|
|
35
|
+
* floatingStyle 이 null 인 초기 레이아웃 직전에는 클래스만 붙지만,
|
|
36
|
+
* useLayoutEffect 가 paint 전에 좌표를 채우므로 빈 fixed 가 노출되지 않는다.
|
|
37
|
+
*/
|
|
38
|
+
const resolvePortalPanelBinding = (shouldPortal, floatingStyle) => {
|
|
39
|
+
if (!shouldPortal) {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
className: 'ncua-select-dropdown--portal',
|
|
44
|
+
style: floatingStyle ?? undefined
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* 패널 노드를 인라인·Portal 두 마운트 지점 중 한 곳에만 넘긴다. 양쪽에 두면 dropdownRef 가
|
|
49
|
+
* 나중 노드로 덮여 외부 클릭 판정과 키보드 스크롤이 유령 노드를 가리키게 된다.
|
|
50
|
+
*/
|
|
51
|
+
const resolveDropdownMounts = _ref => {
|
|
52
|
+
let {
|
|
53
|
+
node,
|
|
54
|
+
shouldPortal,
|
|
55
|
+
portalContainer,
|
|
56
|
+
isOpen
|
|
57
|
+
} = _ref;
|
|
58
|
+
if (!shouldPortal) {
|
|
59
|
+
return {
|
|
60
|
+
inlineDropdown: node,
|
|
61
|
+
portaledDropdown: null
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (!portalContainer || !isOpen) {
|
|
65
|
+
return {
|
|
66
|
+
inlineDropdown: null,
|
|
67
|
+
portaledDropdown: null
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
inlineDropdown: null,
|
|
72
|
+
portaledDropdown: /*#__PURE__*/(0, _reactDom.createPortal)(node, portalContainer)
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
31
76
|
let {
|
|
32
77
|
placeholder = '검색하세요',
|
|
33
78
|
id,
|
|
@@ -51,11 +96,19 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
51
96
|
maxSelection,
|
|
52
97
|
onEdit,
|
|
53
98
|
onComplete,
|
|
99
|
+
usePortal = false,
|
|
54
100
|
...props
|
|
55
|
-
} =
|
|
101
|
+
} = _ref2;
|
|
56
102
|
const internalRef = (0, _react.useRef)(null);
|
|
103
|
+
// 인라인 패널의 offset parent 가 __content 다. Portal 좌표도 같은 박스를 기준으로 잡아야
|
|
104
|
+
// label·hintText 가 있을 때 두 모드의 패널 위치가 어긋나지 않는다.
|
|
105
|
+
const contentRef = (0, _react.useRef)(null);
|
|
57
106
|
const dropdownRef = (0, _react.useRef)(null);
|
|
58
107
|
const inputRef = (0, _react.useRef)(null);
|
|
108
|
+
const {
|
|
109
|
+
shouldPortal,
|
|
110
|
+
portalContainer
|
|
111
|
+
} = (0, _usePortalState.usePortalState)(usePortal);
|
|
59
112
|
const [inputValue, setInputValue] = (0, _react.useState)(searchValue);
|
|
60
113
|
const [showAllItems, setShowAllItems] = (0, _react.useState)(false);
|
|
61
114
|
const [selectedTags, setSelectedTags] = (0, _react.useState)([]);
|
|
@@ -108,6 +161,9 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
108
161
|
} = (0, _dropdown.useDropdown)({
|
|
109
162
|
triggerRef: internalRef,
|
|
110
163
|
dropdownRef,
|
|
164
|
+
// Portal 모드에서는 hintText 등으로 root 가 content 보다 아래까지 차지할 수 있어
|
|
165
|
+
// internalRef 기준 direction 판정이 잘못될 수 있다. contentRef 로 교정한다.
|
|
166
|
+
positionRef: shouldPortal ? contentRef : undefined,
|
|
111
167
|
maxHeight,
|
|
112
168
|
itemCount: optionItems.length,
|
|
113
169
|
optionItems: optionItems,
|
|
@@ -140,6 +196,14 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
140
196
|
// 나머지는 useDropdown 훅에서 처리
|
|
141
197
|
dropdownHandleKeyDown(e);
|
|
142
198
|
};
|
|
199
|
+
const floatingStyle = (0, _useFloatingPosition.useFloatingPosition)({
|
|
200
|
+
enabled: shouldPortal,
|
|
201
|
+
isOpen,
|
|
202
|
+
triggerRef: contentRef,
|
|
203
|
+
floatingRef: dropdownRef,
|
|
204
|
+
direction: dropdownDirection,
|
|
205
|
+
matchTriggerWidth: true
|
|
206
|
+
});
|
|
143
207
|
// biome-ignore lint/style/noNonNullAssertion: forwardRef 패턴에서 internalRef는 첫 렌더 후 항상 존재
|
|
144
208
|
(0, _react.useImperativeHandle)(ref, () => internalRef.current, []);
|
|
145
209
|
const trailingElement = {
|
|
@@ -210,6 +274,47 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
210
274
|
const showFooter = multiple || showFooterButtons;
|
|
211
275
|
const hiddenInputValue = multiple ? JSON.stringify(value || []) : String(value || '');
|
|
212
276
|
const hasTags = selectedTags.length > 0;
|
|
277
|
+
const {
|
|
278
|
+
className: portalPanelClassName,
|
|
279
|
+
style: portalPanelStyle
|
|
280
|
+
} = resolvePortalPanelBinding(shouldPortal, floatingStyle);
|
|
281
|
+
const selectDropdownNode = (0, _jsxRuntime.jsxs)(_selectDropdown.SelectDropdown, {
|
|
282
|
+
ref: dropdownRef,
|
|
283
|
+
isOpen: isOpen,
|
|
284
|
+
direction: dropdownDirection,
|
|
285
|
+
size: size,
|
|
286
|
+
options: displayedOptions,
|
|
287
|
+
value: value,
|
|
288
|
+
focusedIndex: focusedIndex,
|
|
289
|
+
maxHeight: maxHeight,
|
|
290
|
+
listboxId: comboboxId,
|
|
291
|
+
onOptionSelect: handleDropdownSelect,
|
|
292
|
+
onMouseMove: handleMouseMove,
|
|
293
|
+
isKeyboardNavigation: isKeyboardNavigation,
|
|
294
|
+
multiple: multiple,
|
|
295
|
+
showFooterButtons: showFooter,
|
|
296
|
+
selectAllButtonText: selectAllButtonText,
|
|
297
|
+
showSelectAllAction: !isMaxSelectionActive,
|
|
298
|
+
onSelectAll: handleSelectAll,
|
|
299
|
+
onEdit: handleEdit,
|
|
300
|
+
onComplete: handleComplete,
|
|
301
|
+
componentType: "combobox",
|
|
302
|
+
className: portalPanelClassName,
|
|
303
|
+
style: portalPanelStyle,
|
|
304
|
+
children: [showNoResults ? (0, _jsxRuntime.jsx)("li", {
|
|
305
|
+
className: "ncua-select-dropdown__no-results",
|
|
306
|
+
children: "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
307
|
+
}) : null, children]
|
|
308
|
+
});
|
|
309
|
+
const {
|
|
310
|
+
inlineDropdown,
|
|
311
|
+
portaledDropdown
|
|
312
|
+
} = resolveDropdownMounts({
|
|
313
|
+
node: selectDropdownNode,
|
|
314
|
+
shouldPortal,
|
|
315
|
+
portalContainer,
|
|
316
|
+
isOpen
|
|
317
|
+
});
|
|
213
318
|
return (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
214
319
|
children: [(0, _jsxRuntime.jsxs)("div", {
|
|
215
320
|
ref: internalRef,
|
|
@@ -220,6 +325,7 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
220
325
|
}, className),
|
|
221
326
|
...props,
|
|
222
327
|
children: [(0, _jsxRuntime.jsxs)("div", {
|
|
328
|
+
ref: contentRef,
|
|
223
329
|
className: "ncua-combobox__content",
|
|
224
330
|
children: [(0, _jsxRuntime.jsx)(_InputBase.InputBase, {
|
|
225
331
|
ref: inputRef,
|
|
@@ -246,32 +352,7 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
246
352
|
setInputValue('');
|
|
247
353
|
onSearch?.('');
|
|
248
354
|
}
|
|
249
|
-
}),
|
|
250
|
-
ref: dropdownRef,
|
|
251
|
-
isOpen: isOpen,
|
|
252
|
-
direction: dropdownDirection,
|
|
253
|
-
size: size,
|
|
254
|
-
options: displayedOptions,
|
|
255
|
-
value: value,
|
|
256
|
-
focusedIndex: focusedIndex,
|
|
257
|
-
maxHeight: maxHeight,
|
|
258
|
-
listboxId: comboboxId,
|
|
259
|
-
onOptionSelect: handleDropdownSelect,
|
|
260
|
-
onMouseMove: handleMouseMove,
|
|
261
|
-
isKeyboardNavigation: isKeyboardNavigation,
|
|
262
|
-
multiple: multiple,
|
|
263
|
-
showFooterButtons: showFooter,
|
|
264
|
-
selectAllButtonText: selectAllButtonText,
|
|
265
|
-
showSelectAllAction: !isMaxSelectionActive,
|
|
266
|
-
onSelectAll: handleSelectAll,
|
|
267
|
-
onEdit: handleEdit,
|
|
268
|
-
onComplete: handleComplete,
|
|
269
|
-
componentType: "combobox",
|
|
270
|
-
children: [showNoResults ? (0, _jsxRuntime.jsx)("li", {
|
|
271
|
-
className: "ncua-select-dropdown__no-results",
|
|
272
|
-
children: "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
273
|
-
}) : null, children]
|
|
274
|
-
})]
|
|
355
|
+
}), inlineDropdown, portaledDropdown]
|
|
275
356
|
}), register && (0, _jsxRuntime.jsx)("input", {
|
|
276
357
|
type: "hidden",
|
|
277
358
|
...register,
|