@ncds/ui-admin 1.8.3 → 1.8.5
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/assets/scripts/featuredIcon.js +87 -0
- package/dist/cjs/assets/scripts/notification/FloatingNotification.js +178 -0
- package/dist/cjs/assets/scripts/notification/FullWidthNotification.js +133 -0
- package/dist/cjs/assets/scripts/notification/MessageNotification.js +159 -0
- package/dist/cjs/assets/scripts/notification/Notification.js +120 -0
- package/dist/cjs/assets/scripts/notification/const/classNames.js +50 -0
- package/dist/cjs/assets/scripts/notification/const/icons.js +31 -0
- package/dist/cjs/assets/scripts/notification/const/index.js +87 -0
- package/dist/cjs/assets/scripts/notification/const/sizes.js +46 -0
- package/dist/cjs/assets/scripts/notification/const/types.js +14 -0
- package/dist/cjs/assets/scripts/notification/index.js +116 -0
- package/dist/cjs/assets/scripts/notification/positionSync.js +180 -0
- package/dist/cjs/assets/scripts/notification/utils.js +122 -0
- package/dist/cjs/assets/scripts/shared/ButtonCloseX.js +45 -0
- package/dist/cjs/assets/scripts/utils/sanitize.js +39 -0
- package/dist/cjs/src/components/data-display/data-grid/DataGrid.js +5 -1
- package/dist/cjs/src/components/data-display/table/Table.js +118 -96
- package/dist/cjs/src/components/data-display/table/useTableScrollbars.js +187 -0
- package/dist/cjs/src/components/forms-and-input/combo-box/ComboBox.js +11 -10
- package/dist/cjs/src/components/forms-and-input/image-file-input/ImageFileInput.js +5 -2
- package/dist/cjs/src/components/forms-and-input/select-box/SelectBox.js +67 -29
- package/dist/cjs/src/components/index.js +33 -0
- package/dist/cjs/src/components/layout/block-container/BlockContainer.js +38 -0
- package/dist/cjs/src/components/layout/block-container/index.js +16 -0
- package/dist/cjs/src/components/layout/block-header/BlockHeader.js +107 -0
- package/dist/cjs/src/components/layout/block-header/SubTitle.js +56 -0
- package/dist/cjs/src/components/layout/block-header/index.js +27 -0
- package/dist/cjs/src/components/layout/page-title/PageTitle.js +95 -0
- package/dist/cjs/src/components/layout/page-title/index.js +16 -0
- package/dist/cjs/src/components/overlays/dropdown/Dropdown.js +47 -19
- package/dist/cjs/src/components/overlays/notification/CalloutNotification.js +25 -0
- package/dist/cjs/src/components/overlays/notification/FloatingNotification.js +86 -13
- package/dist/cjs/src/components/overlays/notification/Notification.js +7 -0
- package/dist/cjs/src/components/overlays/notification/host.js +12 -0
- package/dist/cjs/src/components/overlays/tooltip/Tooltip.js +57 -44
- package/dist/cjs/src/components/select-dropdown/SelectDropdown.js +2 -1
- package/dist/cjs/src/contexts/FloatingContext.js +11 -0
- package/dist/cjs/src/contexts/index.js +16 -0
- package/dist/cjs/src/hooks/index.js +11 -0
- package/dist/cjs/src/hooks/useFloatingPosition.js +78 -0
- package/dist/cjs/src/hooks/usePortalState.js +17 -0
- package/dist/cjs/src/utils/dropdown/maxSelection.js +35 -0
- package/dist/cjs/src/utils/dropdown/multiSelect.js +72 -15
- package/dist/esm/assets/scripts/featuredIcon.js +80 -0
- package/dist/esm/assets/scripts/notification/FloatingNotification.js +171 -0
- package/dist/esm/assets/scripts/notification/FullWidthNotification.js +126 -0
- package/dist/esm/assets/scripts/notification/MessageNotification.js +152 -0
- package/dist/esm/assets/scripts/notification/Notification.js +113 -0
- package/dist/esm/assets/scripts/notification/const/classNames.js +44 -0
- package/dist/esm/assets/scripts/notification/const/icons.js +25 -0
- package/dist/esm/assets/scripts/notification/const/index.js +4 -0
- package/dist/esm/assets/scripts/notification/const/sizes.js +40 -0
- package/dist/esm/assets/scripts/notification/const/types.js +8 -0
- package/dist/esm/assets/scripts/notification/index.js +10 -0
- package/dist/esm/assets/scripts/notification/positionSync.js +171 -0
- package/dist/esm/assets/scripts/notification/utils.js +109 -0
- package/dist/esm/assets/scripts/shared/ButtonCloseX.js +37 -0
- package/dist/esm/assets/scripts/utils/sanitize.js +31 -0
- package/dist/esm/src/components/data-display/data-grid/DataGrid.js +5 -1
- package/dist/esm/src/components/data-display/table/Table.js +118 -96
- package/dist/esm/src/components/data-display/table/useTableScrollbars.js +179 -0
- package/dist/esm/src/components/forms-and-input/combo-box/ComboBox.js +11 -10
- package/dist/esm/src/components/forms-and-input/image-file-input/ImageFileInput.js +5 -2
- package/dist/esm/src/components/forms-and-input/select-box/SelectBox.js +67 -29
- package/dist/esm/src/components/index.js +3 -0
- package/dist/esm/src/components/layout/block-container/BlockContainer.js +31 -0
- package/dist/esm/src/components/layout/block-container/index.js +1 -0
- package/dist/esm/src/components/layout/block-header/BlockHeader.js +100 -0
- package/dist/esm/src/components/layout/block-header/SubTitle.js +49 -0
- package/dist/esm/src/components/layout/block-header/index.js +2 -0
- package/dist/esm/src/components/layout/page-title/PageTitle.js +88 -0
- package/dist/esm/src/components/layout/page-title/index.js +1 -0
- package/dist/esm/src/components/overlays/dropdown/Dropdown.js +47 -19
- package/dist/esm/src/components/overlays/notification/CalloutNotification.js +19 -0
- package/dist/esm/src/components/overlays/notification/FloatingNotification.js +86 -14
- package/dist/esm/src/components/overlays/notification/Notification.js +7 -0
- package/dist/esm/src/components/overlays/notification/host.js +9 -0
- package/dist/esm/src/components/overlays/tooltip/Tooltip.js +58 -45
- package/dist/esm/src/components/select-dropdown/SelectDropdown.js +2 -1
- package/dist/esm/src/contexts/FloatingContext.js +4 -0
- package/dist/esm/src/contexts/index.js +1 -0
- package/dist/esm/src/hooks/index.js +1 -0
- package/dist/esm/src/hooks/useFloatingPosition.js +71 -0
- package/dist/esm/src/hooks/usePortalState.js +10 -0
- package/dist/esm/src/utils/dropdown/maxSelection.js +27 -0
- package/dist/esm/src/utils/dropdown/multiSelect.js +70 -14
- package/dist/temp/assets/scripts/featuredIcon.d.ts +22 -0
- package/dist/temp/assets/scripts/featuredIcon.js +79 -0
- package/dist/temp/assets/scripts/notification/FloatingNotification.d.ts +24 -0
- package/dist/temp/assets/scripts/notification/FloatingNotification.js +156 -0
- package/dist/temp/assets/scripts/notification/FullWidthNotification.d.ts +21 -0
- package/dist/temp/assets/scripts/notification/FullWidthNotification.js +111 -0
- package/dist/temp/assets/scripts/notification/MessageNotification.d.ts +22 -0
- package/dist/temp/assets/scripts/notification/MessageNotification.js +140 -0
- package/dist/temp/assets/scripts/notification/Notification.d.ts +22 -0
- package/dist/temp/assets/scripts/notification/Notification.js +112 -0
- package/dist/temp/assets/scripts/notification/const/classNames.d.ts +43 -0
- package/dist/temp/assets/scripts/notification/const/classNames.js +44 -0
- package/dist/temp/assets/scripts/notification/const/icons.d.ts +25 -0
- package/dist/temp/assets/scripts/notification/const/icons.js +25 -0
- package/dist/temp/assets/scripts/notification/const/index.d.ts +5 -0
- package/dist/temp/assets/scripts/notification/const/index.js +4 -0
- package/dist/temp/assets/scripts/notification/const/sizes.d.ts +32 -0
- package/dist/temp/assets/scripts/notification/const/sizes.js +40 -0
- package/dist/temp/assets/scripts/notification/const/types.d.ts +19 -0
- package/dist/temp/assets/scripts/notification/const/types.js +8 -0
- package/dist/temp/assets/scripts/notification/index.d.ts +8 -0
- package/dist/temp/assets/scripts/notification/index.js +10 -0
- package/dist/temp/assets/scripts/notification/positionSync.d.ts +50 -0
- package/dist/temp/assets/scripts/notification/positionSync.js +170 -0
- package/dist/temp/assets/scripts/notification/utils.d.ts +8 -0
- package/dist/temp/assets/scripts/notification/utils.js +115 -0
- package/dist/temp/assets/scripts/shared/ButtonCloseX.d.ts +5 -0
- package/dist/temp/assets/scripts/shared/ButtonCloseX.js +33 -0
- package/dist/temp/assets/scripts/utils/sanitize.d.ts +22 -0
- package/dist/temp/assets/scripts/utils/sanitize.js +31 -0
- package/dist/temp/src/components/data-display/data-grid/DataGrid.js +1 -1
- package/dist/temp/src/components/data-display/data-grid/DataGrid.types.d.ts +7 -0
- package/dist/temp/src/components/data-display/table/Table.d.ts +4 -1
- package/dist/temp/src/components/data-display/table/Table.js +53 -68
- package/dist/temp/src/components/data-display/table/types.d.ts +18 -0
- package/dist/temp/src/components/data-display/table/useTableScrollbars.d.ts +25 -0
- package/dist/temp/src/components/data-display/table/useTableScrollbars.js +136 -0
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.d.ts +8 -0
- package/dist/temp/src/components/forms-and-input/combo-box/ComboBox.js +7 -11
- package/dist/temp/src/components/forms-and-input/image-file-input/ImageFileInput.js +1 -1
- package/dist/temp/src/components/forms-and-input/select-box/SelectBox.d.ts +13 -0
- package/dist/temp/src/components/forms-and-input/select-box/SelectBox.js +30 -3
- package/dist/temp/src/components/index.d.ts +3 -0
- package/dist/temp/src/components/index.js +3 -0
- package/dist/temp/src/components/layout/block-container/BlockContainer.d.ts +19 -0
- package/dist/temp/src/components/layout/block-container/BlockContainer.js +11 -0
- package/dist/temp/src/components/layout/block-container/index.d.ts +1 -0
- package/dist/temp/src/components/layout/block-container/index.js +1 -0
- package/dist/temp/src/components/layout/block-header/BlockHeader.d.ts +23 -0
- package/dist/temp/src/components/layout/block-header/BlockHeader.js +21 -0
- package/dist/temp/src/components/layout/block-header/SubTitle.d.ts +19 -0
- package/dist/temp/src/components/layout/block-header/SubTitle.js +8 -0
- package/dist/temp/src/components/layout/block-header/index.d.ts +2 -0
- package/dist/temp/src/components/layout/block-header/index.js +2 -0
- package/dist/temp/src/components/layout/page-title/PageTitle.d.ts +22 -0
- package/dist/temp/src/components/layout/page-title/PageTitle.js +19 -0
- package/dist/temp/src/components/layout/page-title/index.d.ts +1 -0
- package/dist/temp/src/components/layout/page-title/index.js +1 -0
- package/dist/temp/src/components/overlays/dropdown/Dropdown.d.ts +5 -0
- package/dist/temp/src/components/overlays/dropdown/Dropdown.js +35 -11
- package/dist/temp/src/components/overlays/notification/CalloutNotification.d.ts +9 -0
- package/dist/temp/src/components/overlays/notification/CalloutNotification.js +6 -0
- package/dist/temp/src/components/overlays/notification/FloatingNotification.d.ts +15 -0
- package/dist/temp/src/components/overlays/notification/FloatingNotification.js +81 -13
- package/dist/temp/src/components/overlays/notification/Notification.d.ts +18 -3
- package/dist/temp/src/components/overlays/notification/Notification.js +4 -0
- package/dist/temp/src/components/overlays/notification/host.d.ts +9 -0
- package/dist/temp/src/components/overlays/notification/host.js +9 -0
- package/dist/temp/src/components/overlays/tooltip/Tooltip.d.ts +5 -1
- package/dist/temp/src/components/overlays/tooltip/Tooltip.js +25 -22
- package/dist/temp/src/components/select-dropdown/SelectDropdown.d.ts +6 -0
- package/dist/temp/src/components/select-dropdown/SelectDropdown.js +2 -2
- package/dist/temp/src/contexts/FloatingContext.d.ts +6 -0
- package/dist/temp/src/contexts/FloatingContext.js +4 -0
- package/dist/temp/src/contexts/index.d.ts +1 -0
- package/dist/temp/src/contexts/index.js +1 -0
- package/dist/temp/src/hooks/index.d.ts +1 -0
- package/dist/temp/src/hooks/index.js +1 -0
- package/dist/temp/src/hooks/useFloatingPosition.d.ts +19 -0
- package/dist/temp/src/hooks/useFloatingPosition.js +55 -0
- package/dist/temp/src/hooks/usePortalState.d.ts +6 -0
- package/dist/temp/src/hooks/usePortalState.js +7 -0
- package/dist/temp/src/utils/dropdown/maxSelection.d.ts +24 -0
- package/dist/temp/src/utils/dropdown/maxSelection.js +28 -0
- package/dist/temp/src/utils/dropdown/multiSelect.d.ts +42 -2
- package/dist/temp/src/utils/dropdown/multiSelect.js +66 -13
- package/dist/types/assets/scripts/featuredIcon.d.ts +22 -0
- package/dist/types/assets/scripts/notification/FloatingNotification.d.ts +24 -0
- package/dist/types/assets/scripts/notification/FullWidthNotification.d.ts +21 -0
- package/dist/types/assets/scripts/notification/MessageNotification.d.ts +22 -0
- package/dist/types/assets/scripts/notification/Notification.d.ts +22 -0
- package/dist/types/assets/scripts/notification/const/classNames.d.ts +43 -0
- package/dist/types/assets/scripts/notification/const/icons.d.ts +25 -0
- package/dist/types/assets/scripts/notification/const/index.d.ts +5 -0
- package/dist/types/assets/scripts/notification/const/sizes.d.ts +32 -0
- package/dist/types/assets/scripts/notification/const/types.d.ts +19 -0
- package/dist/types/assets/scripts/notification/index.d.ts +8 -0
- package/dist/types/assets/scripts/notification/positionSync.d.ts +50 -0
- package/dist/types/assets/scripts/notification/utils.d.ts +8 -0
- package/dist/types/assets/scripts/shared/ButtonCloseX.d.ts +5 -0
- package/dist/types/assets/scripts/utils/sanitize.d.ts +22 -0
- package/dist/types/src/components/data-display/data-grid/DataGrid.types.d.ts +7 -0
- package/dist/types/src/components/data-display/table/Table.d.ts +4 -1
- package/dist/types/src/components/data-display/table/types.d.ts +18 -0
- package/dist/types/src/components/data-display/table/useTableScrollbars.d.ts +25 -0
- package/dist/types/src/components/forms-and-input/combo-box/ComboBox.d.ts +8 -0
- package/dist/types/src/components/forms-and-input/select-box/SelectBox.d.ts +13 -0
- package/dist/types/src/components/index.d.ts +3 -0
- package/dist/types/src/components/layout/block-container/BlockContainer.d.ts +19 -0
- package/dist/types/src/components/layout/block-container/index.d.ts +1 -0
- package/dist/types/src/components/layout/block-header/BlockHeader.d.ts +23 -0
- package/dist/types/src/components/layout/block-header/SubTitle.d.ts +19 -0
- package/dist/types/src/components/layout/block-header/index.d.ts +2 -0
- package/dist/types/src/components/layout/page-title/PageTitle.d.ts +22 -0
- package/dist/types/src/components/layout/page-title/index.d.ts +1 -0
- package/dist/types/src/components/overlays/dropdown/Dropdown.d.ts +5 -0
- package/dist/types/src/components/overlays/notification/CalloutNotification.d.ts +9 -0
- package/dist/types/src/components/overlays/notification/FloatingNotification.d.ts +15 -0
- package/dist/types/src/components/overlays/notification/Notification.d.ts +18 -3
- package/dist/types/src/components/overlays/notification/host.d.ts +9 -0
- package/dist/types/src/components/overlays/tooltip/Tooltip.d.ts +5 -1
- package/dist/types/src/components/select-dropdown/SelectDropdown.d.ts +6 -0
- package/dist/types/src/contexts/FloatingContext.d.ts +6 -0
- package/dist/types/src/contexts/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/useFloatingPosition.d.ts +19 -0
- package/dist/types/src/hooks/usePortalState.d.ts +6 -0
- package/dist/types/src/utils/dropdown/maxSelection.d.ts +24 -0
- package/dist/types/src/utils/dropdown/multiSelect.d.ts +42 -2
- package/dist/ui-admin/assets/styles/style.css +596 -64
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ButtonCloseX = ButtonCloseX;
|
|
7
|
+
exports.X_CLOSE_SVG = exports.SVG_SIZE = void 0;
|
|
8
|
+
// 공통 X버튼 로직 (React ButtonCloseX 컴포넌트와 동일한 구조)
|
|
9
|
+
// React ButtonCloseX와 동일한 SVG 사이즈 매핑
|
|
10
|
+
const SVG_SIZE = exports.SVG_SIZE = {
|
|
11
|
+
xs: 16,
|
|
12
|
+
sm: 20,
|
|
13
|
+
md: 20,
|
|
14
|
+
lg: 24
|
|
15
|
+
};
|
|
16
|
+
// X버튼 SVG 아이콘
|
|
17
|
+
const X_CLOSE_SVG = size => `<svg width="${size}" height="${size}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
18
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
19
|
+
</svg>`;
|
|
20
|
+
// X버튼 렌더링 유틸리티 (React ButtonCloseX와 동일한 인터페이스)
|
|
21
|
+
exports.X_CLOSE_SVG = X_CLOSE_SVG;
|
|
22
|
+
function ButtonCloseX(size) {
|
|
23
|
+
let theme = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'light';
|
|
24
|
+
let additionalClasses = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
|
25
|
+
let ariaLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '닫기';
|
|
26
|
+
let onClick = arguments.length > 4 ? arguments[4] : undefined;
|
|
27
|
+
const svgSize = SVG_SIZE[size];
|
|
28
|
+
const buttonId = `close-btn-${Math.random().toString(36).substr(2, 9)}`;
|
|
29
|
+
const buttonHTML = `
|
|
30
|
+
<button type="button" id="${buttonId}" class="ncua-button-close-x ncua-button-close-x--${size} ncua-button-close-x--${theme} ${additionalClasses}" aria-label="${ariaLabel}">
|
|
31
|
+
${X_CLOSE_SVG(svgSize.toString())}
|
|
32
|
+
</button>
|
|
33
|
+
`;
|
|
34
|
+
// onClick이 제공된 경우 이벤트 바인딩
|
|
35
|
+
if (onClick) {
|
|
36
|
+
// DOM에 추가된 후 이벤트 바인딩을 위해 setTimeout 사용
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
const button = document.getElementById(buttonId);
|
|
39
|
+
if (button) {
|
|
40
|
+
button.addEventListener('click', onClick);
|
|
41
|
+
}
|
|
42
|
+
}, 0);
|
|
43
|
+
}
|
|
44
|
+
return buttonHTML;
|
|
45
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sanitizeHtml = sanitizeHtml;
|
|
7
|
+
exports.setSafeInnerHTML = setSafeInnerHTML;
|
|
8
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
/**
|
|
11
|
+
* HTML 문자열을 DOMPurify 기본 설정으로 sanitize한다.
|
|
12
|
+
*
|
|
13
|
+
* 제거되는 항목 (기본 설정):
|
|
14
|
+
* - `<script>`, `<iframe>`, `<object>` 등 실행 위험 태그
|
|
15
|
+
* - `onclick`, `onerror` 등 inline 이벤트 핸들러 속성
|
|
16
|
+
* - `href="javascript:..."` 같은 javascript: URL
|
|
17
|
+
*
|
|
18
|
+
* 유지되는 항목:
|
|
19
|
+
* - `<svg>`, `<button>`, `<div>`, `<span>`, `<input>` 등 일반 HTML/SVG 태그
|
|
20
|
+
* - `class`, `style`, `role`, `aria-*`, `data-*` 등 표현용 속성
|
|
21
|
+
* - SVG 표현 속성 (`viewBox`, `stroke`, `fill` 등)
|
|
22
|
+
*
|
|
23
|
+
* 이벤트 바인딩은 addEventListener로 별도 처리할 것.
|
|
24
|
+
*/
|
|
25
|
+
function sanitizeHtml(dirty) {
|
|
26
|
+
return _dompurify.default.sanitize(dirty);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 엘리먼트에 콘텐츠를 안전하게 설정한다.
|
|
30
|
+
* - string: sanitize 후 innerHTML 교체
|
|
31
|
+
* - HTMLElement: 기존 자식 제거 후 appendChild
|
|
32
|
+
*/
|
|
33
|
+
function setSafeInnerHTML(element, content) {
|
|
34
|
+
if (content instanceof HTMLElement) {
|
|
35
|
+
element.replaceChildren(content);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
element.innerHTML = sanitizeHtml(content);
|
|
39
|
+
}
|
|
@@ -80,7 +80,9 @@ const DataGridTable = /*#__PURE__*/(0, _react.forwardRef)((_ref5, ref) => {
|
|
|
80
80
|
fixedHeader,
|
|
81
81
|
maxHeight,
|
|
82
82
|
hoverable,
|
|
83
|
-
selectable
|
|
83
|
+
selectable,
|
|
84
|
+
horizontalScroll,
|
|
85
|
+
minWidth
|
|
84
86
|
} = _ref5;
|
|
85
87
|
return (0, _jsxRuntime.jsx)("div", {
|
|
86
88
|
ref: ref,
|
|
@@ -92,6 +94,8 @@ const DataGridTable = /*#__PURE__*/(0, _react.forwardRef)((_ref5, ref) => {
|
|
|
92
94
|
maxHeight: maxHeight,
|
|
93
95
|
hoverable: hoverable,
|
|
94
96
|
selectable: selectable,
|
|
97
|
+
horizontalScroll: horizontalScroll,
|
|
98
|
+
minWidth: minWidth,
|
|
95
99
|
children: children
|
|
96
100
|
})
|
|
97
101
|
});
|
|
@@ -8,13 +8,19 @@ 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 _FloatingContext = require("../../../contexts/FloatingContext");
|
|
12
|
+
var _useTableScrollbars = require("./useTableScrollbars");
|
|
11
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
// 가로 스크롤 디자인 기준 폭 — 14인치 모니터 + LNB 고려한 디자인 권장 너비
|
|
15
|
+
const DEFAULT_HORIZONTAL_SCROLL_MIN_WIDTH = 1140;
|
|
16
|
+
const FLOATING_PORTAL_VALUE = {
|
|
17
|
+
preferPortal: true
|
|
18
|
+
};
|
|
19
|
+
// TABLE_HEADER_HEIGHT·DEFAULT_HORIZONTAL_SCROLL_MIN_WIDTH를 CSS 커스텀 프로퍼티로 주입 — SCSS fallback 단일 소스
|
|
20
|
+
const WRAPPER_STYLE = {
|
|
21
|
+
'--ncua-table-header-height': `${_useTableScrollbars.TABLE_HEADER_HEIGHT}px`,
|
|
22
|
+
'--ncua-table-default-min-width': `${DEFAULT_HORIZONTAL_SCROLL_MIN_WIDTH}px`
|
|
23
|
+
};
|
|
18
24
|
// Sort Icons (@ncds/ui-admin-icon)
|
|
19
25
|
// ──────────────────────────────────────────────
|
|
20
26
|
const SORT_ICONS = {
|
|
@@ -79,6 +85,7 @@ const HeaderCell = /*#__PURE__*/(0, _react.forwardRef)((_ref4, ref) => {
|
|
|
79
85
|
sortDirection,
|
|
80
86
|
onSort,
|
|
81
87
|
width,
|
|
88
|
+
minWidth,
|
|
82
89
|
style,
|
|
83
90
|
...rest
|
|
84
91
|
} = _ref4;
|
|
@@ -91,7 +98,8 @@ const HeaderCell = /*#__PURE__*/(0, _react.forwardRef)((_ref4, ref) => {
|
|
|
91
98
|
}),
|
|
92
99
|
style: {
|
|
93
100
|
...style,
|
|
94
|
-
width
|
|
101
|
+
width,
|
|
102
|
+
minWidth
|
|
95
103
|
},
|
|
96
104
|
"aria-sort": isSortable ? ARIA_SORT_MAP[sortDirection] : undefined,
|
|
97
105
|
onClick: isSortable ? onSort : undefined,
|
|
@@ -160,10 +168,11 @@ const Pagination = _ref7 => {
|
|
|
160
168
|
Pagination.displayName = 'Table.Pagination';
|
|
161
169
|
const ColGroup = _ref8 => {
|
|
162
170
|
let {
|
|
163
|
-
widths
|
|
171
|
+
widths,
|
|
172
|
+
minWidths
|
|
164
173
|
} = _ref8;
|
|
165
174
|
const resolveColWidth = width => {
|
|
166
|
-
if (width === 'auto') return undefined;
|
|
175
|
+
if (width === undefined || width === 'auto') return undefined;
|
|
167
176
|
if (typeof width === 'number') return `${width}px`;
|
|
168
177
|
return width;
|
|
169
178
|
};
|
|
@@ -172,7 +181,8 @@ const ColGroup = _ref8 => {
|
|
|
172
181
|
// biome-ignore lint/suspicious/noArrayIndexKey: colgroup columns never reorder or change
|
|
173
182
|
(0, _jsxRuntime.jsx)("col", {
|
|
174
183
|
style: {
|
|
175
|
-
width: resolveColWidth(width)
|
|
184
|
+
width: resolveColWidth(width),
|
|
185
|
+
minWidth: resolveColWidth(minWidths?.[index])
|
|
176
186
|
}
|
|
177
187
|
}, index))
|
|
178
188
|
});
|
|
@@ -234,6 +244,8 @@ const TableComponent = /*#__PURE__*/(0, _react.forwardRef)((_ref0, ref) => {
|
|
|
234
244
|
maxHeight,
|
|
235
245
|
hoverable = true,
|
|
236
246
|
selectable = false,
|
|
247
|
+
horizontalScroll = false,
|
|
248
|
+
minWidth,
|
|
237
249
|
children,
|
|
238
250
|
className,
|
|
239
251
|
...rest
|
|
@@ -253,90 +265,104 @@ const TableComponent = /*#__PURE__*/(0, _react.forwardRef)((_ref0, ref) => {
|
|
|
253
265
|
paginationContent
|
|
254
266
|
} = sortChildren(children);
|
|
255
267
|
const scrollStyle = fixedHeader && maxHeight ? {
|
|
256
|
-
maxHeight: typeof maxHeight === 'number' ? `${maxHeight + TABLE_HEADER_HEIGHT}px` : `calc(${maxHeight} + ${TABLE_HEADER_HEIGHT}px)`
|
|
268
|
+
maxHeight: typeof maxHeight === 'number' ? `${maxHeight + _useTableScrollbars.TABLE_HEADER_HEIGHT}px` : `calc(${maxHeight} + ${_useTableScrollbars.TABLE_HEADER_HEIGHT}px)`
|
|
257
269
|
} : undefined;
|
|
258
270
|
// Custom scrollbar refs (used only in fixed-header mode)
|
|
259
271
|
const scrollContainerRef = (0, _react.useRef)(null);
|
|
260
272
|
const scrollAreaRef = (0, _react.useRef)(null);
|
|
273
|
+
const scrollbarRef = (0, _react.useRef)(null);
|
|
261
274
|
const thumbRef = (0, _react.useRef)(null);
|
|
262
|
-
(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
areaEl?.removeAttribute('data-dragging');
|
|
314
|
-
document.removeEventListener('mousemove', onMove);
|
|
315
|
-
document.removeEventListener('mouseup', onUp);
|
|
316
|
-
};
|
|
317
|
-
document.addEventListener('mousemove', onMove);
|
|
318
|
-
document.addEventListener('mouseup', onUp);
|
|
275
|
+
// 가로 스크롤바 refs (horizontalScroll 모드)
|
|
276
|
+
const hScrollContainerRef = (0, _react.useRef)(null);
|
|
277
|
+
const hScrollbarRef = (0, _react.useRef)(null);
|
|
278
|
+
const hThumbRef = (0, _react.useRef)(null);
|
|
279
|
+
const fixedScrollEnabled = !!(fixedHeader && maxHeight);
|
|
280
|
+
const {
|
|
281
|
+
handleThumbMouseDown
|
|
282
|
+
} = (0, _useTableScrollbars.useTableVerticalScrollbar)({
|
|
283
|
+
enabled: fixedScrollEnabled,
|
|
284
|
+
scrollContainerRef,
|
|
285
|
+
scrollAreaRef,
|
|
286
|
+
thumbRef
|
|
287
|
+
});
|
|
288
|
+
const {
|
|
289
|
+
handleHThumbMouseDown
|
|
290
|
+
} = (0, _useTableScrollbars.useTableHorizontalScrollbar)({
|
|
291
|
+
enabled: horizontalScroll,
|
|
292
|
+
hScrollContainerRef,
|
|
293
|
+
hScrollbarRef,
|
|
294
|
+
hThumbRef
|
|
295
|
+
});
|
|
296
|
+
// <colgroup> + <thead> + <tbody> 묶음 — fixed-header 분기와 horizontalScroll 분기 모두에서 재사용
|
|
297
|
+
const renderTable = () => (0, _jsxRuntime.jsxs)("table", {
|
|
298
|
+
className: "ncua-table__table",
|
|
299
|
+
role: "table",
|
|
300
|
+
children: [colGroupContent, headerContent, tableContent]
|
|
301
|
+
});
|
|
302
|
+
// fixed-header 시 scroll-area + scrollbar 래핑, 아니면 <table> 그대로.
|
|
303
|
+
// withScrollbar=false 이면 scrollbar를 제외 — horizontalScroll 분기에서 scrollbar를
|
|
304
|
+
// h-scroll-container 형제 위치에 별도 렌더해 가로 스크롤 시 viewport 우측에 자연 고정.
|
|
305
|
+
const renderScrollableArea = function () {
|
|
306
|
+
let includeVerticalScrollbar = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
307
|
+
return fixedScrollEnabled ? (0, _jsxRuntime.jsxs)("div", {
|
|
308
|
+
ref: scrollAreaRef,
|
|
309
|
+
className: "ncua-table__scroll-area",
|
|
310
|
+
children: [(0, _jsxRuntime.jsx)("div", {
|
|
311
|
+
ref: scrollContainerRef,
|
|
312
|
+
className: "ncua-table__scroll-container",
|
|
313
|
+
style: scrollStyle,
|
|
314
|
+
children: renderTable()
|
|
315
|
+
}), includeVerticalScrollbar && (0, _jsxRuntime.jsx)("div", {
|
|
316
|
+
ref: scrollbarRef,
|
|
317
|
+
className: "ncua-table__scrollbar",
|
|
318
|
+
"aria-hidden": "true",
|
|
319
|
+
children: (0, _jsxRuntime.jsx)("div", {
|
|
320
|
+
ref: thumbRef,
|
|
321
|
+
className: "ncua-table__scrollbar-thumb",
|
|
322
|
+
onMouseDown: handleThumbMouseDown
|
|
323
|
+
})
|
|
324
|
+
})]
|
|
325
|
+
}) : renderTable();
|
|
319
326
|
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
// horizontalScroll=true 시 외곽 wrapper + FloatingProvider 부착.
|
|
328
|
+
// 핵심 — __h-scroll-container 는 <table>(또는 scroll-area) 만 감싸고, footer/pagination 은
|
|
329
|
+
// 그 바깥에서 항상 고정 위치. 세로 스크롤바는 h-scroll-container 형제로 배치되어
|
|
330
|
+
// 가로 스크롤에 영향받지 않고 .ncua-table 우측에 absolute 고정된다.
|
|
331
|
+
if (horizontalScroll) {
|
|
332
|
+
const resolvedMinWidth = minWidth ?? DEFAULT_HORIZONTAL_SCROLL_MIN_WIDTH;
|
|
333
|
+
// CSS 변수로 전달 — SCSS 에서 max(100%, var(--ncua-table-min-width)) 로 부모 너비를 항상 보장한다.
|
|
334
|
+
// (inline min-width 를 직접 주면 부모보다 작은 값에서 wrapper 가 좁아져 콘텐츠가 깨짐)
|
|
335
|
+
const innerStyle = {
|
|
336
|
+
'--ncua-table-min-width': typeof resolvedMinWidth === 'number' ? `${resolvedMinWidth}px` : resolvedMinWidth
|
|
337
|
+
};
|
|
338
|
+
return (0, _jsxRuntime.jsx)(_FloatingContext.FloatingProvider, {
|
|
339
|
+
value: FLOATING_PORTAL_VALUE,
|
|
340
|
+
children: (0, _jsxRuntime.jsxs)("div", {
|
|
341
|
+
ref: ref,
|
|
342
|
+
className: "ncua-table-wrapper",
|
|
343
|
+
style: WRAPPER_STYLE,
|
|
327
344
|
children: [(0, _jsxRuntime.jsxs)("div", {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
children: [(0, _jsxRuntime.
|
|
331
|
-
ref:
|
|
332
|
-
className: "ncua-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
345
|
+
className: tableClasses,
|
|
346
|
+
...rest,
|
|
347
|
+
children: [(0, _jsxRuntime.jsxs)("div", {
|
|
348
|
+
ref: hScrollContainerRef,
|
|
349
|
+
className: "ncua-table__h-scroll-container",
|
|
350
|
+
children: [(0, _jsxRuntime.jsx)("div", {
|
|
351
|
+
className: "ncua-table__h-scroll-inner",
|
|
352
|
+
style: innerStyle,
|
|
353
|
+
children: renderScrollableArea(false)
|
|
354
|
+
}), (0, _jsxRuntime.jsx)("div", {
|
|
355
|
+
ref: hScrollbarRef,
|
|
356
|
+
className: "ncua-table__h-scrollbar",
|
|
357
|
+
"aria-hidden": "true",
|
|
358
|
+
children: (0, _jsxRuntime.jsx)("div", {
|
|
359
|
+
ref: hThumbRef,
|
|
360
|
+
className: "ncua-table__h-scrollbar-thumb",
|
|
361
|
+
onMouseDown: handleHThumbMouseDown
|
|
362
|
+
})
|
|
363
|
+
})]
|
|
364
|
+
}), fixedScrollEnabled && (0, _jsxRuntime.jsx)("div", {
|
|
365
|
+
ref: scrollbarRef,
|
|
340
366
|
className: "ncua-table__scrollbar",
|
|
341
367
|
"aria-hidden": "true",
|
|
342
368
|
children: (0, _jsxRuntime.jsx)("div", {
|
|
@@ -344,23 +370,19 @@ const TableComponent = /*#__PURE__*/(0, _react.forwardRef)((_ref0, ref) => {
|
|
|
344
370
|
className: "ncua-table__scrollbar-thumb",
|
|
345
371
|
onMouseDown: handleThumbMouseDown
|
|
346
372
|
})
|
|
347
|
-
})]
|
|
348
|
-
}),
|
|
349
|
-
})
|
|
373
|
+
}), footerContent]
|
|
374
|
+
}), paginationContent]
|
|
375
|
+
})
|
|
350
376
|
});
|
|
351
377
|
}
|
|
352
|
-
const tableElement = (0, _jsxRuntime.jsxs)("table", {
|
|
353
|
-
className: "ncua-table__table",
|
|
354
|
-
role: "table",
|
|
355
|
-
children: [colGroupContent, headerContent, tableContent]
|
|
356
|
-
});
|
|
357
378
|
return (0, _jsxRuntime.jsxs)("div", {
|
|
358
379
|
ref: ref,
|
|
359
380
|
className: "ncua-table-wrapper",
|
|
381
|
+
style: WRAPPER_STYLE,
|
|
360
382
|
children: [(0, _jsxRuntime.jsxs)("div", {
|
|
361
383
|
className: tableClasses,
|
|
362
384
|
...rest,
|
|
363
|
-
children: [
|
|
385
|
+
children: [renderScrollableArea(), footerContent]
|
|
364
386
|
}), paginationContent]
|
|
365
387
|
});
|
|
366
388
|
});
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useTableVerticalScrollbar = exports.useTableHorizontalScrollbar = exports.TABLE_HEADER_HEIGHT = exports.SCROLLBAR_TRACK_OFFSET = exports.SCROLLBAR_THUMB_MIN_HEIGHT = exports.H_SCROLLBAR_THUMB_MIN_WIDTH = exports.H_SCROLLBAR_SIDE_GAP = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
// ──────────────────────────────────────────────
|
|
9
|
+
// 상수 — Table.tsx 와 _table.scss 양쪽에서 동기화 필요
|
|
10
|
+
// ──────────────────────────────────────────────
|
|
11
|
+
// $table-header-height
|
|
12
|
+
const TABLE_HEADER_HEIGHT = exports.TABLE_HEADER_HEIGHT = 40;
|
|
13
|
+
// 세로/가로 thumb 최소 크기
|
|
14
|
+
const SCROLLBAR_THUMB_MIN_HEIGHT = exports.SCROLLBAR_THUMB_MIN_HEIGHT = 40;
|
|
15
|
+
const H_SCROLLBAR_THUMB_MIN_WIDTH = exports.H_SCROLLBAR_THUMB_MIN_WIDTH = 40;
|
|
16
|
+
// SCSS .ncua-table__h-scrollbar { left/right: var(--spacing-s) = 8px } 와 동기화
|
|
17
|
+
const H_SCROLLBAR_SIDE_GAP = exports.H_SCROLLBAR_SIDE_GAP = 8;
|
|
18
|
+
// 세로 트랙 상하 여백 합계 — top 8 + bottom 8 = 16 (header 회피분 40 은 별도 처리)
|
|
19
|
+
// biome-ignore lint/style/useExportsLast: 상수는 문서 주석과 함께 상단에 정의
|
|
20
|
+
const SCROLLBAR_TRACK_OFFSET = exports.SCROLLBAR_TRACK_OFFSET = 16;
|
|
21
|
+
const startDrag = (e, options) => {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
const {
|
|
24
|
+
axis,
|
|
25
|
+
scrollEl,
|
|
26
|
+
thumbEl,
|
|
27
|
+
draggingTarget = scrollEl,
|
|
28
|
+
sideGap = 0
|
|
29
|
+
} = options;
|
|
30
|
+
draggingTarget.setAttribute('data-dragging', '');
|
|
31
|
+
if (axis === 'y') {
|
|
32
|
+
const startY = e.clientY;
|
|
33
|
+
const startScrollTop = scrollEl.scrollTop;
|
|
34
|
+
const {
|
|
35
|
+
scrollHeight,
|
|
36
|
+
clientHeight
|
|
37
|
+
} = scrollEl;
|
|
38
|
+
const thumbHeight = thumbEl.offsetHeight;
|
|
39
|
+
const ratio = (scrollHeight - clientHeight) / (clientHeight - thumbHeight);
|
|
40
|
+
const onMove = ev => {
|
|
41
|
+
scrollEl.scrollTop = startScrollTop + (ev.clientY - startY) * ratio;
|
|
42
|
+
};
|
|
43
|
+
const onUp = () => {
|
|
44
|
+
draggingTarget.removeAttribute('data-dragging');
|
|
45
|
+
document.removeEventListener('mousemove', onMove);
|
|
46
|
+
document.removeEventListener('mouseup', onUp);
|
|
47
|
+
};
|
|
48
|
+
document.addEventListener('mousemove', onMove);
|
|
49
|
+
document.addEventListener('mouseup', onUp);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const startX = e.clientX;
|
|
53
|
+
const startScrollLeft = scrollEl.scrollLeft;
|
|
54
|
+
const {
|
|
55
|
+
scrollWidth,
|
|
56
|
+
clientWidth
|
|
57
|
+
} = scrollEl;
|
|
58
|
+
const thumbWidth = thumbEl.offsetWidth;
|
|
59
|
+
const trackWidth = clientWidth - sideGap * 2;
|
|
60
|
+
const ratio = (scrollWidth - clientWidth) / (trackWidth - thumbWidth);
|
|
61
|
+
const onMove = ev => {
|
|
62
|
+
scrollEl.scrollLeft = startScrollLeft + (ev.clientX - startX) * ratio;
|
|
63
|
+
};
|
|
64
|
+
const onUp = () => {
|
|
65
|
+
draggingTarget.removeAttribute('data-dragging');
|
|
66
|
+
document.removeEventListener('mousemove', onMove);
|
|
67
|
+
document.removeEventListener('mouseup', onUp);
|
|
68
|
+
};
|
|
69
|
+
document.addEventListener('mousemove', onMove);
|
|
70
|
+
document.addEventListener('mouseup', onUp);
|
|
71
|
+
};
|
|
72
|
+
const useTableVerticalScrollbar = _ref => {
|
|
73
|
+
let {
|
|
74
|
+
enabled,
|
|
75
|
+
scrollContainerRef,
|
|
76
|
+
scrollAreaRef,
|
|
77
|
+
thumbRef
|
|
78
|
+
} = _ref;
|
|
79
|
+
(0, _react.useEffect)(() => {
|
|
80
|
+
if (!enabled) return;
|
|
81
|
+
const scrollEl = scrollContainerRef.current;
|
|
82
|
+
const thumbEl = thumbRef.current;
|
|
83
|
+
if (!scrollEl || !thumbEl) return;
|
|
84
|
+
const update = () => {
|
|
85
|
+
const {
|
|
86
|
+
scrollTop,
|
|
87
|
+
scrollHeight,
|
|
88
|
+
clientHeight
|
|
89
|
+
} = scrollEl;
|
|
90
|
+
if (scrollHeight <= clientHeight) {
|
|
91
|
+
thumbEl.style.height = '0';
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const trackHeight = (scrollAreaRef.current?.clientHeight ?? clientHeight) - TABLE_HEADER_HEIGHT - SCROLLBAR_TRACK_OFFSET;
|
|
95
|
+
const thumbHeight = Math.max(SCROLLBAR_THUMB_MIN_HEIGHT, clientHeight / scrollHeight * trackHeight);
|
|
96
|
+
const thumbTop = scrollTop / (scrollHeight - clientHeight) * (trackHeight - thumbHeight);
|
|
97
|
+
thumbEl.style.height = `${thumbHeight}px`;
|
|
98
|
+
thumbEl.style.transform = `translateY(${thumbTop}px)`;
|
|
99
|
+
};
|
|
100
|
+
scrollEl.addEventListener('scroll', update, {
|
|
101
|
+
passive: true
|
|
102
|
+
});
|
|
103
|
+
const observer = new ResizeObserver(update);
|
|
104
|
+
observer.observe(scrollEl);
|
|
105
|
+
if (scrollAreaRef.current) observer.observe(scrollAreaRef.current);
|
|
106
|
+
update();
|
|
107
|
+
return () => {
|
|
108
|
+
scrollEl.removeEventListener('scroll', update);
|
|
109
|
+
observer.disconnect();
|
|
110
|
+
};
|
|
111
|
+
}, [enabled, scrollContainerRef, scrollAreaRef, thumbRef]);
|
|
112
|
+
const handleThumbMouseDown = e => {
|
|
113
|
+
const scrollEl = scrollContainerRef.current;
|
|
114
|
+
const thumbEl = thumbRef.current;
|
|
115
|
+
const areaEl = scrollAreaRef.current;
|
|
116
|
+
if (!scrollEl || !thumbEl) return;
|
|
117
|
+
startDrag(e, {
|
|
118
|
+
axis: 'y',
|
|
119
|
+
scrollEl,
|
|
120
|
+
thumbEl,
|
|
121
|
+
draggingTarget: areaEl ?? scrollEl
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
handleThumbMouseDown
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
exports.useTableVerticalScrollbar = useTableVerticalScrollbar;
|
|
129
|
+
const useTableHorizontalScrollbar = _ref2 => {
|
|
130
|
+
let {
|
|
131
|
+
enabled,
|
|
132
|
+
hScrollContainerRef,
|
|
133
|
+
hScrollbarRef,
|
|
134
|
+
hThumbRef
|
|
135
|
+
} = _ref2;
|
|
136
|
+
(0, _react.useEffect)(() => {
|
|
137
|
+
if (!enabled) return;
|
|
138
|
+
const hScrollEl = hScrollContainerRef.current;
|
|
139
|
+
const hScrollbarEl = hScrollbarRef.current;
|
|
140
|
+
const hThumbEl = hThumbRef.current;
|
|
141
|
+
if (!hScrollEl || !hScrollbarEl || !hThumbEl) return;
|
|
142
|
+
const update = () => {
|
|
143
|
+
const {
|
|
144
|
+
scrollLeft,
|
|
145
|
+
scrollWidth,
|
|
146
|
+
clientWidth
|
|
147
|
+
} = hScrollEl;
|
|
148
|
+
if (scrollWidth <= clientWidth) {
|
|
149
|
+
hThumbEl.style.width = '0';
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// transform으로 스크롤 오프셋 보정 — reflow 없이 compositor-only 이동
|
|
153
|
+
hScrollbarEl.style.transform = `translateX(${scrollLeft}px)`;
|
|
154
|
+
hScrollbarEl.style.width = `${clientWidth - H_SCROLLBAR_SIDE_GAP * 2}px`;
|
|
155
|
+
const trackWidth = clientWidth - H_SCROLLBAR_SIDE_GAP * 2;
|
|
156
|
+
const thumbWidth = Math.max(H_SCROLLBAR_THUMB_MIN_WIDTH, clientWidth / scrollWidth * trackWidth);
|
|
157
|
+
const thumbLeft = scrollLeft / (scrollWidth - clientWidth) * (trackWidth - thumbWidth);
|
|
158
|
+
hThumbEl.style.width = `${thumbWidth}px`;
|
|
159
|
+
hThumbEl.style.transform = `translateX(${thumbLeft}px)`;
|
|
160
|
+
};
|
|
161
|
+
hScrollEl.addEventListener('scroll', update, {
|
|
162
|
+
passive: true
|
|
163
|
+
});
|
|
164
|
+
const ro = new ResizeObserver(update);
|
|
165
|
+
ro.observe(hScrollEl);
|
|
166
|
+
update();
|
|
167
|
+
return () => {
|
|
168
|
+
hScrollEl.removeEventListener('scroll', update);
|
|
169
|
+
ro.disconnect();
|
|
170
|
+
};
|
|
171
|
+
}, [enabled, hScrollContainerRef, hScrollbarRef, hThumbRef]);
|
|
172
|
+
const handleHThumbMouseDown = e => {
|
|
173
|
+
const hScrollEl = hScrollContainerRef.current;
|
|
174
|
+
const hThumbEl = hThumbRef.current;
|
|
175
|
+
if (!hScrollEl || !hThumbEl) return;
|
|
176
|
+
startDrag(e, {
|
|
177
|
+
axis: 'x',
|
|
178
|
+
scrollEl: hScrollEl,
|
|
179
|
+
thumbEl: hThumbEl,
|
|
180
|
+
sideGap: H_SCROLLBAR_SIDE_GAP
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
handleHThumbMouseDown
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
exports.useTableHorizontalScrollbar = useTableHorizontalScrollbar;
|
|
@@ -17,13 +17,6 @@ var _HintText = require("../../shared/hintText/HintText");
|
|
|
17
17
|
var _InputBase = require("../input-base/InputBase");
|
|
18
18
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
19
|
const defaultMaxHeight = exports.defaultMaxHeight = 275;
|
|
20
|
-
const toggleMultiSelectValue = (currentValue, optionId) => {
|
|
21
|
-
const currentValues = Array.isArray(currentValue) ? currentValue : [];
|
|
22
|
-
if (currentValues.includes(optionId)) {
|
|
23
|
-
return currentValues.filter(v => v !== optionId);
|
|
24
|
-
}
|
|
25
|
-
return [...currentValues, optionId];
|
|
26
|
-
};
|
|
27
20
|
const notifyFormChange = (register, multiple, newValue) => {
|
|
28
21
|
if (register?.onChange) {
|
|
29
22
|
register.onChange({
|
|
@@ -55,6 +48,7 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
55
48
|
required = false,
|
|
56
49
|
multiple = false,
|
|
57
50
|
showFooterButtons = false,
|
|
51
|
+
maxSelection,
|
|
58
52
|
onEdit,
|
|
59
53
|
...props
|
|
60
54
|
} = _ref;
|
|
@@ -67,7 +61,8 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
67
61
|
const handleOptionSelect = option => {
|
|
68
62
|
if (disabled) return;
|
|
69
63
|
if (multiple) {
|
|
70
|
-
const newValue =
|
|
64
|
+
const newValue = tryToggle(option.id, Array.isArray(value) ? value : []);
|
|
65
|
+
if (newValue === null) return;
|
|
71
66
|
onChange?.(newValue);
|
|
72
67
|
notifyFormChange(register, multiple, newValue);
|
|
73
68
|
return;
|
|
@@ -144,6 +139,7 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
144
139
|
// 나머지는 useDropdown 훅에서 처리
|
|
145
140
|
dropdownHandleKeyDown(e);
|
|
146
141
|
};
|
|
142
|
+
// biome-ignore lint/style/noNonNullAssertion: forwardRef 패턴에서 internalRef는 첫 렌더 후 항상 존재
|
|
147
143
|
(0, _react.useImperativeHandle)(ref, () => internalRef.current, []);
|
|
148
144
|
const trailingElement = {
|
|
149
145
|
type: 'custom',
|
|
@@ -173,8 +169,12 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
173
169
|
buttonText: selectAllButtonText,
|
|
174
170
|
toggleSelectAll,
|
|
175
171
|
getSelectedTagsData,
|
|
176
|
-
removeTag
|
|
177
|
-
|
|
172
|
+
removeTag,
|
|
173
|
+
isMaxSelectionActive,
|
|
174
|
+
tryToggle
|
|
175
|
+
} = (0, _multiSelect.useMultiSelect)(currentSelectedValues, optionItems, {
|
|
176
|
+
maxSelection
|
|
177
|
+
});
|
|
178
178
|
const handleSelectAll = () => {
|
|
179
179
|
if (!multiple || !onChange) return;
|
|
180
180
|
const newSelectedValues = toggleSelectAll();
|
|
@@ -260,6 +260,7 @@ const ComboBox = exports.ComboBox = /*#__PURE__*/(0, _react.forwardRef)((_ref, r
|
|
|
260
260
|
multiple: multiple,
|
|
261
261
|
showFooterButtons: showFooter,
|
|
262
262
|
selectAllButtonText: selectAllButtonText,
|
|
263
|
+
showSelectAllAction: !isMaxSelectionActive,
|
|
263
264
|
onSelectAll: handleSelectAll,
|
|
264
265
|
onEdit: handleEdit,
|
|
265
266
|
onComplete: handleComplete,
|
|
@@ -139,9 +139,12 @@ const ImageFileInput = exports.ImageFileInput = /*#__PURE__*/(0, _react.forwardR
|
|
|
139
139
|
onClick: handleBrowseClick,
|
|
140
140
|
disabled: disabled,
|
|
141
141
|
label: imagePreviewTooltipLabel
|
|
142
|
-
}),
|
|
142
|
+
}), (0, _jsxRuntime.jsx)(_tooltip.Tooltip, {
|
|
143
143
|
content: imagePreviewTooltipLabel,
|
|
144
|
-
position: "bottom"
|
|
144
|
+
position: "bottom",
|
|
145
|
+
tooltipType: "black",
|
|
146
|
+
forceVisible: isButtonHovered && !disabled,
|
|
147
|
+
disablePortal: true
|
|
145
148
|
})]
|
|
146
149
|
})]
|
|
147
150
|
});
|