@bigtablet/design-system 2.0.7 → 2.1.0
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/index.css +64 -0
- package/dist/index.d.ts +32 -1
- package/dist/index.js +100 -1
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -1205,6 +1205,70 @@
|
|
|
1205
1205
|
pointer-events: none;
|
|
1206
1206
|
}
|
|
1207
1207
|
|
|
1208
|
+
/* src/ui/otp-input/style.scss */
|
|
1209
|
+
@keyframes skeleton_loading {
|
|
1210
|
+
0% {
|
|
1211
|
+
background-position: 100% 0;
|
|
1212
|
+
}
|
|
1213
|
+
100% {
|
|
1214
|
+
background-position: 0 0;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
.otp_input {
|
|
1218
|
+
display: inline-flex;
|
|
1219
|
+
flex-direction: column;
|
|
1220
|
+
align-items: flex-start;
|
|
1221
|
+
}
|
|
1222
|
+
.otp_input_boxes {
|
|
1223
|
+
display: flex;
|
|
1224
|
+
gap: 6px;
|
|
1225
|
+
}
|
|
1226
|
+
.otp_input_box {
|
|
1227
|
+
width: 48px;
|
|
1228
|
+
min-height: 56px;
|
|
1229
|
+
padding: 4px;
|
|
1230
|
+
border: 1px solid #E5E5E5;
|
|
1231
|
+
border-radius: 12px;
|
|
1232
|
+
background: none;
|
|
1233
|
+
font-family: "Pretendard", sans-serif;
|
|
1234
|
+
font-size: 14px;
|
|
1235
|
+
font-weight: 400;
|
|
1236
|
+
line-height: 20px;
|
|
1237
|
+
color: #121212;
|
|
1238
|
+
text-align: center;
|
|
1239
|
+
outline: none;
|
|
1240
|
+
transition: border-color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
|
|
1241
|
+
}
|
|
1242
|
+
.otp_input_box:hover:not(:disabled):not(:focus) {
|
|
1243
|
+
border-color: #B3B3B3;
|
|
1244
|
+
}
|
|
1245
|
+
.otp_input_box:focus {
|
|
1246
|
+
border-color: #121212;
|
|
1247
|
+
border-width: 2px;
|
|
1248
|
+
padding: calc(4px - 1px);
|
|
1249
|
+
}
|
|
1250
|
+
.otp_input_box_disabled {
|
|
1251
|
+
cursor: not-allowed;
|
|
1252
|
+
color: #666666;
|
|
1253
|
+
}
|
|
1254
|
+
.otp_input_box_error {
|
|
1255
|
+
border-color: #EF4444;
|
|
1256
|
+
}
|
|
1257
|
+
.otp_input_box_error:focus {
|
|
1258
|
+
border-color: #EF4444;
|
|
1259
|
+
}
|
|
1260
|
+
.otp_input_supporting {
|
|
1261
|
+
padding-top: 4px;
|
|
1262
|
+
font-family: "Pretendard", sans-serif;
|
|
1263
|
+
font-size: 12px;
|
|
1264
|
+
font-weight: 400;
|
|
1265
|
+
line-height: 16px;
|
|
1266
|
+
color: #666666;
|
|
1267
|
+
}
|
|
1268
|
+
.otp_input_supporting_error {
|
|
1269
|
+
color: #EF4444;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1208
1272
|
/* src/ui/modal/style.scss */
|
|
1209
1273
|
@keyframes skeleton_loading {
|
|
1210
1274
|
0% {
|
package/dist/index.d.ts
CHANGED
|
@@ -748,6 +748,37 @@ interface ListItemProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "on
|
|
|
748
748
|
*/
|
|
749
749
|
declare const ListItem: ({ overline, label, supportingText, metadata, leadingElement, trailingElement, alignment, disabled, onClick, className, ...props }: ListItemProps) => react_jsx_runtime.JSX.Element;
|
|
750
750
|
|
|
751
|
+
interface OtpInputProps {
|
|
752
|
+
/** OTP 자릿수 (기본값: 6) */
|
|
753
|
+
length?: 4 | 6;
|
|
754
|
+
/** 제어형 값 */
|
|
755
|
+
value?: string;
|
|
756
|
+
/** 값 변경 콜백 */
|
|
757
|
+
onChange?: (value: string) => void;
|
|
758
|
+
/** 에러 상태 */
|
|
759
|
+
error?: boolean;
|
|
760
|
+
/** 비활성화 */
|
|
761
|
+
disabled?: boolean;
|
|
762
|
+
/** 하단 도움말 텍스트 */
|
|
763
|
+
supportingText?: string;
|
|
764
|
+
/** 첫 번째 입력에 자동 포커스 */
|
|
765
|
+
autoFocus?: boolean;
|
|
766
|
+
/** 접근성 레이블 */
|
|
767
|
+
ariaLabel?: string;
|
|
768
|
+
/** 추가 className */
|
|
769
|
+
className?: string;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* OTP 입력 컴포넌트를 렌더링한다.
|
|
773
|
+
* 각 자리를 개별 입력으로 분리하고, 자동 포커스 이동·붙여넣기를 지원한다.
|
|
774
|
+
* @param props OTP 입력 속성
|
|
775
|
+
* @returns 렌더링된 OTP 입력 요소
|
|
776
|
+
*/
|
|
777
|
+
declare const OtpInput: {
|
|
778
|
+
({ length, value, onChange, error, disabled, supportingText, autoFocus, ariaLabel, className, }: OtpInputProps): react_jsx_runtime.JSX.Element;
|
|
779
|
+
displayName: string;
|
|
780
|
+
};
|
|
781
|
+
|
|
751
782
|
interface ModalProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
752
783
|
/** 모달 열림 여부 */
|
|
753
784
|
open: boolean;
|
|
@@ -986,4 +1017,4 @@ interface TopLoadingProps {
|
|
|
986
1017
|
*/
|
|
987
1018
|
declare const TopLoading: ({ progress, color, height, isLoading, ariaLabel, }: TopLoadingProps) => react_jsx_runtime.JSX.Element | null;
|
|
988
1019
|
|
|
989
|
-
export { AlertProvider, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipType, DatePicker, type DatePickerProps, Divider, type DividerProps, FAB, type FABProps, type FABVariant, FileInput, type FileInputProps, Icon, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, type IconName, type IconProps, type IconWeight, LinearProgress, type LinearProgressProps, ListItem, type ListItemProps, Modal, type ModalProps, Pagination, type PaginationProps, Radio, type RadioProps, Select, type SelectOption, type SelectProps, Spinner, type SpinnerProps, TextField, type TextFieldProps, ToastProvider, Toggle, type ToggleProps, TopLoading, type TopLoadingProps, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useToast, zIndex };
|
|
1020
|
+
export { AlertProvider, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipType, DatePicker, type DatePickerProps, Divider, type DividerProps, FAB, type FABProps, type FABVariant, FileInput, type FileInputProps, Icon, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, type IconName, type IconProps, type IconWeight, LinearProgress, type LinearProgressProps, ListItem, type ListItemProps, Modal, type ModalProps, OtpInput, type OtpInputProps, Pagination, type PaginationProps, Radio, type RadioProps, Select, type SelectOption, type SelectProps, Spinner, type SpinnerProps, TextField, type TextFieldProps, ToastProvider, Toggle, type ToggleProps, TopLoading, type TopLoadingProps, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useToast, zIndex };
|
package/dist/index.js
CHANGED
|
@@ -1756,6 +1756,105 @@ var ListItem = ({
|
|
|
1756
1756
|
}
|
|
1757
1757
|
);
|
|
1758
1758
|
};
|
|
1759
|
+
var OtpInput = ({
|
|
1760
|
+
length = 6,
|
|
1761
|
+
value = "",
|
|
1762
|
+
onChange,
|
|
1763
|
+
error = false,
|
|
1764
|
+
disabled = false,
|
|
1765
|
+
supportingText,
|
|
1766
|
+
autoFocus = false,
|
|
1767
|
+
ariaLabel = "OTP \uC785\uB825",
|
|
1768
|
+
className
|
|
1769
|
+
}) => {
|
|
1770
|
+
const inputsRef = React5.useRef([]);
|
|
1771
|
+
const digits = React5.useMemo(() => {
|
|
1772
|
+
const arr = value.split("").slice(0, length);
|
|
1773
|
+
while (arr.length < length) arr.push("");
|
|
1774
|
+
return arr;
|
|
1775
|
+
}, [value, length]);
|
|
1776
|
+
const focusInput = (index) => {
|
|
1777
|
+
inputsRef.current[index]?.focus();
|
|
1778
|
+
};
|
|
1779
|
+
const updateValue = (newDigits) => {
|
|
1780
|
+
onChange?.(newDigits.join(""));
|
|
1781
|
+
};
|
|
1782
|
+
const handleChange = (index, e) => {
|
|
1783
|
+
const val = e.target.value;
|
|
1784
|
+
if (val && !/^\d$/.test(val)) return;
|
|
1785
|
+
const newDigits = [...digits];
|
|
1786
|
+
newDigits[index] = val;
|
|
1787
|
+
updateValue(newDigits);
|
|
1788
|
+
if (val && index < length - 1) {
|
|
1789
|
+
focusInput(index + 1);
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
const handleKeyDown = (index, e) => {
|
|
1793
|
+
if (e.key === "Backspace") {
|
|
1794
|
+
if (digits[index]) {
|
|
1795
|
+
const newDigits = [...digits];
|
|
1796
|
+
newDigits[index] = "";
|
|
1797
|
+
updateValue(newDigits);
|
|
1798
|
+
} else if (index > 0) {
|
|
1799
|
+
focusInput(index - 1);
|
|
1800
|
+
const newDigits = [...digits];
|
|
1801
|
+
newDigits[index - 1] = "";
|
|
1802
|
+
updateValue(newDigits);
|
|
1803
|
+
}
|
|
1804
|
+
e.preventDefault();
|
|
1805
|
+
}
|
|
1806
|
+
if (e.key === "ArrowLeft" && index > 0) {
|
|
1807
|
+
focusInput(index - 1);
|
|
1808
|
+
e.preventDefault();
|
|
1809
|
+
}
|
|
1810
|
+
if (e.key === "ArrowRight" && index < length - 1) {
|
|
1811
|
+
focusInput(index + 1);
|
|
1812
|
+
e.preventDefault();
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1815
|
+
const handlePaste = (e) => {
|
|
1816
|
+
e.preventDefault();
|
|
1817
|
+
const pasted = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, length);
|
|
1818
|
+
if (!pasted) return;
|
|
1819
|
+
const newDigits = [...digits];
|
|
1820
|
+
for (let i = 0; i < pasted.length; i++) {
|
|
1821
|
+
newDigits[i] = pasted[i];
|
|
1822
|
+
}
|
|
1823
|
+
updateValue(newDigits);
|
|
1824
|
+
const nextIndex = Math.min(pasted.length, length - 1);
|
|
1825
|
+
focusInput(nextIndex);
|
|
1826
|
+
};
|
|
1827
|
+
const rootClassName = cn("otp_input", className);
|
|
1828
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, role: "group", "aria-label": ariaLabel, children: [
|
|
1829
|
+
/* @__PURE__ */ jsx("div", { className: "otp_input_boxes", children: digits.map((digit, i) => /* @__PURE__ */ jsx(
|
|
1830
|
+
"input",
|
|
1831
|
+
{
|
|
1832
|
+
ref: (el) => {
|
|
1833
|
+
inputsRef.current[i] = el;
|
|
1834
|
+
},
|
|
1835
|
+
type: "text",
|
|
1836
|
+
inputMode: "numeric",
|
|
1837
|
+
pattern: "\\d*",
|
|
1838
|
+
maxLength: 1,
|
|
1839
|
+
value: digit,
|
|
1840
|
+
onChange: (e) => handleChange(i, e),
|
|
1841
|
+
onKeyDown: (e) => handleKeyDown(i, e),
|
|
1842
|
+
onPaste: i === 0 ? handlePaste : void 0,
|
|
1843
|
+
disabled,
|
|
1844
|
+
autoFocus: autoFocus && i === 0,
|
|
1845
|
+
"aria-label": `${i + 1}\uBC88\uC9F8 \uC790\uB9AC`,
|
|
1846
|
+
className: cn(
|
|
1847
|
+
"otp_input_box",
|
|
1848
|
+
error && "otp_input_box_error",
|
|
1849
|
+
disabled && "otp_input_box_disabled"
|
|
1850
|
+
)
|
|
1851
|
+
},
|
|
1852
|
+
i
|
|
1853
|
+
)) }),
|
|
1854
|
+
supportingText && /* @__PURE__ */ jsx("span", { className: cn("otp_input_supporting", error && "otp_input_supporting_error"), children: supportingText })
|
|
1855
|
+
] });
|
|
1856
|
+
};
|
|
1857
|
+
OtpInput.displayName = "OtpInput";
|
|
1759
1858
|
var Modal = ({
|
|
1760
1859
|
open,
|
|
1761
1860
|
onClose,
|
|
@@ -2415,4 +2514,4 @@ var TopLoading = ({
|
|
|
2415
2514
|
);
|
|
2416
2515
|
};
|
|
2417
2516
|
|
|
2418
|
-
export { AlertProvider, Button, Card, Checkbox, Chip, DatePicker, Divider, FAB, FileInput, Icon, IconButton, LinearProgress, ListItem, Modal, Pagination, Radio, Select, Spinner, TextField, ToastProvider, Toggle, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useToast, zIndex };
|
|
2517
|
+
export { AlertProvider, Button, Card, Checkbox, Chip, DatePicker, Divider, FAB, FileInput, Icon, IconButton, LinearProgress, ListItem, Modal, OtpInput, Pagination, Radio, Select, Spinner, TextField, ToastProvider, Toggle, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useToast, zIndex };
|