@verma-consulting/design-library 0.1.47 → 0.1.48

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.mjs CHANGED
@@ -2271,6 +2271,183 @@ var CountrySelect = ({
2271
2271
  );
2272
2272
  };
2273
2273
  var CountrySelect_default = CountrySelect;
2274
+
2275
+ // src/OTPField.tsx
2276
+ import {
2277
+ useCallback as useCallback2,
2278
+ useEffect as useEffect6,
2279
+ useRef as useRef5,
2280
+ useState as useState7
2281
+ } from "react";
2282
+ import { Box as Box10, TextField as TextField4 } from "@mui/material";
2283
+ import { jsx as jsx19 } from "react/jsx-runtime";
2284
+ function toCells(s, len) {
2285
+ const slice = (s || "").slice(0, len);
2286
+ return Array.from({ length: len }, (_, i) => {
2287
+ var _a2;
2288
+ return (_a2 = slice[i]) != null ? _a2 : "";
2289
+ });
2290
+ }
2291
+ var OTPField = ({
2292
+ length,
2293
+ initialValue = "",
2294
+ onChange,
2295
+ onComplete,
2296
+ secret = false,
2297
+ autoSelect = false,
2298
+ disabled = false,
2299
+ inputFocusStyle,
2300
+ sx,
2301
+ type = "text",
2302
+ inputMode = "text",
2303
+ regexCriteria
2304
+ }) => {
2305
+ const [cells, setCells] = useState7(() => toCells(initialValue, length));
2306
+ const cellsRef = useRef5(cells);
2307
+ cellsRef.current = cells;
2308
+ const refs = useRef5([]);
2309
+ useEffect6(() => {
2310
+ setCells(toCells(initialValue, length));
2311
+ }, [initialValue, length]);
2312
+ const emit = useCallback2(
2313
+ (next, editedIndex) => {
2314
+ setCells(next);
2315
+ const joined = next.join("");
2316
+ onChange(joined, editedIndex);
2317
+ if (onComplete && joined.length === length && next.every(Boolean)) {
2318
+ onComplete(joined, length - 1);
2319
+ }
2320
+ },
2321
+ [length, onChange, onComplete]
2322
+ );
2323
+ useEffect6(() => {
2324
+ if (!autoSelect) return;
2325
+ const id = requestAnimationFrame(() => {
2326
+ var _a2;
2327
+ return (_a2 = refs.current[0]) == null ? void 0 : _a2.focus();
2328
+ });
2329
+ return () => cancelAnimationFrame(id);
2330
+ }, [autoSelect, length]);
2331
+ const charAllowed = useCallback2(
2332
+ (ch) => {
2333
+ if (!ch) return true;
2334
+ if (type === "numeric" && /\D/.test(ch)) return false;
2335
+ if (regexCriteria && !regexCriteria.test(ch)) return false;
2336
+ return true;
2337
+ },
2338
+ [regexCriteria, type]
2339
+ );
2340
+ const applyMany = useCallback2(
2341
+ (startIdx, raw) => {
2342
+ var _a2;
2343
+ const incoming = (type === "numeric" ? raw.replace(/\D/g, "") : raw).split("");
2344
+ const next = [...cellsRef.current];
2345
+ let i = startIdx;
2346
+ for (const ch of incoming) {
2347
+ if (i >= length) break;
2348
+ if (!charAllowed(ch)) return;
2349
+ next[i] = ch;
2350
+ i += 1;
2351
+ }
2352
+ const focusAt = Math.min(Math.max(i - 1, 0), length - 1);
2353
+ emit(next, focusAt);
2354
+ (_a2 = refs.current[focusAt]) == null ? void 0 : _a2.focus();
2355
+ },
2356
+ [charAllowed, emit, length, type]
2357
+ );
2358
+ const onFieldChange = (idx, e) => {
2359
+ var _a2;
2360
+ const raw = e.target.value;
2361
+ if (raw.length > 1) {
2362
+ applyMany(idx, raw);
2363
+ return;
2364
+ }
2365
+ if (raw && !charAllowed(raw)) return;
2366
+ const next = [...cellsRef.current];
2367
+ next[idx] = raw;
2368
+ emit(next, idx);
2369
+ if (raw && idx < length - 1) {
2370
+ (_a2 = refs.current[idx + 1]) == null ? void 0 : _a2.focus();
2371
+ }
2372
+ };
2373
+ const onKeyDown = (idx, e) => {
2374
+ var _a2, _b, _c;
2375
+ if (e.key === "Backspace") {
2376
+ const next = [...cellsRef.current];
2377
+ if (next[idx]) {
2378
+ next[idx] = "";
2379
+ emit(next, idx);
2380
+ } else if (idx > 0) {
2381
+ next[idx - 1] = "";
2382
+ emit(next, idx - 1);
2383
+ (_a2 = refs.current[idx - 1]) == null ? void 0 : _a2.focus();
2384
+ }
2385
+ e.preventDefault();
2386
+ } else if (e.key === "ArrowLeft" && idx > 0) {
2387
+ (_b = refs.current[idx - 1]) == null ? void 0 : _b.focus();
2388
+ e.preventDefault();
2389
+ } else if (e.key === "ArrowRight" && idx < length - 1) {
2390
+ (_c = refs.current[idx + 1]) == null ? void 0 : _c.focus();
2391
+ e.preventDefault();
2392
+ }
2393
+ };
2394
+ const onPasteFirst = (e) => {
2395
+ e.preventDefault();
2396
+ const text = e.clipboardData.getData("text").replace(/\s/g, "");
2397
+ if (!text) return;
2398
+ applyMany(0, text);
2399
+ };
2400
+ const inputType = secret ? "password" : type === "numeric" ? "tel" : "text";
2401
+ return /* @__PURE__ */ jsx19(
2402
+ Box10,
2403
+ {
2404
+ sx: [
2405
+ {
2406
+ display: "flex",
2407
+ gap: 1,
2408
+ flexWrap: "nowrap",
2409
+ justifyContent: "center",
2410
+ alignItems: "center"
2411
+ },
2412
+ ...sx == null ? [] : Array.isArray(sx) ? sx : [sx]
2413
+ ],
2414
+ children: Array.from({ length }).map((_, idx) => /* @__PURE__ */ jsx19(
2415
+ TextField4,
2416
+ {
2417
+ inputRef: (el) => {
2418
+ refs.current[idx] = el;
2419
+ },
2420
+ value: cells[idx],
2421
+ onChange: (e) => onFieldChange(idx, e),
2422
+ onKeyDown: (e) => onKeyDown(idx, e),
2423
+ onPaste: idx === 0 ? onPasteFirst : void 0,
2424
+ disabled,
2425
+ size: "small",
2426
+ type: inputType,
2427
+ sx: {
2428
+ width: 44,
2429
+ "& .MuiOutlinedInput-input": {
2430
+ textAlign: "center",
2431
+ py: 1,
2432
+ px: 0.5
2433
+ },
2434
+ ...inputFocusStyle ? {
2435
+ "& .MuiOutlinedInput-root.Mui-focused fieldset": inputFocusStyle
2436
+ } : {}
2437
+ },
2438
+ inputProps: {
2439
+ maxLength: 1,
2440
+ inputMode: inputMode != null ? inputMode : void 0,
2441
+ "aria-label": `Code character ${idx + 1} of ${length}`,
2442
+ autoComplete: "one-time-code"
2443
+ }
2444
+ },
2445
+ idx
2446
+ ))
2447
+ }
2448
+ );
2449
+ };
2450
+ var OTPField_default = OTPField;
2274
2451
  export {
2275
2452
  CountrySelect_default as CountrySelect,
2276
2453
  EmptyState_default as EmptyState,
@@ -2283,6 +2460,7 @@ export {
2283
2460
  InputFileUpload_default as InputFileUpload,
2284
2461
  Loader_default as Loader,
2285
2462
  Logo_default as Logo,
2463
+ OTPField_default as OTPField,
2286
2464
  PhoneNumberField_default as PhoneNumberField,
2287
2465
  Pill_default as Pill,
2288
2466
  SearchableSelect_default as SearchableSelect,