@ncds/ui-admin 1.1.3 → 1.2.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.
Files changed (52) hide show
  1. package/dist/cjs/index.js +11 -0
  2. package/dist/cjs/src/components/badge/utils.js +2 -2
  3. package/dist/cjs/src/components/breadcrumb/BreadCrumb.js +2 -2
  4. package/dist/cjs/src/components/button/Button.js +2 -2
  5. package/dist/cjs/src/components/button/ButtonCloseX.js +2 -2
  6. package/dist/cjs/src/components/button/ButtonGroup.js +2 -2
  7. package/dist/cjs/src/components/carousel/CarouselArrow.js +2 -2
  8. package/dist/cjs/src/components/dropdown/Dropdown.js +4 -4
  9. package/dist/cjs/src/components/featured-icon/FeaturedIcon.js +2 -2
  10. package/dist/cjs/src/components/input/FileInput.js +222 -0
  11. package/dist/cjs/src/components/input/InputBase.js +6 -6
  12. package/dist/cjs/src/components/input/PasswordInput.js +17 -25
  13. package/dist/cjs/src/components/input/index.js +11 -0
  14. package/dist/cjs/src/components/notification/FullWidthNotification.js +3 -3
  15. package/dist/cjs/src/components/select/Select.js +2 -2
  16. package/dist/cjs/src/components/tag/Tag.js +3 -3
  17. package/dist/cjs/src/hooks/index.js +26 -0
  18. package/dist/cjs/src/hooks/useCallbackRef.js +49 -0
  19. package/dist/cjs/src/hooks/useMergeRefs.js +36 -0
  20. package/dist/esm/index.js +2 -1
  21. package/dist/esm/src/components/badge/utils.js +1 -1
  22. package/dist/esm/src/components/breadcrumb/BreadCrumb.js +1 -1
  23. package/dist/esm/src/components/button/Button.js +1 -1
  24. package/dist/esm/src/components/button/ButtonCloseX.js +1 -1
  25. package/dist/esm/src/components/button/ButtonGroup.js +1 -1
  26. package/dist/esm/src/components/carousel/CarouselArrow.js +1 -1
  27. package/dist/esm/src/components/dropdown/Dropdown.js +1 -1
  28. package/dist/esm/src/components/featured-icon/FeaturedIcon.js +1 -1
  29. package/dist/esm/src/components/input/FileInput.js +215 -0
  30. package/dist/esm/src/components/input/InputBase.js +1 -1
  31. package/dist/esm/src/components/input/PasswordInput.js +17 -25
  32. package/dist/esm/src/components/input/index.js +2 -1
  33. package/dist/esm/src/components/notification/FullWidthNotification.js +1 -1
  34. package/dist/esm/src/components/select/Select.js +1 -1
  35. package/dist/esm/src/components/tag/Tag.js +1 -1
  36. package/dist/esm/src/hooks/index.js +3 -0
  37. package/dist/esm/src/hooks/useCallbackRef.js +43 -0
  38. package/dist/esm/src/hooks/useMergeRefs.js +30 -0
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/types/src/components/dropdown/Dropdown.d.ts +1 -1
  41. package/dist/types/src/components/featured-icon/FeaturedIcon.d.ts +1 -1
  42. package/dist/types/src/components/input/FileInput.d.ts +62 -0
  43. package/dist/types/src/components/input/InputBase.d.ts +1 -1
  44. package/dist/types/src/components/input/index.d.ts +1 -0
  45. package/dist/types/src/components/modal/Modal.d.ts +1 -1
  46. package/dist/types/src/components/notification/Notification.d.ts +1 -1
  47. package/dist/types/src/components/select/Select.d.ts +1 -1
  48. package/dist/types/src/hooks/index.d.ts +4 -0
  49. package/dist/types/src/hooks/useCallbackRef.d.ts +28 -0
  50. package/dist/types/src/hooks/useMergeRefs.d.ts +21 -0
  51. package/dist/ui-admin/assets/styles/style.css +54 -0
  52. package/package.json +2 -2
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCallbackRef = useCallbackRef;
7
+ var _react = require("react");
8
+ /**
9
+ * A callback ref hook that supports cleanup functions.
10
+ * This is useful when you need to perform setup/cleanup operations when the ref changes.
11
+ *
12
+ * @param callback - Function that receives the node and optionally returns a cleanup function
13
+ * @returns A callback ref
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * const MyComponent = () => {
18
+ * const ref = useCallbackRef<HTMLInputElement>((node) => {
19
+ * if (node) {
20
+ * const handleInput = () => console.log('input changed');
21
+ * node.addEventListener('input', handleInput);
22
+ *
23
+ * // Return cleanup function
24
+ * return () => {
25
+ * node.removeEventListener('input', handleInput);
26
+ * };
27
+ * }
28
+ * });
29
+ *
30
+ * return <input ref={ref} />;
31
+ * };
32
+ * ```
33
+ */
34
+ function useCallbackRef(callback) {
35
+ var cleanupRef = (0, _react.useRef)();
36
+ return (0, _react.useCallback)(function (node) {
37
+ // Cleanup previous ref
38
+ if (cleanupRef.current) {
39
+ cleanupRef.current();
40
+ cleanupRef.current = undefined;
41
+ }
42
+ // Set up new ref
43
+ if (node) {
44
+ cleanupRef.current = callback(node);
45
+ } else {
46
+ callback(null);
47
+ }
48
+ }, [callback]);
49
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useMergeRefs = useMergeRefs;
7
+ /**
8
+ * Merges multiple refs into a single callback ref.
9
+ * This is useful when you need to forward a ref while also keeping an internal ref.
10
+ *
11
+ * @param refs - Array of refs to merge
12
+ * @returns A callback ref that will update all provided refs
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const MyComponent = forwardRef<HTMLInputElement, Props>((props, ref) => {
17
+ * const internalRef = useRef<HTMLInputElement>(null);
18
+ * const mergedRef = useMergeRefs([ref, internalRef]);
19
+ *
20
+ * return <input ref={mergedRef} />;
21
+ * });
22
+ * ```
23
+ */
24
+ function useMergeRefs(refs) {
25
+ return function (node) {
26
+ refs.forEach(function (ref) {
27
+ if (ref) {
28
+ if (typeof ref === 'function') {
29
+ ref(node);
30
+ } else {
31
+ ref.current = node;
32
+ }
33
+ }
34
+ });
35
+ };
36
+ }
package/dist/esm/index.js CHANGED
@@ -25,4 +25,5 @@ export * from './src/components/tab';
25
25
  export * from './src/components/tag';
26
26
  export * from './src/components/toggle';
27
27
  export * from './src/components/tooltip';
28
- export * from './src/components';
28
+ export * from './src/components';
29
+ export * from './src/hooks';
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import Icon from '@ncds/ui-admin-icon';
2
+ import Icon from '@ncds/ui-admin-icon/dynamic';
3
3
  import { COLOR } from '../../../constant/color';
4
4
  import { Dot } from '../dot/Dot';
5
5
  var DEFAULT_DOT_COLOR = 'neutral';
@@ -9,7 +9,7 @@ var __assign = this && this.__assign || function () {
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
- import Icon from '@ncds/ui-admin-icon';
12
+ import Icon from '@ncds/ui-admin-icon/dynamic';
13
13
  import classNames from 'classnames';
14
14
  var BreadcrumbItem = function (_a) {
15
15
  var href = _a.href,
@@ -18,8 +18,8 @@ var __rest = this && this.__rest || function (s, e) {
18
18
  };
19
19
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
20
20
  import { createElement, forwardRef, useEffect, useState } from 'react';
21
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
22
  import classnames from 'classnames';
22
- import Icon from '@ncds/ui-admin-icon';
23
23
  import { COLOR } from '../../../constant/color';
24
24
  import { Dot } from '../dot';
25
25
  export var svgSize = {
@@ -9,7 +9,7 @@ var __assign = this && this.__assign || function () {
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
- import Icon from '@ncds/ui-admin-icon';
12
+ import Icon from '@ncds/ui-admin-icon/dynamic';
13
13
  import classnames from 'classnames';
14
14
  var svgSize = {
15
15
  xs: 16,
@@ -17,7 +17,7 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
20
- import Icon from '@ncds/ui-admin-icon';
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
21
  import classNames from 'classnames';
22
22
  import React, { createElement } from 'react';
23
23
  import { COLOR } from '../../../constant/color';
@@ -10,7 +10,7 @@ var __assign = this && this.__assign || function () {
10
10
  };
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  import classNames from 'classnames';
13
- import Icon from '@ncds/ui-admin-icon';
13
+ import Icon from '@ncds/ui-admin-icon/dynamic';
14
14
  export var CarouselArrow = function (_a) {
15
15
  var _b;
16
16
  var _c = _a.type,
@@ -9,7 +9,7 @@ var __assign = this && this.__assign || function () {
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
- import Icon from '@ncds/ui-admin-icon';
12
+ import Icon from '@ncds/ui-admin-icon/dynamic';
13
13
  import { useEffect, useRef, useState } from 'react';
14
14
  export var Dropdown = function (_a) {
15
15
  var trigger = _a.trigger,
@@ -17,7 +17,7 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
20
- import Icon from '@ncds/ui-admin-icon';
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
21
  import classNames from 'classnames';
22
22
  import { forwardRef } from 'react';
23
23
  var iconSizeMap = {
@@ -0,0 +1,215 @@
1
+ var __assign = this && this.__assign || function () {
2
+ __assign = Object.assign || function (t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6
+ }
7
+ return t;
8
+ };
9
+ return __assign.apply(this, arguments);
10
+ };
11
+ var __rest = this && this.__rest || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
15
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
16
+ }
17
+ return t;
18
+ };
19
+ var __spreadArray = this && this.__spreadArray || function (to, from, pack) {
20
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
21
+ if (ar || !(i in from)) {
22
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
23
+ ar[i] = from[i];
24
+ }
25
+ }
26
+ return to.concat(ar || Array.prototype.slice.call(from));
27
+ };
28
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
+ import { forwardRef, useState, useRef, useEffect } from 'react';
30
+ import classNames from 'classnames';
31
+ import Icon from '@ncds/ui-admin-icon/dynamic';
32
+ import { Tag } from '../tag/Tag';
33
+ import { Button } from '../button';
34
+ import { HintText, Label } from '../shared';
35
+ export var FileInputErrorType;
36
+ (function (FileInputErrorType) {
37
+ FileInputErrorType["ALREADY_UPLOADED"] = "ALREADY_UPLOADED";
38
+ FileInputErrorType["EXCEED_MAX_FILE_SIZE"] = "EXCEED_MAX_FILE_SIZE";
39
+ FileInputErrorType["EXCEED_MAX_FILE_COUNT"] = "EXCEED_MAX_FILE_COUNT";
40
+ })(FileInputErrorType || (FileInputErrorType = {}));
41
+ export var FileInput = /*#__PURE__*/forwardRef(function (_a, ref) {
42
+ var _b = _a.size,
43
+ size = _b === void 0 ? 'xs' : _b,
44
+ accept = _a.accept,
45
+ _c = _a.multiple,
46
+ multiple = _c === void 0 ? false : _c,
47
+ maxFileSize = _a.maxFileSize,
48
+ maxFileCount = _a.maxFileCount,
49
+ value = _a.value,
50
+ onChange = _a.onChange,
51
+ onFileSelect = _a.onFileSelect,
52
+ onFail = _a.onFail,
53
+ _d = _a.buttonLabel,
54
+ buttonLabel = _d === void 0 ? '파일 찾기' : _d,
55
+ disabled = _a.disabled,
56
+ label = _a.label,
57
+ hintItems = _a.hintItems,
58
+ validation = _a.validation,
59
+ destructive = _a.destructive,
60
+ isRequired = _a.isRequired,
61
+ showHelpIcon = _a.showHelpIcon,
62
+ hintText = _a.hintText,
63
+ props = __rest(_a, ["size", "accept", "multiple", "maxFileSize", "maxFileCount", "value", "onChange", "onFileSelect", "onFail", "buttonLabel", "disabled", "label", "hintItems", "validation", "destructive", "isRequired", "showHelpIcon", "hintText"]);
64
+ var fileInputRef = useRef(null);
65
+ var _e = useState([]),
66
+ internalFiles = _e[0],
67
+ setInternalFiles = _e[1];
68
+ // Determine if component is controlled or uncontrolled
69
+ var isControlled = value !== undefined;
70
+ var files = isControlled ? value : internalFiles;
71
+ // Sync internal state with controlled value
72
+ useEffect(function () {
73
+ if (isControlled && value) {
74
+ setInternalFiles(value);
75
+ }
76
+ }, [isControlled, value]);
77
+ var updateFiles = function (newFiles) {
78
+ if (isControlled) {
79
+ onChange === null || onChange === void 0 ? void 0 : onChange(newFiles);
80
+ } else {
81
+ setInternalFiles(newFiles);
82
+ onFileSelect === null || onFileSelect === void 0 ? void 0 : onFileSelect(newFiles);
83
+ }
84
+ };
85
+ var handleFileChange = function (event) {
86
+ var selectedFiles = event.target.files;
87
+ if (!selectedFiles || selectedFiles.length === 0) return;
88
+ var _a = validateFiles(Array.from(selectedFiles)),
89
+ validFiles = _a.validFiles,
90
+ invalidFiles = _a.invalidFiles;
91
+ var nextFiles = __spreadArray(__spreadArray([], files, true), validFiles, true);
92
+ updateFiles(nextFiles);
93
+ if (onFail && invalidFiles.length > 0) {
94
+ onFail(invalidFiles);
95
+ }
96
+ };
97
+ var validateFiles = function (fileList) {
98
+ var validFiles = [];
99
+ var invalidFiles = [];
100
+ var _loop_1 = function (file) {
101
+ if (files.some(function (f) {
102
+ return f.name === file.name && f.size === file.size;
103
+ })) {
104
+ invalidFiles.push(__assign(__assign({}, file), {
105
+ errorType: FileInputErrorType.ALREADY_UPLOADED
106
+ }));
107
+ return "continue";
108
+ }
109
+ if (!!maxFileSize && file.size > maxFileSize) {
110
+ invalidFiles.push(__assign(__assign({}, file), {
111
+ errorType: FileInputErrorType.EXCEED_MAX_FILE_SIZE
112
+ }));
113
+ return "continue";
114
+ }
115
+ if (!!maxFileCount && files.length + validFiles.length >= maxFileCount) {
116
+ invalidFiles.push(__assign(__assign({}, file), {
117
+ errorType: FileInputErrorType.EXCEED_MAX_FILE_COUNT
118
+ }));
119
+ return "continue";
120
+ }
121
+ validFiles.push(file);
122
+ };
123
+ for (var _i = 0, fileList_1 = fileList; _i < fileList_1.length; _i++) {
124
+ var file = fileList_1[_i];
125
+ _loop_1(file);
126
+ }
127
+ return {
128
+ validFiles: validFiles,
129
+ invalidFiles: invalidFiles
130
+ };
131
+ };
132
+ var handleBrowseClick = function () {
133
+ if (fileInputRef.current && !disabled) {
134
+ fileInputRef.current.click();
135
+ }
136
+ };
137
+ var handleRemoveFile = function (index) {
138
+ var newFiles = __spreadArray([], files, true);
139
+ newFiles.splice(index, 1);
140
+ updateFiles(newFiles);
141
+ };
142
+ var renderFileTagList = function () {
143
+ if (files.length === 0) return null;
144
+ return _jsx("div", __assign({
145
+ className: "ncua-file-input__file-tags"
146
+ }, {
147
+ children: files.map(function (file, index) {
148
+ return _jsx(Tag, {
149
+ text: file.name,
150
+ size: size === 'xs' ? 'sm' : 'md',
151
+ close: true,
152
+ onButtonClick: function () {
153
+ return handleRemoveFile(index);
154
+ }
155
+ }, "".concat(file.name, "-").concat(index));
156
+ })
157
+ }));
158
+ };
159
+ var renderHintList = function () {
160
+ if (!hintItems || hintItems.length === 0) return null;
161
+ return _jsx("ul", __assign({
162
+ className: "ncua-file-input__hint-list"
163
+ }, {
164
+ children: hintItems.map(function (hint, index) {
165
+ return _jsx("li", __assign({
166
+ className: "ncua-file-input__hint-item"
167
+ }, {
168
+ children: hint
169
+ }), index);
170
+ })
171
+ }));
172
+ };
173
+ return _jsxs("div", __assign({
174
+ className: classNames('ncua-file-input', "ncua-file-input--".concat(size))
175
+ }, {
176
+ children: [_jsx("input", __assign({
177
+ hidden: true,
178
+ ref: fileInputRef,
179
+ type: "file",
180
+ accept: accept,
181
+ multiple: multiple,
182
+ onChange: handleFileChange,
183
+ tabIndex: -1,
184
+ "aria-hidden": "true"
185
+ }, props)), _jsxs("div", __assign({
186
+ className: "ncua-file-input__input-container"
187
+ }, {
188
+ children: [_jsxs("div", __assign({
189
+ className: "ncua-file-input__label"
190
+ }, {
191
+ children: [_jsx(Label, __assign({
192
+ isRequired: isRequired
193
+ }, {
194
+ children: label
195
+ })), showHelpIcon && _jsx(Icon, {
196
+ className: "ncua-input__help-icon",
197
+ name: "help-circle"
198
+ })]
199
+ })), _jsx(Button, {
200
+ size: size,
201
+ onClick: handleBrowseClick,
202
+ disabled: disabled,
203
+ leadingIcon: {
204
+ type: 'icon',
205
+ icon: 'upload-cloud-02'
206
+ },
207
+ label: buttonLabel
208
+ }), hintText && _jsx(HintText, __assign({
209
+ destructive: destructive
210
+ }, {
211
+ children: hintText
212
+ }))]
213
+ })), renderHintList(), renderFileTagList()]
214
+ }));
215
+ });
@@ -17,7 +17,7 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
- import Icon from '@ncds/ui-admin-icon';
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
21
  import classNames from 'classnames';
22
22
  import { forwardRef } from 'react';
23
23
  import { COLOR } from '../../../constant/color';
@@ -17,10 +17,11 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx } from "react/jsx-runtime";
20
+ import { forwardRef, useState } from 'react';
21
+ import { InputBase } from './InputBase';
20
22
  import { Eye, EyeOff } from '@ncds/ui-admin-icon';
21
23
  import classNames from 'classnames';
22
- import { forwardRef, useEffect, useRef, useState } from 'react';
23
- import { InputBase } from './InputBase';
24
+ import { useMergeRefs, useCallbackRef } from '../../hooks';
24
25
  var svgSize = {
25
26
  xs: 14,
26
27
  sm: 20
@@ -29,13 +30,25 @@ export var PasswordInput = /*#__PURE__*/forwardRef(function (_a, ref) {
29
30
  var _b = _a.size,
30
31
  size = _b === void 0 ? 'xs' : _b,
31
32
  props = __rest(_a, ["size"]);
32
- var inputRef = useRef(null);
33
33
  var _c = useState(false),
34
34
  isVisible = _c[0],
35
35
  setIsVisible = _c[1];
36
36
  var _d = useState(false),
37
37
  hasContent = _d[0],
38
38
  setHasContent = _d[1];
39
+ var callbackRef = useCallbackRef(function (node) {
40
+ if (node) {
41
+ setHasContent(!!node.value);
42
+ var handleInput_1 = function () {
43
+ setHasContent(!!node.value);
44
+ };
45
+ node.addEventListener('input', handleInput_1);
46
+ return function () {
47
+ node.removeEventListener('input', handleInput_1);
48
+ };
49
+ }
50
+ });
51
+ var mergedRef = useMergeRefs([ref, callbackRef]);
39
52
  var svgProps = {
40
53
  width: svgSize[size],
41
54
  height: svgSize[size]
@@ -43,29 +56,8 @@ export var PasswordInput = /*#__PURE__*/forwardRef(function (_a, ref) {
43
56
  var handleVisibilityChange = function () {
44
57
  setIsVisible(!isVisible);
45
58
  };
46
- useEffect(function () {
47
- if (inputRef.current) {
48
- setHasContent(!!inputRef.current.value);
49
- var handleInput_1 = function () {
50
- var _a;
51
- setHasContent(!!((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value));
52
- };
53
- inputRef.current.addEventListener('input', handleInput_1);
54
- return function () {
55
- var _a;
56
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('input', handleInput_1);
57
- };
58
- }
59
- }, []);
60
59
  return _jsx(InputBase, __assign({
61
- ref: function (node) {
62
- if (typeof ref === 'function') {
63
- ref(node);
64
- } else if (ref) {
65
- ref.current = node;
66
- }
67
- inputRef.current = node;
68
- },
60
+ ref: mergedRef,
69
61
  size: size,
70
62
  type: isVisible ? 'text' : 'password',
71
63
  leadingElement: {
@@ -1,3 +1,4 @@
1
1
  export * from './InputBase';
2
2
  export * from './PasswordInput';
3
- export * from './Textarea';
3
+ export * from './Textarea';
4
+ export * from './FileInput';
@@ -17,7 +17,7 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
- import Icon from '@ncds/ui-admin-icon';
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
21
  import classNames from 'classnames';
22
22
  import { forwardRef } from 'react';
23
23
  import { COLOR } from '../../../constant/color';
@@ -17,7 +17,7 @@ var __rest = this && this.__rest || function (s, e) {
17
17
  return t;
18
18
  };
19
19
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
20
- import Icon from '@ncds/ui-admin-icon';
20
+ import Icon from '@ncds/ui-admin-icon/dynamic';
21
21
  import classNames from 'classnames';
22
22
  import { forwardRef } from 'react';
23
23
  import { HintText } from '../shared/hintText/HintText';
@@ -9,7 +9,7 @@ var __assign = this && this.__assign || function () {
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
- import Icon from '@ncds/ui-admin-icon';
12
+ import Icon from '@ncds/ui-admin-icon/dynamic';
13
13
  import classNames from 'classnames';
14
14
  import { COLOR } from '../../../constant/color';
15
15
  import { Dot } from '../dot';
@@ -0,0 +1,3 @@
1
+ export { useMediaQuery } from './useMediaQuery';
2
+ export { useMergeRefs } from './useMergeRefs';
3
+ export { useCallbackRef } from './useCallbackRef';
@@ -0,0 +1,43 @@
1
+ import { useCallback, useRef } from 'react';
2
+ /**
3
+ * A callback ref hook that supports cleanup functions.
4
+ * This is useful when you need to perform setup/cleanup operations when the ref changes.
5
+ *
6
+ * @param callback - Function that receives the node and optionally returns a cleanup function
7
+ * @returns A callback ref
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const MyComponent = () => {
12
+ * const ref = useCallbackRef<HTMLInputElement>((node) => {
13
+ * if (node) {
14
+ * const handleInput = () => console.log('input changed');
15
+ * node.addEventListener('input', handleInput);
16
+ *
17
+ * // Return cleanup function
18
+ * return () => {
19
+ * node.removeEventListener('input', handleInput);
20
+ * };
21
+ * }
22
+ * });
23
+ *
24
+ * return <input ref={ref} />;
25
+ * };
26
+ * ```
27
+ */
28
+ export function useCallbackRef(callback) {
29
+ var cleanupRef = useRef();
30
+ return useCallback(function (node) {
31
+ // Cleanup previous ref
32
+ if (cleanupRef.current) {
33
+ cleanupRef.current();
34
+ cleanupRef.current = undefined;
35
+ }
36
+ // Set up new ref
37
+ if (node) {
38
+ cleanupRef.current = callback(node);
39
+ } else {
40
+ callback(null);
41
+ }
42
+ }, [callback]);
43
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Merges multiple refs into a single callback ref.
3
+ * This is useful when you need to forward a ref while also keeping an internal ref.
4
+ *
5
+ * @param refs - Array of refs to merge
6
+ * @returns A callback ref that will update all provided refs
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const MyComponent = forwardRef<HTMLInputElement, Props>((props, ref) => {
11
+ * const internalRef = useRef<HTMLInputElement>(null);
12
+ * const mergedRef = useMergeRefs([ref, internalRef]);
13
+ *
14
+ * return <input ref={mergedRef} />;
15
+ * });
16
+ * ```
17
+ */
18
+ export function useMergeRefs(refs) {
19
+ return function (node) {
20
+ refs.forEach(function (ref) {
21
+ if (ref) {
22
+ if (typeof ref === 'function') {
23
+ ref(node);
24
+ } else {
25
+ ref.current = node;
26
+ }
27
+ }
28
+ });
29
+ };
30
+ }
@@ -26,4 +26,5 @@ export * from './src/components/tag';
26
26
  export * from './src/components/toggle';
27
27
  export * from './src/components/tooltip';
28
28
  export * from './src/components';
29
+ export * from './src/hooks';
29
30
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- import { IconName } from '@ncds/ui-admin-icon';
1
+ import { type IconName } from '@ncds/ui-admin-icon/dynamic';
2
2
  export type AvatarTrigger = {
3
3
  type: 'avatar';
4
4
  avatar: string;
@@ -1,4 +1,4 @@
1
- import { IconName } from '@ncds/ui-admin-icon';
1
+ import { type IconName } from '@ncds/ui-admin-icon/dynamic';
2
2
  import { ComponentPropsWithoutRef } from 'react';
3
3
  export type FeaturedIconTheme = 'light-circle' | 'dark-circle' | 'outline-circle' | 'square-outline';
4
4
  export type FeaturedIconColor = 'neutral' | 'error' | 'warning' | 'success';
@@ -0,0 +1,62 @@
1
+ import { InputBaseProps } from './InputBase';
2
+ export declare enum FileInputErrorType {
3
+ ALREADY_UPLOADED = "ALREADY_UPLOADED",
4
+ EXCEED_MAX_FILE_SIZE = "EXCEED_MAX_FILE_SIZE",
5
+ EXCEED_MAX_FILE_COUNT = "EXCEED_MAX_FILE_COUNT"
6
+ }
7
+ export interface InvalidFile extends Omit<File, 'constructor'> {
8
+ errorType: FileInputErrorType;
9
+ }
10
+ export interface FileInputProps extends Omit<InputBaseProps, 'clearText' | 'onClearText' | 'hintText' | 'value' | 'onChange'> {
11
+ /**
12
+ * Accepted file types
13
+ * e.g. '.jpg,.png,.pdf' or 'image/*'
14
+ */
15
+ accept?: string;
16
+ /**
17
+ * Maximum number of files
18
+ */
19
+ maxFileCount?: number;
20
+ /**
21
+ * Maximum file size in bytes
22
+ */
23
+ maxFileSize?: number;
24
+ /**
25
+ * Current files (controlled mode)
26
+ */
27
+ value?: File[];
28
+ /**
29
+ * Callback when files change (controlled mode)
30
+ */
31
+ onChange?: (files: File[]) => void;
32
+ /**
33
+ * Callback when files are selected (uncontrolled mode)
34
+ */
35
+ onFileSelect?: (files: File[]) => void;
36
+ /**
37
+ * Callback when file selection fails
38
+ */
39
+ onFail?: (files: InvalidFile[]) => void;
40
+ /**
41
+ * Label shown on the button
42
+ */
43
+ buttonLabel?: string;
44
+ /**
45
+ * Hint text items to display as a list
46
+ */
47
+ hintItems?: string[];
48
+ /**
49
+ * Whether the input is required
50
+ */
51
+ isRequired?: boolean;
52
+ /**
53
+ * Whether to show the help icon
54
+ */
55
+ showHelpIcon?: boolean;
56
+ /**
57
+ * Hint text to display
58
+ */
59
+ hintText?: string;
60
+ }
61
+ export declare const FileInput: import("react").ForwardRefExoticComponent<FileInputProps & import("react").RefAttributes<HTMLInputElement>>;
62
+ //# sourceMappingURL=FileInput.d.ts.map