@verma-consulting/design-library 0.1.46 → 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/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Shared MUI-based React components for Verma Consulting applications. Use this package for consistent UI patterns, forms, and design tokens across projects.
4
4
 
5
+ ## Requirements
6
+
7
+ - **Node.js** `>=24.4.1` (see `engines` in `package.json`). For local development, use **24.4.1** via `.nvmrc`, `.node-version`, `.mise.toml`, or Volta (`volta` field in `package.json`).
8
+
5
9
  ## Installation
6
10
 
7
11
  ```bash
@@ -16,11 +20,11 @@ yarn add @verma-consulting/design-library
16
20
 
17
21
  Install these in your app (they are not bundled):
18
22
 
19
- - `react` (>=17)
20
- - `react-dom` (>=17)
21
- - `@mui/material` (^5.15.15)
22
- - `@mui/icons-material` (^7.3.0)
23
- - `@mui/styles` (^5.15.15)
23
+ - `react` (^18 or ^19)
24
+ - `react-dom` (^18 or ^19)
25
+ - `@mui/material` (^5.16.8 or ^7.3)
26
+ - `@mui/icons-material` (^5.16.8 or ^7.3)
27
+ - `@mui/styles` (^5.16.8 or ^7.3)
24
28
 
25
29
  The package also depends on `@verma-consulting/common-library`; it will be installed automatically.
26
30
 
@@ -60,6 +64,7 @@ The library re-exports **all of `@mui/material`**, so you can use MUI components
60
64
  | [FormSnackBar](./docs/FormSnackBar.md) | Snackbar for form success/error messages. |
61
65
  | [SearchableSelect](./docs/SearchableSelect.md) | Searchable single/multi select with view/edit modes. |
62
66
  | [PhoneNumberField](./docs/PhoneNumberField.md) | Phone input with country code and E.164 output. |
67
+ | [OTPField](./docs/OTPField.md) | One-time code input (single-character cells, paste, mask). |
63
68
  | [InputFileUpload](./docs/InputFileUpload.md) | Button that opens a file picker. |
64
69
  | [ImageUploadAvatar](./docs/ImageUploadAvatar.md) | Avatar-style image upload with preview and clear. |
65
70
  | [TabPanel](./docs/TabPanel.md) | Panel content for MUI Tabs (by index). |
package/dist/index.d.mts CHANGED
@@ -2,10 +2,9 @@ import { DialogProps, DrawerProps } from '@mui/material';
2
2
  export * from '@mui/material';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React from 'react';
5
- import React__default, { FC, KeyboardEvent } from 'react';
6
- import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
7
- import * as _mui_material_TablePagination from '@mui/material/TablePagination';
8
- import _mui_material_TablePagination__default, { LabelDisplayedRowsArgs } from '@mui/material/TablePagination';
5
+ import React__default, { FC, KeyboardEvent, CSSProperties } from 'react';
6
+ import MuiTablePagination, { LabelDisplayedRowsArgs } from '@mui/material/TablePagination';
7
+ import { SxProps, Theme } from '@mui/material/styles';
9
8
  export { ThemeProvider, createTheme, styled, useTheme } from '@mui/material/styles';
10
9
  export { makeStyles } from '@mui/styles';
11
10
  import { SwitchProps } from '@mui/material/Switch';
@@ -18,7 +17,7 @@ interface TabPanelProps {
18
17
  }
19
18
  declare const TabPanel: (props: TabPanelProps) => react_jsx_runtime.JSX.Element;
20
19
 
21
- type TablePaginationDesignProps = React.ComponentProps<typeof _mui_material_TablePagination__default> & {
20
+ type TablePaginationDesignProps = React.ComponentProps<typeof MuiTablePagination> & {
22
21
  /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
23
22
  rowsPerPageLabel?: React.ReactNode;
24
23
  /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
@@ -31,17 +30,7 @@ type TablePaginationDesignProps = React.ComponentProps<typeof _mui_material_Tabl
31
30
  * navigation by default. Use inside `TableFooter` for vertical alignment with
32
31
  * table rows.
33
32
  */
34
- declare const TablePagination: React.ForwardRefExoticComponent<(Omit<_mui_material_TablePagination.TablePaginationOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<_mui_material_TablePagination.TablePaginationBaseProps, "classes" | "align" | "colSpan" | "headers" | "rowSpan" | "scope" | "abbr" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "height" | "width" | "valign" | "padding" | "size" | "sortDirection" | "sx" | "variant" | "ref" | "ActionsComponent" | "backIconButtonProps" | "count" | "disabled" | "getItemAriaLabel" | "labelDisplayedRows" | "labelRowsPerPage" | "nextIconButtonProps" | "onPageChange" | "onRowsPerPageChange" | "page" | "rowsPerPage" | "rowsPerPageOptions" | "SelectProps" | "showFirstButton" | "showLastButton" | "slotProps" | "slots"> & {
35
- /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
36
- rowsPerPageLabel?: React.ReactNode;
37
- /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
38
- displayedRangeLabel?: (info: LabelDisplayedRowsArgs) => React.ReactNode;
39
- }, "ref"> | Omit<_mui_material_TablePagination.TablePaginationOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<Omit<_mui_material_TablePagination.TablePaginationBaseProps, "ref"> & React.RefAttributes<React.Component<any, any, any>>, "classes" | "align" | "colSpan" | "headers" | "rowSpan" | "scope" | "abbr" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "height" | "width" | "valign" | "padding" | "size" | "sortDirection" | "sx" | "variant" | "ref" | "ActionsComponent" | "backIconButtonProps" | "count" | "disabled" | "getItemAriaLabel" | "labelDisplayedRows" | "labelRowsPerPage" | "nextIconButtonProps" | "onPageChange" | "onRowsPerPageChange" | "page" | "rowsPerPage" | "rowsPerPageOptions" | "SelectProps" | "showFirstButton" | "showLastButton" | "slotProps" | "slots"> & {
40
- /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
41
- rowsPerPageLabel?: React.ReactNode;
42
- /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
43
- displayedRangeLabel?: (info: LabelDisplayedRowsArgs) => React.ReactNode;
44
- }, "ref">) & React.RefAttributes<unknown>>;
33
+ declare const TablePagination: React.ForwardRefExoticComponent<Omit<TablePaginationDesignProps, "ref"> & React.RefAttributes<unknown>>;
45
34
 
46
35
  type LogoProps = {
47
36
  loggedIn?: boolean;
@@ -216,8 +205,29 @@ interface CountrySelectProps {
216
205
  label?: string;
217
206
  size?: "small" | "medium";
218
207
  disabled?: boolean;
219
- style?: React__default.CSSProperties;
208
+ /** Applied to the view wrapper and the edit-mode `Autocomplete` root. */
209
+ sx?: SxProps<Theme>;
220
210
  }
221
211
  declare const CountrySelect: React__default.FC<CountrySelectProps>;
222
212
 
223
- export { CountrySelect, type CountryType, EmptyState, FormDialog, FormDrawer, FormPopover, FormSnackBar, IOSSwitch, ImageUploadAvatar, InputFileUpload, Loader, Logo, PhoneNumberField, Pill, SearchableSelect, SkeletonBar, StatusPill, TabPanel, TablePagination, type TablePaginationDesignProps };
213
+ type OTPFieldProps = {
214
+ length: number;
215
+ initialValue?: string;
216
+ onChange: (value: string, index?: number) => void;
217
+ onComplete?: (value: string, index?: number) => void;
218
+ /** Use password inputs (no brief reveal; React 19–safe replacement for `react-pin-input` `secret`). */
219
+ secret?: boolean;
220
+ autoSelect?: boolean;
221
+ disabled?: boolean;
222
+ /** Applied to the focused cell’s outline (`fieldset`). */
223
+ inputFocusStyle?: CSSProperties;
224
+ /** Applied to the outer `Box` (MUI `sx`). */
225
+ sx?: SxProps<Theme>;
226
+ type?: string;
227
+ inputMode?: React__default.HTMLAttributes<HTMLInputElement>["inputMode"];
228
+ /** Optional per-character filter (same idea as `react-pin-input` `regexCriteria`). */
229
+ regexCriteria?: RegExp;
230
+ };
231
+ declare const OTPField: React__default.FC<OTPFieldProps>;
232
+
233
+ export { CountrySelect, type CountryType, EmptyState, FormDialog, FormDrawer, FormPopover, FormSnackBar, IOSSwitch, ImageUploadAvatar, InputFileUpload, Loader, Logo, OTPField, type OTPFieldProps, PhoneNumberField, Pill, SearchableSelect, SkeletonBar, StatusPill, TabPanel, TablePagination, type TablePaginationDesignProps };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,9 @@ import { DialogProps, DrawerProps } from '@mui/material';
2
2
  export * from '@mui/material';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React from 'react';
5
- import React__default, { FC, KeyboardEvent } from 'react';
6
- import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
7
- import * as _mui_material_TablePagination from '@mui/material/TablePagination';
8
- import _mui_material_TablePagination__default, { LabelDisplayedRowsArgs } from '@mui/material/TablePagination';
5
+ import React__default, { FC, KeyboardEvent, CSSProperties } from 'react';
6
+ import MuiTablePagination, { LabelDisplayedRowsArgs } from '@mui/material/TablePagination';
7
+ import { SxProps, Theme } from '@mui/material/styles';
9
8
  export { ThemeProvider, createTheme, styled, useTheme } from '@mui/material/styles';
10
9
  export { makeStyles } from '@mui/styles';
11
10
  import { SwitchProps } from '@mui/material/Switch';
@@ -18,7 +17,7 @@ interface TabPanelProps {
18
17
  }
19
18
  declare const TabPanel: (props: TabPanelProps) => react_jsx_runtime.JSX.Element;
20
19
 
21
- type TablePaginationDesignProps = React.ComponentProps<typeof _mui_material_TablePagination__default> & {
20
+ type TablePaginationDesignProps = React.ComponentProps<typeof MuiTablePagination> & {
22
21
  /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
23
22
  rowsPerPageLabel?: React.ReactNode;
24
23
  /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
@@ -31,17 +30,7 @@ type TablePaginationDesignProps = React.ComponentProps<typeof _mui_material_Tabl
31
30
  * navigation by default. Use inside `TableFooter` for vertical alignment with
32
31
  * table rows.
33
32
  */
34
- declare const TablePagination: React.ForwardRefExoticComponent<(Omit<_mui_material_TablePagination.TablePaginationOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<_mui_material_TablePagination.TablePaginationBaseProps, "classes" | "align" | "colSpan" | "headers" | "rowSpan" | "scope" | "abbr" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "height" | "width" | "valign" | "padding" | "size" | "sortDirection" | "sx" | "variant" | "ref" | "ActionsComponent" | "backIconButtonProps" | "count" | "disabled" | "getItemAriaLabel" | "labelDisplayedRows" | "labelRowsPerPage" | "nextIconButtonProps" | "onPageChange" | "onRowsPerPageChange" | "page" | "rowsPerPage" | "rowsPerPageOptions" | "SelectProps" | "showFirstButton" | "showLastButton" | "slotProps" | "slots"> & {
35
- /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
36
- rowsPerPageLabel?: React.ReactNode;
37
- /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
38
- displayedRangeLabel?: (info: LabelDisplayedRowsArgs) => React.ReactNode;
39
- }, "ref"> | Omit<_mui_material_TablePagination.TablePaginationOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<Omit<_mui_material_TablePagination.TablePaginationBaseProps, "ref"> & React.RefAttributes<React.Component<any, any, any>>, "classes" | "align" | "colSpan" | "headers" | "rowSpan" | "scope" | "abbr" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "height" | "width" | "valign" | "padding" | "size" | "sortDirection" | "sx" | "variant" | "ref" | "ActionsComponent" | "backIconButtonProps" | "count" | "disabled" | "getItemAriaLabel" | "labelDisplayedRows" | "labelRowsPerPage" | "nextIconButtonProps" | "onPageChange" | "onRowsPerPageChange" | "page" | "rowsPerPage" | "rowsPerPageOptions" | "SelectProps" | "showFirstButton" | "showLastButton" | "slotProps" | "slots"> & {
40
- /** Label before the rows-per-page control. Default: "Per page". Overrides MUI `labelRowsPerPage` when both are omitted; explicit `labelRowsPerPage` wins. */
41
- rowsPerPageLabel?: React.ReactNode;
42
- /** Formats the range summary (e.g. total count). Default: "1–10 of 47 results". Overrides MUI `labelDisplayedRows` when both are omitted; explicit `labelDisplayedRows` wins. */
43
- displayedRangeLabel?: (info: LabelDisplayedRowsArgs) => React.ReactNode;
44
- }, "ref">) & React.RefAttributes<unknown>>;
33
+ declare const TablePagination: React.ForwardRefExoticComponent<Omit<TablePaginationDesignProps, "ref"> & React.RefAttributes<unknown>>;
45
34
 
46
35
  type LogoProps = {
47
36
  loggedIn?: boolean;
@@ -216,8 +205,29 @@ interface CountrySelectProps {
216
205
  label?: string;
217
206
  size?: "small" | "medium";
218
207
  disabled?: boolean;
219
- style?: React__default.CSSProperties;
208
+ /** Applied to the view wrapper and the edit-mode `Autocomplete` root. */
209
+ sx?: SxProps<Theme>;
220
210
  }
221
211
  declare const CountrySelect: React__default.FC<CountrySelectProps>;
222
212
 
223
- export { CountrySelect, type CountryType, EmptyState, FormDialog, FormDrawer, FormPopover, FormSnackBar, IOSSwitch, ImageUploadAvatar, InputFileUpload, Loader, Logo, PhoneNumberField, Pill, SearchableSelect, SkeletonBar, StatusPill, TabPanel, TablePagination, type TablePaginationDesignProps };
213
+ type OTPFieldProps = {
214
+ length: number;
215
+ initialValue?: string;
216
+ onChange: (value: string, index?: number) => void;
217
+ onComplete?: (value: string, index?: number) => void;
218
+ /** Use password inputs (no brief reveal; React 19–safe replacement for `react-pin-input` `secret`). */
219
+ secret?: boolean;
220
+ autoSelect?: boolean;
221
+ disabled?: boolean;
222
+ /** Applied to the focused cell’s outline (`fieldset`). */
223
+ inputFocusStyle?: CSSProperties;
224
+ /** Applied to the outer `Box` (MUI `sx`). */
225
+ sx?: SxProps<Theme>;
226
+ type?: string;
227
+ inputMode?: React__default.HTMLAttributes<HTMLInputElement>["inputMode"];
228
+ /** Optional per-character filter (same idea as `react-pin-input` `regexCriteria`). */
229
+ regexCriteria?: RegExp;
230
+ };
231
+ declare const OTPField: React__default.FC<OTPFieldProps>;
232
+
233
+ export { CountrySelect, type CountryType, EmptyState, FormDialog, FormDrawer, FormPopover, FormSnackBar, IOSSwitch, ImageUploadAvatar, InputFileUpload, Loader, Logo, OTPField, type OTPFieldProps, PhoneNumberField, Pill, SearchableSelect, SkeletonBar, StatusPill, TabPanel, TablePagination, type TablePaginationDesignProps };
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  InputFileUpload: () => InputFileUpload_default,
43
43
  Loader: () => Loader_default,
44
44
  Logo: () => Logo_default,
45
+ OTPField: () => OTPField_default,
45
46
  PhoneNumberField: () => PhoneNumberField_default,
46
47
  Pill: () => Pill_default,
47
48
  SearchableSelect: () => SearchableSelect_default,
@@ -2100,23 +2101,33 @@ var CountrySelect = ({
2100
2101
  label = "Country",
2101
2102
  size = "small",
2102
2103
  disabled = false,
2103
- style = {}
2104
+ sx
2104
2105
  }) => {
2105
2106
  const theme = (0, import_styles16.useTheme)();
2106
2107
  const classes = useStyles3();
2107
2108
  const [editMode, setEditMode] = (0, import_react9.useState)(false);
2109
+ const [listOpen, setListOpen] = (0, import_react9.useState)(false);
2108
2110
  const glassBackground = theme.palette.mode === "dark" ? "linear-gradient(160deg, rgba(31,41,55,0.78), rgba(17,24,39,0.68))" : "linear-gradient(160deg, rgba(255,255,255,0.9), rgba(245,249,255,0.72))";
2109
2111
  const handleBlur = () => {
2110
2112
  setTimeout(() => setEditMode(false), 15);
2111
2113
  };
2114
+ (0, import_react9.useEffect)(() => {
2115
+ if (!editMode) setListOpen(false);
2116
+ }, [editMode]);
2112
2117
  const selectedOption = COUNTRIES.find((country) => country.code === value);
2113
2118
  if (!editMode) {
2114
2119
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2115
- "div",
2120
+ import_material16.Box,
2116
2121
  {
2117
- onClick: () => !disabled && setEditMode(true),
2122
+ component: "div",
2123
+ onClick: () => {
2124
+ if (!disabled) {
2125
+ setEditMode(true);
2126
+ setListOpen(true);
2127
+ }
2128
+ },
2118
2129
  className: classes.defaultMode,
2119
- style,
2130
+ sx,
2120
2131
  children: [
2121
2132
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.FormLabel, { className: classes.formLabel, children: label }),
2122
2133
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
@@ -2156,14 +2167,20 @@ var CountrySelect = ({
2156
2167
  options: COUNTRIES,
2157
2168
  getOptionLabel: (option) => option.label,
2158
2169
  autoHighlight: true,
2170
+ open: listOpen,
2171
+ onOpen: () => setListOpen(true),
2172
+ onClose: () => setListOpen(false),
2159
2173
  openOnFocus: true,
2160
2174
  disableClearable: true,
2161
2175
  value: selectedOption != null ? selectedOption : void 0,
2162
2176
  onChange: (_, newValue) => {
2163
- if (newValue != null) onChange(newValue);
2177
+ if (newValue == null) return;
2178
+ onChange(newValue);
2179
+ setListOpen(false);
2180
+ setEditMode(false);
2164
2181
  },
2165
2182
  onBlur: handleBlur,
2166
- sx: style,
2183
+ sx,
2167
2184
  size,
2168
2185
  componentsProps: {
2169
2186
  paper: {
@@ -2207,6 +2224,7 @@ var CountrySelect = ({
2207
2224
  label,
2208
2225
  variant: "outlined",
2209
2226
  size,
2227
+ autoFocus: true,
2210
2228
  inputProps: {
2211
2229
  ...params.inputProps,
2212
2230
  autoComplete: "new-password"
@@ -2257,6 +2275,178 @@ var CountrySelect = ({
2257
2275
  );
2258
2276
  };
2259
2277
  var CountrySelect_default = CountrySelect;
2278
+
2279
+ // src/OTPField.tsx
2280
+ var import_react11 = require("react");
2281
+ var import_material17 = require("@mui/material");
2282
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2283
+ function toCells(s, len) {
2284
+ const slice = (s || "").slice(0, len);
2285
+ return Array.from({ length: len }, (_, i) => {
2286
+ var _a2;
2287
+ return (_a2 = slice[i]) != null ? _a2 : "";
2288
+ });
2289
+ }
2290
+ var OTPField = ({
2291
+ length,
2292
+ initialValue = "",
2293
+ onChange,
2294
+ onComplete,
2295
+ secret = false,
2296
+ autoSelect = false,
2297
+ disabled = false,
2298
+ inputFocusStyle,
2299
+ sx,
2300
+ type = "text",
2301
+ inputMode = "text",
2302
+ regexCriteria
2303
+ }) => {
2304
+ const [cells, setCells] = (0, import_react11.useState)(() => toCells(initialValue, length));
2305
+ const cellsRef = (0, import_react11.useRef)(cells);
2306
+ cellsRef.current = cells;
2307
+ const refs = (0, import_react11.useRef)([]);
2308
+ (0, import_react11.useEffect)(() => {
2309
+ setCells(toCells(initialValue, length));
2310
+ }, [initialValue, length]);
2311
+ const emit = (0, import_react11.useCallback)(
2312
+ (next, editedIndex) => {
2313
+ setCells(next);
2314
+ const joined = next.join("");
2315
+ onChange(joined, editedIndex);
2316
+ if (onComplete && joined.length === length && next.every(Boolean)) {
2317
+ onComplete(joined, length - 1);
2318
+ }
2319
+ },
2320
+ [length, onChange, onComplete]
2321
+ );
2322
+ (0, import_react11.useEffect)(() => {
2323
+ if (!autoSelect) return;
2324
+ const id = requestAnimationFrame(() => {
2325
+ var _a2;
2326
+ return (_a2 = refs.current[0]) == null ? void 0 : _a2.focus();
2327
+ });
2328
+ return () => cancelAnimationFrame(id);
2329
+ }, [autoSelect, length]);
2330
+ const charAllowed = (0, import_react11.useCallback)(
2331
+ (ch) => {
2332
+ if (!ch) return true;
2333
+ if (type === "numeric" && /\D/.test(ch)) return false;
2334
+ if (regexCriteria && !regexCriteria.test(ch)) return false;
2335
+ return true;
2336
+ },
2337
+ [regexCriteria, type]
2338
+ );
2339
+ const applyMany = (0, import_react11.useCallback)(
2340
+ (startIdx, raw) => {
2341
+ var _a2;
2342
+ const incoming = (type === "numeric" ? raw.replace(/\D/g, "") : raw).split("");
2343
+ const next = [...cellsRef.current];
2344
+ let i = startIdx;
2345
+ for (const ch of incoming) {
2346
+ if (i >= length) break;
2347
+ if (!charAllowed(ch)) return;
2348
+ next[i] = ch;
2349
+ i += 1;
2350
+ }
2351
+ const focusAt = Math.min(Math.max(i - 1, 0), length - 1);
2352
+ emit(next, focusAt);
2353
+ (_a2 = refs.current[focusAt]) == null ? void 0 : _a2.focus();
2354
+ },
2355
+ [charAllowed, emit, length, type]
2356
+ );
2357
+ const onFieldChange = (idx, e) => {
2358
+ var _a2;
2359
+ const raw = e.target.value;
2360
+ if (raw.length > 1) {
2361
+ applyMany(idx, raw);
2362
+ return;
2363
+ }
2364
+ if (raw && !charAllowed(raw)) return;
2365
+ const next = [...cellsRef.current];
2366
+ next[idx] = raw;
2367
+ emit(next, idx);
2368
+ if (raw && idx < length - 1) {
2369
+ (_a2 = refs.current[idx + 1]) == null ? void 0 : _a2.focus();
2370
+ }
2371
+ };
2372
+ const onKeyDown = (idx, e) => {
2373
+ var _a2, _b, _c;
2374
+ if (e.key === "Backspace") {
2375
+ const next = [...cellsRef.current];
2376
+ if (next[idx]) {
2377
+ next[idx] = "";
2378
+ emit(next, idx);
2379
+ } else if (idx > 0) {
2380
+ next[idx - 1] = "";
2381
+ emit(next, idx - 1);
2382
+ (_a2 = refs.current[idx - 1]) == null ? void 0 : _a2.focus();
2383
+ }
2384
+ e.preventDefault();
2385
+ } else if (e.key === "ArrowLeft" && idx > 0) {
2386
+ (_b = refs.current[idx - 1]) == null ? void 0 : _b.focus();
2387
+ e.preventDefault();
2388
+ } else if (e.key === "ArrowRight" && idx < length - 1) {
2389
+ (_c = refs.current[idx + 1]) == null ? void 0 : _c.focus();
2390
+ e.preventDefault();
2391
+ }
2392
+ };
2393
+ const onPasteFirst = (e) => {
2394
+ e.preventDefault();
2395
+ const text = e.clipboardData.getData("text").replace(/\s/g, "");
2396
+ if (!text) return;
2397
+ applyMany(0, text);
2398
+ };
2399
+ const inputType = secret ? "password" : type === "numeric" ? "tel" : "text";
2400
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2401
+ import_material17.Box,
2402
+ {
2403
+ sx: [
2404
+ {
2405
+ display: "flex",
2406
+ gap: 1,
2407
+ flexWrap: "nowrap",
2408
+ justifyContent: "center",
2409
+ alignItems: "center"
2410
+ },
2411
+ ...sx == null ? [] : Array.isArray(sx) ? sx : [sx]
2412
+ ],
2413
+ children: Array.from({ length }).map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2414
+ import_material17.TextField,
2415
+ {
2416
+ inputRef: (el) => {
2417
+ refs.current[idx] = el;
2418
+ },
2419
+ value: cells[idx],
2420
+ onChange: (e) => onFieldChange(idx, e),
2421
+ onKeyDown: (e) => onKeyDown(idx, e),
2422
+ onPaste: idx === 0 ? onPasteFirst : void 0,
2423
+ disabled,
2424
+ size: "small",
2425
+ type: inputType,
2426
+ sx: {
2427
+ width: 44,
2428
+ "& .MuiOutlinedInput-input": {
2429
+ textAlign: "center",
2430
+ py: 1,
2431
+ px: 0.5
2432
+ },
2433
+ ...inputFocusStyle ? {
2434
+ "& .MuiOutlinedInput-root.Mui-focused fieldset": inputFocusStyle
2435
+ } : {}
2436
+ },
2437
+ inputProps: {
2438
+ maxLength: 1,
2439
+ inputMode: inputMode != null ? inputMode : void 0,
2440
+ "aria-label": `Code character ${idx + 1} of ${length}`,
2441
+ autoComplete: "one-time-code"
2442
+ }
2443
+ },
2444
+ idx
2445
+ ))
2446
+ }
2447
+ );
2448
+ };
2449
+ var OTPField_default = OTPField;
2260
2450
  // Annotate the CommonJS export names for ESM import in node:
2261
2451
  0 && (module.exports = {
2262
2452
  CountrySelect,
@@ -2270,6 +2460,7 @@ var CountrySelect_default = CountrySelect;
2270
2460
  InputFileUpload,
2271
2461
  Loader,
2272
2462
  Logo,
2463
+ OTPField,
2273
2464
  PhoneNumberField,
2274
2465
  Pill,
2275
2466
  SearchableSelect,