@mantine/core 9.6.0 → 9.6.2
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/cjs/components/Accordion/Accordion.module.cjs.map +1 -1
- package/cjs/components/Combobox/use-combobox/use-combobox.cjs +1 -4
- package/cjs/components/Combobox/use-combobox/use-combobox.cjs.map +1 -1
- package/cjs/components/ComboboxPopover/ComboboxPopover.cjs +1 -1
- package/cjs/components/ComboboxPopover/ComboboxPopover.cjs.map +1 -1
- package/cjs/components/Drawer/Drawer.cjs +2 -1
- package/cjs/components/Drawer/Drawer.cjs.map +1 -1
- package/cjs/components/Drawer/DrawerStack.cjs +3 -1
- package/cjs/components/Drawer/DrawerStack.cjs.map +1 -1
- package/cjs/components/Menu/MenuSub/MenuSub.cjs +1 -1
- package/cjs/components/Menu/MenuSub/MenuSub.cjs.map +1 -1
- package/cjs/components/Modal/Modal.cjs +2 -1
- package/cjs/components/Modal/Modal.cjs.map +1 -1
- package/cjs/components/Modal/ModalStack.cjs +3 -1
- package/cjs/components/Modal/ModalStack.cjs.map +1 -1
- package/cjs/components/ModalBase/ModalBase.cjs +3 -2
- package/cjs/components/ModalBase/ModalBase.cjs.map +1 -1
- package/cjs/components/ModalBase/use-modal.cjs +7 -2
- package/cjs/components/ModalBase/use-modal.cjs.map +1 -1
- package/cjs/components/NumberInput/NumberInput.cjs +32 -22
- package/cjs/components/NumberInput/NumberInput.cjs.map +1 -1
- package/cjs/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.cjs +19 -0
- package/cjs/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.cjs.map +1 -0
- package/cjs/components/NumberInput/normalize-pasted-value/normalize-pasted-value.cjs +35 -0
- package/cjs/components/NumberInput/normalize-pasted-value/normalize-pasted-value.cjs.map +1 -0
- package/cjs/components/OverflowList/use-dimensions.cjs +9 -9
- package/cjs/components/OverflowList/use-dimensions.cjs.map +1 -1
- package/cjs/components/Popover/use-popover.cjs +7 -1
- package/cjs/components/Popover/use-popover.cjs.map +1 -1
- package/cjs/components/SegmentedControl/SegmentedControl.cjs +12 -1
- package/cjs/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
- package/cjs/components/Textarea/Autosize.cjs +8 -2
- package/cjs/components/Textarea/Autosize.cjs.map +1 -1
- package/esm/components/Accordion/Accordion.module.mjs.map +1 -1
- package/esm/components/Combobox/use-combobox/use-combobox.mjs +1 -4
- package/esm/components/Combobox/use-combobox/use-combobox.mjs.map +1 -1
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs +1 -1
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs.map +1 -1
- package/esm/components/Drawer/Drawer.mjs +2 -1
- package/esm/components/Drawer/Drawer.mjs.map +1 -1
- package/esm/components/Drawer/DrawerStack.mjs +3 -1
- package/esm/components/Drawer/DrawerStack.mjs.map +1 -1
- package/esm/components/Menu/MenuSub/MenuSub.mjs +1 -1
- package/esm/components/Menu/MenuSub/MenuSub.mjs.map +1 -1
- package/esm/components/Modal/Modal.mjs +2 -1
- package/esm/components/Modal/Modal.mjs.map +1 -1
- package/esm/components/Modal/ModalStack.mjs +3 -1
- package/esm/components/Modal/ModalStack.mjs.map +1 -1
- package/esm/components/ModalBase/ModalBase.mjs +3 -2
- package/esm/components/ModalBase/ModalBase.mjs.map +1 -1
- package/esm/components/ModalBase/use-modal.mjs +7 -2
- package/esm/components/ModalBase/use-modal.mjs.map +1 -1
- package/esm/components/NumberInput/NumberInput.mjs +32 -22
- package/esm/components/NumberInput/NumberInput.mjs.map +1 -1
- package/esm/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.mjs +19 -0
- package/esm/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.mjs.map +1 -0
- package/esm/components/NumberInput/normalize-pasted-value/normalize-pasted-value.mjs +35 -0
- package/esm/components/NumberInput/normalize-pasted-value/normalize-pasted-value.mjs.map +1 -0
- package/esm/components/OverflowList/use-dimensions.mjs +9 -9
- package/esm/components/OverflowList/use-dimensions.mjs.map +1 -1
- package/esm/components/Popover/use-popover.mjs +7 -1
- package/esm/components/Popover/use-popover.mjs.map +1 -1
- package/esm/components/SegmentedControl/SegmentedControl.mjs +12 -1
- package/esm/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
- package/esm/components/Textarea/Autosize.mjs +9 -3
- package/esm/components/Textarea/Autosize.mjs.map +1 -1
- package/lib/components/Drawer/DrawerStack.d.ts +1 -0
- package/lib/components/Menu/MenuSub/MenuSub.d.ts +3 -1
- package/lib/components/Modal/ModalStack.d.ts +1 -0
- package/lib/components/ModalBase/ModalBase.d.ts +2 -1
- package/lib/components/ModalBase/use-modal.d.ts +2 -1
- package/lib/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.d.ts +1 -0
- package/lib/components/NumberInput/normalize-pasted-value/normalize-pasted-value.d.ts +7 -0
- package/package.json +2 -2
- package/styles/Accordion.css +4 -2
- package/styles/Accordion.layer.css +4 -2
- package/styles.css +4 -2
- package/styles.layer.css +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalStack.mjs","names":[],"sources":["../../../src/components/Modal/ModalStack.tsx"],"sourcesContent":["import { createContext, useState } from 'react';\nimport { getDefaultZIndex } from '../../core';\n\ninterface ModalStackContext {\n stack: string[];\n addModal: (id: string, zIndex: number | string) => void;\n removeModal: (id: string) => void;\n getZIndex: (id: string) => string;\n currentId: string;\n maxZIndex: string | number;\n}\n\nexport const ModalStackContext = createContext<ModalStackContext | null>(null);\n\nexport interface ModalStackProps {\n children: React.ReactNode;\n}\n\nexport function ModalStack({ children }: ModalStackProps) {\n const [stack, setStack] = useState<string[]>([]);\n const [maxZIndex, setMaxZIndex] = useState<number | string>(getDefaultZIndex('modal'));\n\n return (\n <ModalStackContext\n value={{\n stack,\n addModal: (id, zIndex) => {\n setStack((current) => [...new Set([...current, id])]);\n setMaxZIndex((current) =>\n typeof zIndex === 'number' && typeof current === 'number'\n ? Math.max(current, zIndex)\n : current\n );\n },\n removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),\n getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,\n currentId: stack[stack.length - 1],\n maxZIndex,\n }}\n >\n {children}\n </ModalStackContext>\n );\n}\n\nModalStack.displayName = '@mantine/core/ModalStack';\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"ModalStack.mjs","names":[],"sources":["../../../src/components/Modal/ModalStack.tsx"],"sourcesContent":["import { createContext, useState } from 'react';\nimport { getDefaultZIndex } from '../../core';\n\ninterface ModalStackContext {\n stack: string[];\n addModal: (id: string, zIndex: number | string) => void;\n removeModal: (id: string) => void;\n getZIndex: (id: string) => string;\n currentId: string;\n maxZIndex: string | number;\n handledEscapeEvents: WeakSet<KeyboardEvent>;\n}\n\nexport const ModalStackContext = createContext<ModalStackContext | null>(null);\n\nexport interface ModalStackProps {\n children: React.ReactNode;\n}\n\nexport function ModalStack({ children }: ModalStackProps) {\n const [stack, setStack] = useState<string[]>([]);\n const [maxZIndex, setMaxZIndex] = useState<number | string>(getDefaultZIndex('modal'));\n const [handledEscapeEvents] = useState(() => new WeakSet<KeyboardEvent>());\n\n return (\n <ModalStackContext\n value={{\n stack,\n addModal: (id, zIndex) => {\n setStack((current) => [...new Set([...current, id])]);\n setMaxZIndex((current) =>\n typeof zIndex === 'number' && typeof current === 'number'\n ? Math.max(current, zIndex)\n : current\n );\n },\n removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),\n getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,\n currentId: stack[stack.length - 1],\n maxZIndex,\n handledEscapeEvents,\n }}\n >\n {children}\n </ModalStackContext>\n );\n}\n\nModalStack.displayName = '@mantine/core/ModalStack';\n"],"mappings":";;;;;AAaA,MAAa,oBAAoB,cAAwC,IAAI;AAM7E,SAAgB,WAAW,EAAE,YAA6B;CACxD,MAAM,CAAC,OAAO,YAAY,SAAmB,CAAC,CAAC;CAC/C,MAAM,CAAC,WAAW,gBAAgB,SAA0B,iBAAiB,OAAO,CAAC;CACrF,MAAM,CAAC,uBAAuB,+BAAe,IAAI,QAAuB,CAAC;CAEzE,OACE,oBAAC,mBAAD;EACE,OAAO;GACL;GACA,WAAW,IAAI,WAAW;IACxB,UAAU,YAAY,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;IACpD,cAAc,YACZ,OAAO,WAAW,YAAY,OAAO,YAAY,WAC7C,KAAK,IAAI,SAAS,MAAM,IACxB,OACN;GACF;GACA,cAAc,OAAO,UAAU,YAAY,QAAQ,QAAQ,cAAc,cAAc,EAAE,CAAC;GAC1F,YAAY,OAAO,QAAQ,UAAU,KAAK,MAAM,QAAQ,EAAE,EAAE;GAC5D,WAAW,MAAM,MAAM,SAAS;GAChC;GACA;EACF;EAEC;CACgB,CAAA;AAEvB;AAEA,WAAW,cAAc"}
|
|
@@ -8,7 +8,7 @@ import { useModal } from "./use-modal.mjs";
|
|
|
8
8
|
import { RemoveScroll } from "react-remove-scroll";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
10
10
|
//#region packages/@mantine/core/src/components/ModalBase/ModalBase.tsx
|
|
11
|
-
function ModalBase({ keepMounted, keepMountedMode = "activity", opened, onClose, id, transitionProps, onExitTransitionEnd, onEnterTransitionEnd, trapFocus, closeOnEscape, returnFocus, closeOnClickOutside, withinPortal, portalProps, lockScroll, children, zIndex, shadow, padding, __vars, unstyled, removeScrollProps, ...others }) {
|
|
11
|
+
function ModalBase({ keepMounted, keepMountedMode = "activity", opened, onClose, id, transitionProps, onExitTransitionEnd, onEnterTransitionEnd, trapFocus, closeOnEscape, returnFocus, closeOnClickOutside, withinPortal, portalProps, lockScroll, children, zIndex, shadow, padding, __vars, unstyled, removeScrollProps, __handledEscapeEvents, ...others }) {
|
|
12
12
|
const { _id, titleMounted, bodyMounted, shouldLockScroll, setTitleMounted, setBodyMounted } = useModal({
|
|
13
13
|
id,
|
|
14
14
|
transitionProps,
|
|
@@ -16,7 +16,8 @@ function ModalBase({ keepMounted, keepMountedMode = "activity", opened, onClose,
|
|
|
16
16
|
trapFocus,
|
|
17
17
|
closeOnEscape,
|
|
18
18
|
onClose,
|
|
19
|
-
returnFocus
|
|
19
|
+
returnFocus,
|
|
20
|
+
handledEscapeEvents: __handledEscapeEvents
|
|
20
21
|
});
|
|
21
22
|
const { key: removeScrollKey, ...otherRemoveScrollProps } = removeScrollProps || {};
|
|
22
23
|
return /* @__PURE__ */ jsx(OptionalPortal, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalBase.mjs","names":[],"sources":["../../../src/components/ModalBase/ModalBase.tsx"],"sourcesContent":["import { RemoveScroll } from 'react-remove-scroll';\nimport {\n Box,\n BoxProps,\n ElementProps,\n getDefaultZIndex,\n getShadow,\n getSpacing,\n MantineShadow,\n MantineSize,\n MantineSpacing,\n} from '../../core';\nimport { BasePortalProps, OptionalPortal } from '../Portal';\nimport { TransitionOverride } from '../Transition';\nimport { ModalBaseProvider } from './ModalBase.context';\nimport { useModal } from './use-modal';\n\ntype RemoveScrollProps = Omit<React.ComponentProps<typeof RemoveScroll>, 'children'>;\n\nexport interface ModalBaseProps extends BoxProps, ElementProps<'div', 'title'> {\n unstyled?: boolean;\n\n /** If set modal/drawer is not unmounted from the DOM when hidden. `display: none` styles are applied instead. @default false */\n keepMounted?: boolean;\n\n /** Controls how the modal/drawer is hidden when `keepMounted` is set:\n * `'activity'` - hidden with React 19 `Activity` component,\n * `'display-none'` - hidden with `display: none` styles\n * @default 'activity'\n */\n keepMountedMode?: 'activity' | 'display-none';\n\n /** Controls opened state */\n opened: boolean;\n\n /** Called when modal/drawer is closed */\n onClose: () => void;\n\n /** Id used to connect modal/drawer with body and title */\n id?: string;\n\n /** If set, scroll is locked when `opened={true}` @default true */\n lockScroll?: boolean;\n\n /** If set, focus is trapped within the modal/drawer @default true */\n trapFocus?: boolean;\n\n /** If set, the component is rendered inside `Portal` @default true */\n withinPortal?: boolean;\n\n /** Props passed down to the Portal component when `withinPortal` is set */\n portalProps?: BasePortalProps;\n\n /** Modal/drawer content */\n children?: React.ReactNode;\n\n /** If set, the modal/drawer is closed when user clicks on the overlay @default true */\n closeOnClickOutside?: boolean;\n\n /** Props added to the `Transition` component that used to animate overlay and body, use to configure duration and animation type, `{ duration: 200, transition: 'fade-down' }` by default */\n transitionProps?: TransitionOverride;\n\n /** Called when exit transition ends */\n onExitTransitionEnd?: () => void;\n\n /** Called when enter transition ends */\n onEnterTransitionEnd?: () => void;\n\n /** If set, `onClose` is called when user presses the escape key @default true */\n closeOnEscape?: boolean;\n\n /** If set, focus is returned to the last active element when `onClose` is called @default true */\n returnFocus?: boolean;\n\n /** `z-index` CSS property of the root element @default 200 */\n zIndex?: string | number;\n\n /** Key of `theme.shadows` or any valid CSS box-shadow value @default 'xl' */\n shadow?: MantineShadow;\n\n /** Key of `theme.spacing` or any valid CSS value to set content, header and footer padding @default 'md' */\n padding?: MantineSpacing;\n\n /** Controls width of the content area @default 'md' */\n size?: MantineSize | (string & {}) | number;\n\n /** Props passed down to react-remove-scroll, can be used to customize scroll lock behavior */\n removeScrollProps?: RemoveScrollProps;\n}\n\nexport function ModalBase({\n keepMounted,\n keepMountedMode = 'activity',\n opened,\n onClose,\n id,\n transitionProps,\n onExitTransitionEnd,\n onEnterTransitionEnd,\n trapFocus,\n closeOnEscape,\n returnFocus,\n closeOnClickOutside,\n withinPortal,\n portalProps,\n lockScroll,\n children,\n zIndex,\n shadow,\n padding,\n __vars,\n unstyled,\n removeScrollProps,\n ...others\n}: ModalBaseProps) {\n const { _id, titleMounted, bodyMounted, shouldLockScroll, setTitleMounted, setBodyMounted } =\n useModal({
|
|
1
|
+
{"version":3,"file":"ModalBase.mjs","names":[],"sources":["../../../src/components/ModalBase/ModalBase.tsx"],"sourcesContent":["import { RemoveScroll } from 'react-remove-scroll';\nimport {\n Box,\n BoxProps,\n ElementProps,\n getDefaultZIndex,\n getShadow,\n getSpacing,\n MantineShadow,\n MantineSize,\n MantineSpacing,\n} from '../../core';\nimport { BasePortalProps, OptionalPortal } from '../Portal';\nimport { TransitionOverride } from '../Transition';\nimport { ModalBaseProvider } from './ModalBase.context';\nimport { useModal } from './use-modal';\n\ntype RemoveScrollProps = Omit<React.ComponentProps<typeof RemoveScroll>, 'children'>;\n\nexport interface ModalBaseProps extends BoxProps, ElementProps<'div', 'title'> {\n unstyled?: boolean;\n __handledEscapeEvents?: WeakSet<KeyboardEvent>;\n\n /** If set modal/drawer is not unmounted from the DOM when hidden. `display: none` styles are applied instead. @default false */\n keepMounted?: boolean;\n\n /** Controls how the modal/drawer is hidden when `keepMounted` is set:\n * `'activity'` - hidden with React 19 `Activity` component,\n * `'display-none'` - hidden with `display: none` styles\n * @default 'activity'\n */\n keepMountedMode?: 'activity' | 'display-none';\n\n /** Controls opened state */\n opened: boolean;\n\n /** Called when modal/drawer is closed */\n onClose: () => void;\n\n /** Id used to connect modal/drawer with body and title */\n id?: string;\n\n /** If set, scroll is locked when `opened={true}` @default true */\n lockScroll?: boolean;\n\n /** If set, focus is trapped within the modal/drawer @default true */\n trapFocus?: boolean;\n\n /** If set, the component is rendered inside `Portal` @default true */\n withinPortal?: boolean;\n\n /** Props passed down to the Portal component when `withinPortal` is set */\n portalProps?: BasePortalProps;\n\n /** Modal/drawer content */\n children?: React.ReactNode;\n\n /** If set, the modal/drawer is closed when user clicks on the overlay @default true */\n closeOnClickOutside?: boolean;\n\n /** Props added to the `Transition` component that used to animate overlay and body, use to configure duration and animation type, `{ duration: 200, transition: 'fade-down' }` by default */\n transitionProps?: TransitionOverride;\n\n /** Called when exit transition ends */\n onExitTransitionEnd?: () => void;\n\n /** Called when enter transition ends */\n onEnterTransitionEnd?: () => void;\n\n /** If set, `onClose` is called when user presses the escape key @default true */\n closeOnEscape?: boolean;\n\n /** If set, focus is returned to the last active element when `onClose` is called @default true */\n returnFocus?: boolean;\n\n /** `z-index` CSS property of the root element @default 200 */\n zIndex?: string | number;\n\n /** Key of `theme.shadows` or any valid CSS box-shadow value @default 'xl' */\n shadow?: MantineShadow;\n\n /** Key of `theme.spacing` or any valid CSS value to set content, header and footer padding @default 'md' */\n padding?: MantineSpacing;\n\n /** Controls width of the content area @default 'md' */\n size?: MantineSize | (string & {}) | number;\n\n /** Props passed down to react-remove-scroll, can be used to customize scroll lock behavior */\n removeScrollProps?: RemoveScrollProps;\n}\n\nexport function ModalBase({\n keepMounted,\n keepMountedMode = 'activity',\n opened,\n onClose,\n id,\n transitionProps,\n onExitTransitionEnd,\n onEnterTransitionEnd,\n trapFocus,\n closeOnEscape,\n returnFocus,\n closeOnClickOutside,\n withinPortal,\n portalProps,\n lockScroll,\n children,\n zIndex,\n shadow,\n padding,\n __vars,\n unstyled,\n removeScrollProps,\n __handledEscapeEvents,\n ...others\n}: ModalBaseProps) {\n const { _id, titleMounted, bodyMounted, shouldLockScroll, setTitleMounted, setBodyMounted } =\n useModal({\n id,\n transitionProps,\n opened,\n trapFocus,\n closeOnEscape,\n onClose,\n returnFocus,\n handledEscapeEvents: __handledEscapeEvents,\n });\n\n const { key: removeScrollKey, ...otherRemoveScrollProps } = removeScrollProps || {};\n\n return (\n <OptionalPortal {...portalProps} withinPortal={withinPortal}>\n <ModalBaseProvider\n value={{\n opened,\n onClose,\n closeOnClickOutside,\n onExitTransitionEnd,\n onEnterTransitionEnd,\n transitionProps: { ...transitionProps, keepMounted, keepMountedMode },\n getTitleId: () => `${_id}-title`,\n getBodyId: () => `${_id}-body`,\n titleMounted,\n bodyMounted,\n setTitleMounted,\n setBodyMounted,\n trapFocus,\n closeOnEscape,\n zIndex,\n unstyled,\n }}\n >\n <RemoveScroll\n enabled={shouldLockScroll && lockScroll}\n key={removeScrollKey}\n {...otherRemoveScrollProps}\n >\n <Box\n {...others}\n id={_id}\n __vars={{\n ...__vars,\n '--mb-z-index': (zIndex || getDefaultZIndex('modal')).toString(),\n '--mb-shadow': getShadow(shadow),\n '--mb-padding': getSpacing(padding),\n }}\n >\n {children}\n </Box>\n </RemoveScroll>\n </ModalBaseProvider>\n </OptionalPortal>\n );\n}\n\nModalBase.displayName = '@mantine/core/ModalBase';\n"],"mappings":";;;;;;;;;;AA2FA,SAAgB,UAAU,EACxB,aACA,kBAAkB,YAClB,QACA,SACA,IACA,iBACA,qBACA,sBACA,WACA,eACA,aACA,qBACA,cACA,aACA,YACA,UACA,QACA,QACA,SACA,QACA,UACA,mBACA,uBACA,GAAG,UACc;CACjB,MAAM,EAAE,KAAK,cAAc,aAAa,kBAAkB,iBAAiB,mBACzE,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA,qBAAqB;CACvB,CAAC;CAEH,MAAM,EAAE,KAAK,iBAAiB,GAAG,2BAA2B,qBAAqB,CAAC;CAElF,OACE,oBAAC,gBAAD;EAAgB,GAAI;EAA2B;EAC7C,UAAA,oBAAC,mBAAD;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA,iBAAiB;KAAE,GAAG;KAAiB;KAAa;IAAgB;IACpE,kBAAkB,GAAG,IAAI;IACzB,iBAAiB,GAAG,IAAI;IACxB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GAEA,UAAA,oBAAC,cAAD;IACE,SAAS,oBAAoB;IAE7B,GAAI;IAEJ,UAAA,oBAAC,KAAD;KACE,GAAI;KACJ,IAAI;KACJ,QAAQ;MACN,GAAG;MACH,iBAAiB,UAAU,iBAAiB,OAAO,EAAA,CAAG,SAAS;MAC/D,eAAe,UAAU,MAAM;MAC/B,gBAAgB,WAAW,OAAO;KACpC;KAEC;IACE,CAAA;GACO,GAfP,eAeO;EACG,CAAA;CACL,CAAA;AAEpB;AAEA,UAAU,cAAc"}
|
|
@@ -3,7 +3,7 @@ import { useLockScroll } from "./use-lock-scroll.mjs";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { useFocusReturn, useId as useId$1, useWindowEvent } from "@mantine/hooks";
|
|
5
5
|
//#region packages/@mantine/core/src/components/ModalBase/use-modal.ts
|
|
6
|
-
function useModal({ id, transitionProps, opened, trapFocus, closeOnEscape, onClose, returnFocus }) {
|
|
6
|
+
function useModal({ id, transitionProps, opened, trapFocus, closeOnEscape, onClose, returnFocus, handledEscapeEvents }) {
|
|
7
7
|
const _id = useId$1(id);
|
|
8
8
|
const [titleMounted, setTitleMounted] = useState(false);
|
|
9
9
|
const [bodyMounted, setBodyMounted] = useState(false);
|
|
@@ -13,7 +13,12 @@ function useModal({ id, transitionProps, opened, trapFocus, closeOnEscape, onClo
|
|
|
13
13
|
transitionDuration
|
|
14
14
|
});
|
|
15
15
|
useWindowEvent("keydown", (event) => {
|
|
16
|
-
if (event.key === "Escape" && closeOnEscape && !event.isComposing && opened
|
|
16
|
+
if (event.key === "Escape" && closeOnEscape && !event.isComposing && opened && !handledEscapeEvents?.has(event)) {
|
|
17
|
+
if (event.target?.getAttribute("data-mantine-stop-propagation") !== "true") {
|
|
18
|
+
handledEscapeEvents?.add(event);
|
|
19
|
+
onClose();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
17
22
|
}, { capture: true });
|
|
18
23
|
useFocusReturn({
|
|
19
24
|
opened,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-modal.mjs","names":["useId"],"sources":["../../../src/components/ModalBase/use-modal.ts"],"sourcesContent":["import { useState } from 'react';\nimport { useFocusReturn, useId, useWindowEvent } from '@mantine/hooks';\nimport { TransitionOverride } from '../Transition';\nimport { useLockScroll } from './use-lock-scroll';\n\ninterface UseModalInput {\n opened: boolean;\n onClose: () => void;\n id: string | undefined;\n transitionProps: TransitionOverride | undefined;\n trapFocus: boolean | undefined;\n closeOnEscape: boolean | undefined;\n returnFocus: boolean | undefined;\n}\n\nexport function useModal({\n id,\n transitionProps,\n opened,\n trapFocus,\n closeOnEscape,\n onClose,\n returnFocus,\n}: UseModalInput) {\n const _id = useId(id);\n const [titleMounted, setTitleMounted] = useState(false);\n const [bodyMounted, setBodyMounted] = useState(false);\n\n const transitionDuration =\n typeof transitionProps?.duration === 'number' ? transitionProps?.duration : 200;\n\n const shouldLockScroll = useLockScroll({ opened, transitionDuration });\n\n useWindowEvent(\n 'keydown',\n (event) => {\n if (event.key === 'Escape'
|
|
1
|
+
{"version":3,"file":"use-modal.mjs","names":["useId"],"sources":["../../../src/components/ModalBase/use-modal.ts"],"sourcesContent":["import { useState } from 'react';\nimport { useFocusReturn, useId, useWindowEvent } from '@mantine/hooks';\nimport { TransitionOverride } from '../Transition';\nimport { useLockScroll } from './use-lock-scroll';\n\ninterface UseModalInput {\n opened: boolean;\n onClose: () => void;\n id: string | undefined;\n transitionProps: TransitionOverride | undefined;\n trapFocus: boolean | undefined;\n closeOnEscape: boolean | undefined;\n returnFocus: boolean | undefined;\n handledEscapeEvents?: WeakSet<KeyboardEvent>;\n}\n\nexport function useModal({\n id,\n transitionProps,\n opened,\n trapFocus,\n closeOnEscape,\n onClose,\n returnFocus,\n handledEscapeEvents,\n}: UseModalInput) {\n const _id = useId(id);\n const [titleMounted, setTitleMounted] = useState(false);\n const [bodyMounted, setBodyMounted] = useState(false);\n\n const transitionDuration =\n typeof transitionProps?.duration === 'number' ? transitionProps?.duration : 200;\n\n const shouldLockScroll = useLockScroll({ opened, transitionDuration });\n\n useWindowEvent(\n 'keydown',\n (event) => {\n if (\n event.key === 'Escape' &&\n closeOnEscape &&\n !event.isComposing &&\n opened &&\n !handledEscapeEvents?.has(event)\n ) {\n const shouldTrigger =\n (event.target as HTMLElement)?.getAttribute('data-mantine-stop-propagation') !== 'true';\n if (shouldTrigger) {\n handledEscapeEvents?.add(event);\n onClose();\n }\n }\n },\n { capture: true }\n );\n\n useFocusReturn({ opened, shouldReturnFocus: trapFocus && returnFocus });\n\n return {\n _id,\n titleMounted,\n bodyMounted,\n shouldLockScroll,\n setTitleMounted,\n setBodyMounted,\n };\n}\n"],"mappings":";;;;;AAgBA,SAAgB,SAAS,EACvB,IACA,iBACA,QACA,WACA,eACA,SACA,aACA,uBACgB;CAChB,MAAM,MAAMA,QAAM,EAAE;CACpB,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CAEpD,MAAM,qBACJ,OAAO,iBAAiB,aAAa,WAAW,iBAAiB,WAAW;CAE9E,MAAM,mBAAmB,cAAc;EAAE;EAAQ;CAAmB,CAAC;CAErE,eACE,YACC,UAAU;EACT,IACE,MAAM,QAAQ,YACd,iBACA,CAAC,MAAM,eACP,UACA,CAAC,qBAAqB,IAAI,KAAK,GAG5B;OAAA,MAAM,QAAwB,aAAa,+BAA+B,MAAM,QAChE;IACjB,qBAAqB,IAAI,KAAK;IAC9B,QAAQ;GACV;;CAEJ,GACA,EAAE,SAAS,KAAK,CAClB;CAEA,eAAe;EAAE;EAAQ,mBAAmB,aAAa;CAAY,CAAC;CAEtE,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -8,6 +8,8 @@ import { useStyles } from "../../core/styles-api/use-styles/use-styles.mjs";
|
|
|
8
8
|
import { genericFactory } from "../../core/factory/factory.mjs";
|
|
9
9
|
import { UnstyledButton } from "../UnstyledButton/UnstyledButton.mjs";
|
|
10
10
|
import { InputBase } from "../InputBase/InputBase.mjs";
|
|
11
|
+
import { getCaretPositionAfterPaste } from "./get-caret-position-after-paste/get-caret-position-after-paste.mjs";
|
|
12
|
+
import { normalizePastedValue } from "./normalize-pasted-value/normalize-pasted-value.mjs";
|
|
11
13
|
import { NumberInputChevron } from "./NumberInputChevron.mjs";
|
|
12
14
|
import NumberInput_module_default from "./NumberInput.module.mjs";
|
|
13
15
|
import { useRef } from "react";
|
|
@@ -80,16 +82,18 @@ const defaultProps = {
|
|
|
80
82
|
allowedDecimalSeparators: [".", ","]
|
|
81
83
|
};
|
|
82
84
|
const varsResolver = createVarsResolver((_, { size }) => ({ controls: { "--ni-chevron-size": getSize(size, "ni-chevron-size") } }));
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
85
|
+
function withTrailingSeparator(value, hasTrailingDecimalSeparator) {
|
|
86
|
+
return hasTrailingDecimalSeparator ? `${value}.` : value;
|
|
87
|
+
}
|
|
88
|
+
function sanitizeInputOnBlur(value, options) {
|
|
89
|
+
const hasTrailingDecimalSeparator = trailingDecimalSeparatorPattern.test(value);
|
|
90
|
+
const trimmed = options.trim ? value.replace(/^0+(?=\d)/, "") : value;
|
|
91
|
+
const parsedValue = parseFloat(trimmed);
|
|
92
|
+
if (Number.isNaN(parsedValue)) return trimmed;
|
|
93
|
+
if (!options.clamp) return options.trim ? withTrailingSeparator(parsedValue, hasTrailingDecimalSeparator) : value;
|
|
94
|
+
const clamped = parsedValue > Number.MAX_SAFE_INTEGER && options.max !== void 0 ? options.max : clamp(parsedValue, options.min, options.max);
|
|
95
|
+
if (!options.trim && clamped === parsedValue) return value;
|
|
96
|
+
return withTrailingSeparator(clamped, hasTrailingDecimalSeparator);
|
|
93
97
|
}
|
|
94
98
|
function clampAndSanitizeBigIntInput(sanitizedValue, options) {
|
|
95
99
|
if (sanitizedValue === "" || sanitizedValue === "-") return sanitizedValue;
|
|
@@ -268,13 +272,15 @@ const NumberInput = genericFactory((_props) => {
|
|
|
268
272
|
const handlePaste = (event) => {
|
|
269
273
|
const pastedText = event.clipboardData.getData("text");
|
|
270
274
|
const _decimalSeparator = others.decimalSeparator || ".";
|
|
271
|
-
const
|
|
272
|
-
|
|
275
|
+
const _thousandSeparator = others.thousandSeparator === true ? "," : others.thousandSeparator === false ? void 0 : others.thousandSeparator;
|
|
276
|
+
const modifiedText = normalizePastedValue(pastedText, {
|
|
277
|
+
decimalSeparator: _decimalSeparator,
|
|
278
|
+
thousandSeparator: _thousandSeparator,
|
|
279
|
+
allowedDecimalSeparators: allowedDecimalSeparators || [".", ","],
|
|
280
|
+
thousandsGroupStyle: others.thousandsGroupStyle
|
|
281
|
+
});
|
|
282
|
+
if (modifiedText !== pastedText) {
|
|
273
283
|
event.preventDefault();
|
|
274
|
-
let modifiedText = pastedText;
|
|
275
|
-
separatorsToReplace.forEach((s) => {
|
|
276
|
-
modifiedText = modifiedText.split(s).join(_decimalSeparator);
|
|
277
|
-
});
|
|
278
284
|
const input = inputRef.current;
|
|
279
285
|
if (input) {
|
|
280
286
|
const start = input.selectionStart ?? 0;
|
|
@@ -283,8 +289,8 @@ const NumberInput = genericFactory((_props) => {
|
|
|
283
289
|
const newValue = currentValue.substring(0, start) + modifiedText + currentValue.substring(end);
|
|
284
290
|
(Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set)?.call(input, newValue);
|
|
285
291
|
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
286
|
-
const
|
|
287
|
-
setTimeout(() => adjustCursor(
|
|
292
|
+
const rawCaret = start + modifiedText.length;
|
|
293
|
+
setTimeout(() => adjustCursor(getCaretPositionAfterPaste(newValue, rawCaret, input.value, _decimalSeparator)), 0);
|
|
288
294
|
}
|
|
289
295
|
}
|
|
290
296
|
others.onPaste?.(event);
|
|
@@ -324,10 +330,14 @@ const NumberInput = genericFactory((_props) => {
|
|
|
324
330
|
max: maxBigInt,
|
|
325
331
|
clampBehavior
|
|
326
332
|
});
|
|
327
|
-
} else {
|
|
328
|
-
if (clampBehavior === "blur"
|
|
329
|
-
|
|
330
|
-
|
|
333
|
+
} else if (typeof sanitizedValue === "number") {
|
|
334
|
+
if (clampBehavior === "blur") sanitizedValue = clamp(sanitizedValue, minNumber, maxNumber);
|
|
335
|
+
} else if (typeof sanitizedValue === "string") sanitizedValue = sanitizeInputOnBlur(sanitizedValue, {
|
|
336
|
+
min: minNumber,
|
|
337
|
+
max: maxNumber,
|
|
338
|
+
trim: !!trimLeadingZeroesOnBlur && getDecimalPlaces(sanitizedValue) < 15,
|
|
339
|
+
clamp: clampBehavior === "blur"
|
|
340
|
+
});
|
|
331
341
|
if (_value !== sanitizedValue) setValue(sanitizedValue);
|
|
332
342
|
onBlur?.(event);
|
|
333
343
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberInput.mjs","names":["classes"],"sources":["../../../src/components/NumberInput/NumberInput.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport cx from 'clsx';\nimport { NumberFormatValues, NumericFormat, OnValueChange } from 'react-number-format';\nimport { assignRef, clamp, useMergedRef, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n Factory,\n genericFactory,\n getSize,\n noop,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { __BaseInputProps, __InputStylesNames, InputVariant } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { UnstyledButton } from '../UnstyledButton';\nimport { NumberInputChevron } from './NumberInputChevron';\nimport classes from './NumberInput.module.css';\n\n// Re for negative -0, -0., -0.0, -0.00, -0.000 ... strings\n// And for positive 0., 0.0, 0.00, 0.000 ... strings\nconst leadingDecimalZeroPattern = /^(0\\.0*|-0(\\.0*)?)$/;\n\n// Re for 01, 006, 00.02, -0010, -000.293 ... and negative counterparts\nconst leadingZerosPattern = /^-?0\\d+(\\.\\d+)?\\.?$/;\n\n// Re for decimal numbers with trailing zeros like 13.0, 13.00, 5.10 ... strings\nconst trailingZerosPattern = /\\.\\d*0$/;\n\n// Re for numbers with trailing decimal separator like 10. or -3.\nconst trailingDecimalSeparatorPattern = /^-?\\d+\\.$/;\n\nexport interface NumberInputHandlers {\n increment: () => void;\n decrement: () => void;\n}\n\nexport type NumberInputMode = 'number' | 'bigint';\nexport type NumberInputNumericType = number | bigint;\nexport type NumberInputValue<T extends NumberInputNumericType = number> = T | string;\ntype NumberInputNumericValue<T extends NumberInputNumericType = number> = T;\ntype InternalNumberInputValue = string | number | bigint;\n\nfunction isNumberString(value: unknown) {\n return typeof value === 'string' && value !== '' && !Number.isNaN(Number(value));\n}\n\nfunction isBigIntValue(value: unknown): value is bigint {\n return typeof value === 'bigint';\n}\n\nfunction canStep(value: number | string) {\n if (typeof value === 'number') {\n return value < Number.MAX_SAFE_INTEGER;\n }\n\n return value === '' || (isNumberString(value) && Number(value) < Number.MAX_SAFE_INTEGER);\n}\n\nfunction isValidBigIntString(value: string, allowNegative: boolean) {\n if (value === '') {\n return false;\n }\n\n if (value === '-') {\n return false;\n }\n\n if (!allowNegative && value.startsWith('-')) {\n return false;\n }\n\n return /^-?\\d+$/.test(value);\n}\n\nfunction canStepBigInt(value: bigint | string, allowNegative: boolean) {\n if (typeof value === 'bigint') {\n return true;\n }\n\n return value === '' || isValidBigIntString(value, allowNegative);\n}\n\nfunction parseBigIntFromString(value: string): bigint | null {\n if (!/^-?\\d+$/.test(value)) {\n return null;\n }\n\n try {\n return BigInt(value);\n } catch {\n return null;\n }\n}\n\nfunction toBigIntOrUndefined(value: unknown): bigint | undefined {\n if (typeof value === 'bigint') {\n return value;\n }\n\n if (typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value)) {\n return BigInt(value);\n }\n\n return undefined;\n}\n\nfunction clampBigInt(value: bigint, min?: bigint, max?: bigint) {\n if (min !== undefined && value < min) {\n return min;\n }\n\n if (max !== undefined && value > max) {\n return max;\n }\n\n return value;\n}\n\nfunction getTotalDigits(inputValue: string | number): number {\n // All digits must be counted, parseFloat precision depends\n // on the number of digits in the input, not only on the decimal scale\n return inputValue.toString().replace('.', '').length;\n}\n\nfunction isValidNumber(floatValue: number | undefined, value: string): floatValue is number {\n return (\n (typeof floatValue === 'number'\n ? floatValue < Number.MAX_SAFE_INTEGER\n : !Number.isNaN(Number(floatValue))) &&\n !Number.isNaN(floatValue) &&\n getTotalDigits(value) < 14 &&\n value !== ''\n );\n}\n\nfunction isInRange(value: number | undefined, min: number | undefined, max: number | undefined) {\n if (value === undefined) {\n return true;\n }\n\n const minValid = min === undefined || value >= min;\n const maxValid = max === undefined || value <= max;\n\n return minValid && maxValid;\n}\n\nexport type NumberInputStylesNames = 'controls' | 'control' | __InputStylesNames;\nexport type NumberInputCssVariables = {\n controls: '--ni-chevron-size';\n};\n\nexport interface NumberInputProps<T extends NumberInputNumericType = number>\n extends\n BoxProps,\n Omit<__BaseInputProps, 'pointer'>,\n StylesApiProps<NumberInputFactory>,\n ElementProps<\n 'input',\n 'size' | 'type' | 'onChange' | 'value' | 'defaultValue' | 'min' | 'max' | 'step'\n > {\n /** Controlled component value */\n value?: NumberInputValue<T>;\n\n /** Uncontrolled component default value */\n defaultValue?: NumberInputValue<T>;\n\n /** Called when value changes */\n onChange?: (value: NumberInputValue<T>) => void;\n\n /** Called when value changes with `react-number-format` payload */\n onValueChange?: OnValueChange;\n\n /** Determines whether leading zeros are allowed during input. If `false`, leading zeros are removed as you type (e.g., typing `007` results in `7`). Works in conjunction with `trimLeadingZeroesOnBlur`. @default true */\n allowLeadingZeros?: boolean;\n\n /** Determines whether negative numbers are allowed. If `false`, the input will not accept negative values, and the decrement button will stop at `0` (when `min` is not set). @default true */\n allowNegative?: boolean;\n\n /** Characters which when pressed result in a decimal separator. These characters will be replaced by the `decimalSeparator` in the input value. @default ['.', ','] */\n allowedDecimalSeparators?: string[];\n\n /** Limits the number of digits that can be entered after the decimal point @default Infinity */\n decimalScale?: number;\n\n /** Character used as a decimal separator. Generally used with `allowedDecimalSeparators` prop. @default '.' */\n decimalSeparator?: string;\n\n /** If `true`, automatically pads the decimal part with zeros to match `decimalScale` (e.g., with `decimalScale={2}`, typing `5.1` displays as `5.10`). Requires `decimalScale` to be set. @default false */\n fixedDecimalScale?: boolean;\n\n /** Prefix added before the input value */\n prefix?: string;\n\n /** Suffix added after the input value */\n suffix?: string;\n\n /** Defines the thousand grouping style. 'thousand' (1,000), 'lakh' (1,00,000), 'wan' (1,0000), 'none'. */\n thousandsGroupStyle?: 'thousand' | 'lakh' | 'wan' | 'none';\n\n /** A function to validate the input value. If this function returns `false`, the `onChange` will not be called and the input value will not change. */\n isAllowed?: (values: NumberFormatValues) => boolean;\n\n /** Advanced: Set to `true` if you're passing numeric strings (e.g., `\"12345\"`) and using formatting props like `prefix` or `suffix`. In most cases, you don't need this prop. See [react-number-format docs](https://www.npmjs.com/package/react-number-format) for details. @default false */\n valueIsNumericString?: boolean;\n\n /** Controls input `type` attribute @default 'text' */\n type?: 'text' | 'tel' | 'password';\n\n /** A character used to separate thousands */\n thousandSeparator?: string | boolean;\n\n /** Minimum possible value */\n min?: NumberInputNumericValue<T>;\n\n /** Maximum possible value */\n max?: NumberInputNumericValue<T>;\n\n /** Number by which value will be incremented/decremented with up/down controls and keyboard arrows @default 1 */\n step?: NumberInputNumericValue<T>;\n\n /** If set, the up/down controls are hidden @default false */\n hideControls?: boolean;\n\n /** Controls how values are clamped to the `min`/`max` range:\n * - `'blur'` (default): User can type any value, but it's clamped when the input loses focus\n * - `'strict'`: User cannot type values outside the range\n * - `'none'`: No clamping; `min`/`max` only apply to increment/decrement controls and arrow keys\n */\n clampBehavior?: 'strict' | 'blur' | 'none';\n\n /** If set, decimal values are allowed @default true */\n allowDecimal?: boolean;\n\n /** Increment/decrement handlers */\n handlersRef?: React.Ref<NumberInputHandlers | undefined>;\n\n /** Value used when incrementing/decrementing an empty input. If `min` is set and `startValue < min`, `min` is used instead. @default 0 */\n startValue?: NumberInputNumericValue<T>;\n\n /** Interval in milliseconds between value steps when increment/decrement button is held down. Can be a number or a function `(stepCount) => number` for dynamic intervals. Requires `stepHoldDelay` to be set. @default undefined */\n stepHoldInterval?: number | ((stepCount: number) => number);\n\n /** Initial delay in milliseconds before stepping the value. */\n stepHoldDelay?: number;\n\n /** If set, up/down keyboard events increment/decrement value @default true */\n withKeyboardEvents?: boolean;\n\n /** If set, leading zeros are removed on blur. For example, `00100` -> `100` @default true */\n trimLeadingZeroesOnBlur?: boolean;\n\n /** If set, all text is selected when the input receives focus @default false */\n selectAllOnFocus?: boolean;\n\n /** Called when the increment button or arrow up key is pressed and the value has reached the maximum */\n onMinReached?: () => void;\n\n /** Called when the decrement button or arrow down key is pressed and the value has reached the minimum */\n onMaxReached?: () => void;\n}\n\nexport type NumberInputFactory = Factory<{\n props: NumberInputProps;\n ref: HTMLInputElement;\n stylesNames: NumberInputStylesNames;\n vars: NumberInputCssVariables;\n variant: InputVariant;\n signature: <T extends NumberInputNumericType = number>(\n props: NumberInputProps<T>\n ) => React.JSX.Element;\n}>;\n\nconst defaultProps = {\n size: 'sm',\n step: 1,\n clampBehavior: 'blur',\n allowDecimal: true,\n allowNegative: true,\n withKeyboardEvents: true,\n allowLeadingZeros: true,\n trimLeadingZeroesOnBlur: true,\n startValue: 0,\n allowedDecimalSeparators: ['.', ','],\n} satisfies Partial<NumberInputProps<number | bigint>>;\n\nconst varsResolver = createVarsResolver<NumberInputFactory>((_, { size }) => ({\n controls: {\n '--ni-chevron-size': getSize(size, 'ni-chevron-size'),\n },\n}));\n\nfunction clampAndSanitizeInput(sanitizedValue: string | number, max?: number, min?: number) {\n const stringValue = sanitizedValue.toString();\n const hasTrailingDecimalSeparator = trailingDecimalSeparatorPattern.test(stringValue);\n\n const replaced = stringValue.replace(/^0+(?=\\d)/, '');\n const parsedValue = parseFloat(replaced);\n\n if (Number.isNaN(parsedValue)) {\n return replaced;\n }\n\n if (parsedValue > Number.MAX_SAFE_INTEGER) {\n return max !== undefined ? max : replaced;\n }\n\n const clamped = clamp(parsedValue, min, max);\n\n if (hasTrailingDecimalSeparator) {\n const clampedString = clamped.toString().replace(/^0+(?=\\d)/, '');\n return `${clampedString}.`;\n }\n\n return clamped;\n}\n\nfunction clampAndSanitizeBigIntInput(\n sanitizedValue: string,\n options: { min?: bigint; max?: bigint; clampBehavior: NumberInputProps['clampBehavior'] }\n) {\n if (sanitizedValue === '' || sanitizedValue === '-') {\n return sanitizedValue;\n }\n\n const parsed = parseBigIntFromString(sanitizedValue);\n\n if (parsed === null) {\n return sanitizedValue;\n }\n\n return options.clampBehavior === 'blur' ? clampBigInt(parsed, options.min, options.max) : parsed;\n}\n\nexport const NumberInput = genericFactory<NumberInputFactory>(\n <T extends NumberInputNumericType = number>(_props: NumberInputProps<T>) => {\n const props = useProps(\n ['Input', 'InputWrapper', 'NumberInput'],\n defaultProps as Partial<NumberInputProps>,\n _props as unknown as NumberInputProps\n );\n const {\n className,\n classNames,\n styles,\n unstyled,\n vars,\n onChange,\n onValueChange,\n value,\n defaultValue,\n max,\n min,\n step,\n hideControls,\n rightSection,\n isAllowed,\n clampBehavior,\n onBlur,\n allowDecimal,\n decimalScale,\n onKeyDown,\n onKeyDownCapture,\n handlersRef,\n startValue,\n disabled,\n rightSectionPointerEvents,\n allowNegative,\n readOnly,\n size,\n rightSectionWidth,\n stepHoldInterval,\n stepHoldDelay,\n allowLeadingZeros,\n withKeyboardEvents,\n trimLeadingZeroesOnBlur,\n allowedDecimalSeparators,\n selectAllOnFocus,\n onMinReached,\n onMaxReached,\n onFocus,\n attributes,\n ref,\n ...others\n } = props;\n const allowNegativeResolved = allowNegative ?? true;\n const allowLeadingZerosResolved = allowLeadingZeros ?? true;\n\n const getStyles = useStyles<NumberInputFactory>({\n name: 'NumberInput',\n classes,\n props: props as NumberInputProps,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<NumberInputFactory>({\n classNames,\n styles,\n props: props as NumberInputProps,\n });\n\n const valueModeRef = useRef<NumberInputMode>(\n isBigIntValue(value) || isBigIntValue(defaultValue) ? 'bigint' : 'number'\n );\n\n if (isBigIntValue(value)) {\n valueModeRef.current = 'bigint';\n } else if (typeof value === 'number') {\n valueModeRef.current = 'number';\n }\n\n const isBigIntMode = valueModeRef.current === 'bigint';\n\n const [_value, setValue] = useUncontrolled<InternalNumberInputValue>({\n value: value as InternalNumberInputValue | undefined,\n defaultValue: defaultValue as InternalNumberInputValue | undefined,\n finalValue: '',\n onChange: onChange as ((value: InternalNumberInputValue) => void) | undefined,\n });\n\n const shouldUseStepInterval = stepHoldDelay !== undefined && stepHoldInterval !== undefined;\n const inputRef = useRef<HTMLInputElement>(null);\n const onStepTimeoutRef = useRef<number | null>(null);\n const stepCountRef = useRef<number>(0);\n\n const minNumber = typeof min === 'number' ? min : undefined;\n const maxNumber = typeof max === 'number' ? max : undefined;\n const stepNumber = typeof step === 'number' ? step : defaultProps.step;\n const startValueNumber = typeof startValue === 'number' ? startValue : defaultProps.startValue;\n\n const minBigInt = toBigIntOrUndefined(min);\n const maxBigInt = toBigIntOrUndefined(max);\n const stepBigInt = toBigIntOrUndefined(step) ?? BigInt(1);\n const startValueBigInt = toBigIntOrUndefined(startValue) ?? BigInt(0);\n\n const parseBigIntOrString = (inputValue: string): bigint | string => {\n if (\n !isValidBigIntString(inputValue, allowNegativeResolved) ||\n (allowLeadingZerosResolved && leadingZerosPattern.test(inputValue))\n ) {\n return inputValue;\n }\n\n const parsed = parseBigIntFromString(inputValue);\n return parsed ?? inputValue;\n };\n\n const getBigIntFloatValue = (inputValue: bigint) => {\n const numericValue = Number(inputValue);\n return Number.isSafeInteger(numericValue) ? numericValue : undefined;\n };\n\n const handleValueChange: OnValueChange = (payload, event) => {\n if (event.source === 'event') {\n if (isBigIntMode) {\n setValue(parseBigIntOrString(payload.value));\n } else {\n setValue(\n isValidNumber(payload.floatValue, payload.value) &&\n !leadingDecimalZeroPattern.test(payload.value) &&\n !(allowLeadingZerosResolved ? leadingZerosPattern.test(payload.value) : false) &&\n !trailingZerosPattern.test(payload.value) &&\n !trailingDecimalSeparatorPattern.test(payload.value)\n ? payload.floatValue\n : payload.value\n );\n }\n }\n onValueChange?.(payload, event);\n };\n\n const getDecimalPlaces = (inputValue: number | string): number => {\n const match = String(inputValue).match(/(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/);\n if (!match) {\n return 0;\n }\n return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));\n };\n\n const adjustCursor = (position?: number) => {\n if (inputRef.current && typeof position !== 'undefined') {\n inputRef.current.setSelectionRange(position, position);\n }\n };\n\n const incrementRef = useRef<() => void>(noop);\n incrementRef.current = () => {\n if (isBigIntMode) {\n if (!canStepBigInt(_value as bigint | string, allowNegativeResolved)) {\n return;\n }\n\n let val: bigint;\n const currentValue = _value;\n\n if (typeof currentValue === 'bigint') {\n const incrementedValue = currentValue + stepBigInt;\n if (maxBigInt !== undefined && incrementedValue > maxBigInt) {\n onMaxReached?.();\n }\n val =\n maxBigInt !== undefined && incrementedValue > maxBigInt ? maxBigInt : incrementedValue;\n } else if (typeof currentValue === 'string' && currentValue !== '') {\n const parsed = parseBigIntFromString(currentValue);\n if (parsed === null) {\n return;\n }\n\n const incrementedValue = parsed + stepBigInt;\n if (maxBigInt !== undefined && incrementedValue > maxBigInt) {\n onMaxReached?.();\n }\n val =\n maxBigInt !== undefined && incrementedValue > maxBigInt ? maxBigInt : incrementedValue;\n } else {\n val = clampBigInt(startValueBigInt, minBigInt, maxBigInt);\n }\n\n const formattedValue = val.toString();\n setValue(val);\n onValueChange?.(\n { floatValue: getBigIntFloatValue(val), formattedValue, value: formattedValue },\n { source: 'increment' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n return;\n }\n\n if (!canStep(_value as number | string)) {\n return;\n }\n\n let val: number;\n const currentValuePrecision = getDecimalPlaces(_value as number | string);\n const stepPrecision = getDecimalPlaces(stepNumber);\n const maxPrecision = Math.max(currentValuePrecision, stepPrecision);\n const factor = 10 ** maxPrecision;\n\n if (!isNumberString(_value) && (typeof _value !== 'number' || Number.isNaN(_value))) {\n val = clamp(startValueNumber, minNumber, maxNumber);\n } else if (maxNumber !== undefined) {\n const incrementedValue =\n (Math.round(Number(_value) * factor) + Math.round(stepNumber * factor)) / factor;\n if (incrementedValue > maxNumber) {\n onMaxReached?.();\n }\n val = incrementedValue <= maxNumber ? incrementedValue : maxNumber;\n } else {\n val = (Math.round(Number(_value) * factor) + Math.round(stepNumber * factor)) / factor;\n }\n\n const formattedValue = val.toFixed(maxPrecision);\n setValue(parseFloat(formattedValue));\n onValueChange?.(\n { floatValue: parseFloat(formattedValue), formattedValue, value: formattedValue },\n { source: 'increment' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n };\n\n const decrementRef = useRef<() => void>(noop);\n decrementRef.current = () => {\n if (isBigIntMode) {\n if (!canStepBigInt(_value as bigint | string, allowNegativeResolved)) {\n return;\n }\n\n let val: bigint;\n const minValue =\n minBigInt !== undefined ? minBigInt : !allowNegativeResolved ? BigInt(0) : undefined;\n const currentValue = _value;\n\n if (typeof currentValue === 'bigint') {\n const decrementedValue = currentValue - stepBigInt;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n } else if (typeof currentValue === 'string' && currentValue !== '') {\n const parsed = parseBigIntFromString(currentValue);\n if (parsed === null) {\n return;\n }\n\n const decrementedValue = parsed - stepBigInt;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n } else {\n val = clampBigInt(startValueBigInt, minValue, maxBigInt);\n }\n\n const formattedValue = val.toString();\n setValue(val);\n onValueChange?.(\n { floatValue: getBigIntFloatValue(val), formattedValue, value: formattedValue },\n { source: 'decrement' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n return;\n }\n\n if (!canStep(_value as number | string)) {\n return;\n }\n\n let val: number;\n const minValue =\n minNumber !== undefined ? minNumber : !allowNegativeResolved ? 0 : Number.MIN_SAFE_INTEGER;\n const currentValuePrecision = getDecimalPlaces(_value as number | string);\n const stepPrecision = getDecimalPlaces(stepNumber);\n const maxPrecision = Math.max(currentValuePrecision, stepPrecision);\n const factor = 10 ** maxPrecision;\n\n if ((!isNumberString(_value) && typeof _value !== 'number') || Number.isNaN(_value)) {\n val = clamp(startValueNumber, minValue, maxNumber);\n } else {\n const decrementedValue =\n (Math.round(Number(_value) * factor) - Math.round(stepNumber * factor)) / factor;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n }\n\n const formattedValue = val.toFixed(maxPrecision);\n setValue(parseFloat(formattedValue));\n onValueChange?.(\n { floatValue: parseFloat(formattedValue), formattedValue, value: formattedValue },\n { source: 'decrement' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n const pastedText = event.clipboardData.getData('text');\n const _decimalSeparator = others.decimalSeparator || '.';\n const separatorsToReplace = (allowedDecimalSeparators || ['.', ',']).filter(\n (s) => s !== _decimalSeparator\n );\n\n if (separatorsToReplace.some((s) => pastedText.includes(s))) {\n event.preventDefault();\n let modifiedText = pastedText;\n separatorsToReplace.forEach((s) => {\n modifiedText = modifiedText.split(s).join(_decimalSeparator);\n });\n\n const input = inputRef.current;\n if (input) {\n const start = input.selectionStart ?? 0;\n const end = input.selectionEnd ?? 0;\n const currentValue = input.value;\n const newValue =\n currentValue.substring(0, start) + modifiedText + currentValue.substring(end);\n\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value'\n )?.set;\n nativeInputValueSetter?.call(input, newValue);\n input.dispatchEvent(new Event('change', { bubbles: true }));\n\n const cursorPos = start + modifiedText.length;\n setTimeout(() => adjustCursor(cursorPos), 0);\n }\n }\n\n others.onPaste?.(event as any);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n\n if (readOnly || !withKeyboardEvents) {\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n incrementRef.current?.();\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n decrementRef.current?.();\n }\n };\n\n const handleKeyDownCapture = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDownCapture?.(event);\n if (event.key === 'Backspace') {\n const input = inputRef.current;\n if (input && input.selectionStart === 0 && input.selectionStart === input.selectionEnd) {\n event.preventDefault();\n window.setTimeout(() => adjustCursor(0), 0);\n }\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n if (selectAllOnFocus) {\n window.setTimeout(() => inputRef.current?.select(), 0);\n }\n onFocus?.(event);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n let sanitizedValue = _value;\n\n if (isBigIntMode) {\n if (clampBehavior === 'blur' && typeof sanitizedValue === 'bigint') {\n sanitizedValue = clampBigInt(sanitizedValue, minBigInt, maxBigInt);\n }\n\n if (trimLeadingZeroesOnBlur && typeof sanitizedValue === 'string') {\n sanitizedValue = clampAndSanitizeBigIntInput(sanitizedValue, {\n min: minBigInt,\n max: maxBigInt,\n clampBehavior,\n });\n }\n } else {\n if (clampBehavior === 'blur' && typeof sanitizedValue === 'number') {\n sanitizedValue = clamp(sanitizedValue, minNumber, maxNumber);\n }\n\n if (\n trimLeadingZeroesOnBlur &&\n typeof sanitizedValue === 'string' &&\n getDecimalPlaces(sanitizedValue) < 15\n ) {\n sanitizedValue = clampAndSanitizeInput(sanitizedValue, maxNumber, minNumber);\n }\n }\n\n if (_value !== sanitizedValue) {\n setValue(sanitizedValue);\n }\n\n onBlur?.(event);\n };\n\n assignRef(handlersRef, { increment: incrementRef.current, decrement: decrementRef.current });\n\n const onStepHandleChange = (isIncrement: boolean) => {\n if (isIncrement) {\n incrementRef.current?.();\n } else {\n decrementRef.current?.();\n }\n stepCountRef.current += 1;\n };\n\n const onStepLoop = (isIncrement: boolean) => {\n onStepHandleChange(isIncrement);\n\n if (shouldUseStepInterval) {\n const interval =\n typeof stepHoldInterval === 'number'\n ? stepHoldInterval\n : stepHoldInterval(stepCountRef.current);\n onStepTimeoutRef.current = window.setTimeout(() => onStepLoop(isIncrement), interval);\n }\n };\n\n const onStep = (\n event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,\n isIncrement: boolean\n ) => {\n event.preventDefault();\n inputRef.current?.focus();\n onStepHandleChange(isIncrement);\n if (shouldUseStepInterval) {\n onStepTimeoutRef.current = window.setTimeout(() => onStepLoop(isIncrement), stepHoldDelay);\n }\n };\n\n const onStepDone = () => {\n if (onStepTimeoutRef.current) {\n window.clearTimeout(onStepTimeoutRef.current);\n }\n onStepTimeoutRef.current = null;\n stepCountRef.current = 0;\n };\n\n const controls = (\n <div {...getStyles('controls')}>\n <UnstyledButton\n {...getStyles('control')}\n tabIndex={-1}\n aria-hidden\n disabled={\n disabled ||\n (typeof _value === 'number' && maxNumber !== undefined && _value >= maxNumber) ||\n (typeof _value === 'bigint' && maxBigInt !== undefined && _value >= maxBigInt)\n }\n mod={{ direction: 'up' }}\n onMouseDown={(event) => event.preventDefault()}\n onPointerDown={(event) => {\n onStep(event, true);\n }}\n onPointerUp={onStepDone}\n onPointerLeave={onStepDone}\n >\n <NumberInputChevron direction=\"up\" />\n </UnstyledButton>\n <UnstyledButton\n {...getStyles('control')}\n tabIndex={-1}\n aria-hidden\n disabled={\n disabled ||\n (typeof _value === 'number' && minNumber !== undefined && _value <= minNumber) ||\n (typeof _value === 'bigint' && minBigInt !== undefined && _value <= minBigInt)\n }\n mod={{ direction: 'down' }}\n onMouseDown={(event) => event.preventDefault()}\n onPointerDown={(event) => {\n onStep(event, false);\n }}\n onPointerUp={onStepDone}\n onPointerLeave={onStepDone}\n >\n <NumberInputChevron direction=\"down\" />\n </UnstyledButton>\n </div>\n );\n\n return (\n <InputBase\n component={NumericFormat}\n allowNegative={allowNegative}\n className={cx(classes.root, className)}\n size={size}\n {...others}\n inputMode={isBigIntMode ? 'numeric' : 'decimal'}\n readOnly={readOnly}\n disabled={disabled}\n value={typeof _value === 'bigint' ? _value.toString() : _value}\n getInputRef={useMergedRef(ref, inputRef)}\n onValueChange={handleValueChange}\n rightSection={\n hideControls ||\n readOnly ||\n !(isBigIntMode\n ? canStepBigInt(_value as bigint | string, allowNegativeResolved)\n : canStep(_value as number | string))\n ? rightSection\n : rightSection || controls\n }\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n __staticSelector=\"NumberInput\"\n decimalScale={isBigIntMode ? 0 : allowDecimal ? decimalScale : 0}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n onKeyDownCapture={handleKeyDownCapture}\n rightSectionPointerEvents={rightSectionPointerEvents ?? (disabled ? 'none' : undefined)}\n rightSectionWidth={rightSectionWidth ?? `var(--ni-right-section-width-${size || 'sm'})`}\n allowLeadingZeros={allowLeadingZeros}\n allowedDecimalSeparators={allowedDecimalSeparators}\n onBlur={handleBlur}\n attributes={attributes}\n isAllowed={(val) => {\n const userAllowed = isAllowed ? isAllowed(val) : true;\n if (!userAllowed) {\n return false;\n }\n\n if (clampBehavior !== 'strict') {\n return true;\n }\n\n if (!isBigIntMode) {\n return isInRange(val.floatValue, minNumber, maxNumber);\n }\n\n if (val.value === '' || val.value === '-') {\n return true;\n }\n\n const parsed = parseBigIntFromString(val.value);\n\n if (parsed === null) {\n return true;\n }\n\n return (\n (minBigInt === undefined || parsed >= minBigInt) &&\n (maxBigInt === undefined || parsed <= maxBigInt)\n );\n }}\n />\n );\n }\n);\n\nNumberInput.classes = { ...InputBase.classes, ...classes };\nNumberInput.varsResolver = varsResolver;\nNumberInput.displayName = '@mantine/core/NumberInput';\n\nexport namespace NumberInput {\n export type Props<T extends NumberInputNumericType = number> = NumberInputProps<T>;\n export type StylesNames = NumberInputStylesNames;\n export type Factory = NumberInputFactory;\n export type CssVariables = NumberInputCssVariables;\n export type Handlers = NumberInputHandlers;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,MAAM,4BAA4B;AAGlC,MAAM,sBAAsB;AAG5B,MAAM,uBAAuB;AAG7B,MAAM,kCAAkC;AAaxC,SAAS,eAAe,OAAgB;CACtC,OAAO,OAAO,UAAU,YAAY,UAAU,MAAM,CAAC,OAAO,MAAM,OAAO,KAAK,CAAC;AACjF;AAEA,SAAS,cAAc,OAAiC;CACtD,OAAO,OAAO,UAAU;AAC1B;AAEA,SAAS,QAAQ,OAAwB;CACvC,IAAI,OAAO,UAAU,UACnB,OAAO,QAAQ,OAAO;CAGxB,OAAO,UAAU,MAAO,eAAe,KAAK,KAAK,OAAO,KAAK,IAAI,OAAO;AAC1E;AAEA,SAAS,oBAAoB,OAAe,eAAwB;CAClE,IAAI,UAAU,IACZ,OAAO;CAGT,IAAI,UAAU,KACZ,OAAO;CAGT,IAAI,CAAC,iBAAiB,MAAM,WAAW,GAAG,GACxC,OAAO;CAGT,OAAO,UAAU,KAAK,KAAK;AAC7B;AAEA,SAAS,cAAc,OAAwB,eAAwB;CACrE,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,OAAO,UAAU,MAAM,oBAAoB,OAAO,aAAa;AACjE;AAEA,SAAS,sBAAsB,OAA8B;CAC3D,IAAI,CAAC,UAAU,KAAK,KAAK,GACvB,OAAO;CAGT,IAAI;EACF,OAAO,OAAO,KAAK;CACrB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,oBAAoB,OAAoC;CAC/D,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,OAAO,UAAU,KAAK,GAC/E,OAAO,OAAO,KAAK;AAIvB;AAEA,SAAS,YAAY,OAAe,KAAc,KAAc;CAC9D,IAAI,QAAQ,KAAA,KAAa,QAAQ,KAC/B,OAAO;CAGT,IAAI,QAAQ,KAAA,KAAa,QAAQ,KAC/B,OAAO;CAGT,OAAO;AACT;AAEA,SAAS,eAAe,YAAqC;CAG3D,OAAO,WAAW,SAAS,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;AAChD;AAEA,SAAS,cAAc,YAAgC,OAAqC;CAC1F,QACG,OAAO,eAAe,WACnB,aAAa,OAAO,mBACpB,CAAC,OAAO,MAAM,OAAO,UAAU,CAAC,MACpC,CAAC,OAAO,MAAM,UAAU,KACxB,eAAe,KAAK,IAAI,MACxB,UAAU;AAEd;AAEA,SAAS,UAAU,OAA2B,KAAyB,KAAyB;CAC9F,IAAI,UAAU,KAAA,GACZ,OAAO;CAMT,QAHiB,QAAQ,KAAA,KAAa,SAAS,SAC9B,QAAQ,KAAA,KAAa,SAAS;AAGjD;AAgIA,MAAM,eAAe;CACnB,MAAM;CACN,MAAM;CACN,eAAe;CACf,cAAc;CACd,eAAe;CACf,oBAAoB;CACpB,mBAAmB;CACnB,yBAAyB;CACzB,YAAY;CACZ,0BAA0B,CAAC,KAAK,GAAG;AACrC;AAEA,MAAM,eAAe,oBAAwC,GAAG,EAAE,YAAY,EAC5E,UAAU,EACR,qBAAqB,QAAQ,MAAM,iBAAiB,EACtD,EACF,EAAE;AAEF,SAAS,sBAAsB,gBAAiC,KAAc,KAAc;CAC1F,MAAM,cAAc,eAAe,SAAS;CAC5C,MAAM,8BAA8B,gCAAgC,KAAK,WAAW;CAEpF,MAAM,WAAW,YAAY,QAAQ,aAAa,EAAE;CACpD,MAAM,cAAc,WAAW,QAAQ;CAEvC,IAAI,OAAO,MAAM,WAAW,GAC1B,OAAO;CAGT,IAAI,cAAc,OAAO,kBACvB,OAAO,QAAQ,KAAA,IAAY,MAAM;CAGnC,MAAM,UAAU,MAAM,aAAa,KAAK,GAAG;CAE3C,IAAI,6BAEF,OAAO,GADe,QAAQ,SAAS,CAAC,CAAC,QAAQ,aAAa,EACxC,EAAE;CAG1B,OAAO;AACT;AAEA,SAAS,4BACP,gBACA,SACA;CACA,IAAI,mBAAmB,MAAM,mBAAmB,KAC9C,OAAO;CAGT,MAAM,SAAS,sBAAsB,cAAc;CAEnD,IAAI,WAAW,MACb,OAAO;CAGT,OAAO,QAAQ,kBAAkB,SAAS,YAAY,QAAQ,QAAQ,KAAK,QAAQ,GAAG,IAAI;AAC5F;AAEA,MAAa,cAAc,gBACmB,WAAgC;CAC1E,MAAM,QAAQ,SACZ;EAAC;EAAS;EAAgB;CAAa,GACvC,cACA,MACF;CACA,MAAM,EACJ,WACA,YACA,QACA,UACA,MACA,UACA,eACA,OACA,cACA,KACA,KACA,MACA,cACA,cACA,WACA,eACA,QACA,cACA,cACA,WACA,kBACA,aACA,YACA,UACA,2BACA,eACA,UACA,MACA,mBACA,kBACA,eACA,mBACA,oBACA,yBACA,0BACA,kBACA,cACA,cACA,SACA,YACA,KACA,GAAG,WACD;CACJ,MAAM,wBAAwB,iBAAiB;CAC/C,MAAM,4BAA4B,qBAAqB;CAEvD,MAAM,YAAY,UAA8B;EAC9C,MAAM;EACN,SAAA;EACO;EACP;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,oBAAoB,mBAAmB,qBAAyC;EACtF;EACA;EACO;CACT,CAAC;CAED,MAAM,eAAe,OACnB,cAAc,KAAK,KAAK,cAAc,YAAY,IAAI,WAAW,QACnE;CAEA,IAAI,cAAc,KAAK,GACrB,aAAa,UAAU;MAClB,IAAI,OAAO,UAAU,UAC1B,aAAa,UAAU;CAGzB,MAAM,eAAe,aAAa,YAAY;CAE9C,MAAM,CAAC,QAAQ,YAAY,gBAA0C;EAC5D;EACO;EACd,YAAY;EACF;CACZ,CAAC;CAED,MAAM,wBAAwB,kBAAkB,KAAA,KAAa,qBAAqB,KAAA;CAClF,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,mBAAmB,OAAsB,IAAI;CACnD,MAAM,eAAe,OAAe,CAAC;CAErC,MAAM,YAAY,OAAO,QAAQ,WAAW,MAAM,KAAA;CAClD,MAAM,YAAY,OAAO,QAAQ,WAAW,MAAM,KAAA;CAClD,MAAM,aAAa,OAAO,SAAS,WAAW,OAAO,aAAa;CAClE,MAAM,mBAAmB,OAAO,eAAe,WAAW,aAAa,aAAa;CAEpF,MAAM,YAAY,oBAAoB,GAAG;CACzC,MAAM,YAAY,oBAAoB,GAAG;CACzC,MAAM,aAAa,oBAAoB,IAAI,KAAK,OAAO,CAAC;CACxD,MAAM,mBAAmB,oBAAoB,UAAU,KAAK,OAAO,CAAC;CAEpE,MAAM,uBAAuB,eAAwC;EACnE,IACE,CAAC,oBAAoB,YAAY,qBAAqB,KACrD,6BAA6B,oBAAoB,KAAK,UAAU,GAEjE,OAAO;EAIT,OADe,sBAAsB,UACzB,KAAK;CACnB;CAEA,MAAM,uBAAuB,eAAuB;EAClD,MAAM,eAAe,OAAO,UAAU;EACtC,OAAO,OAAO,cAAc,YAAY,IAAI,eAAe,KAAA;CAC7D;CAEA,MAAM,qBAAoC,SAAS,UAAU;EAC3D,IAAI,MAAM,WAAW,SAAS;GAC5B,IAAI,cACF,SAAS,oBAAoB,QAAQ,KAAK,CAAC;QAE3C,SACE,cAAc,QAAQ,YAAY,QAAQ,KAAK,KAC7C,CAAC,0BAA0B,KAAK,QAAQ,KAAK,KAC7C,EAAE,4BAA4B,oBAAoB,KAAK,QAAQ,KAAK,IAAI,UACxE,CAAC,qBAAqB,KAAK,QAAQ,KAAK,KACxC,CAAC,gCAAgC,KAAK,QAAQ,KAAK,IACjD,QAAQ,aACR,QAAQ,KACd;EAEJ;EACA,gBAAgB,SAAS,KAAK;CAChC;CAEA,MAAM,oBAAoB,eAAwC;EAChE,MAAM,QAAQ,OAAO,UAAU,CAAC,CAAC,MAAM,kCAAkC;EACzE,IAAI,CAAC,OACH,OAAO;EAET,OAAO,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC,SAAS,MAAM,MAAM,KAAK,CAAC,MAAM,KAAK,EAAE;CAClF;CAEA,MAAM,gBAAgB,aAAsB;EAC1C,IAAI,SAAS,WAAW,OAAO,aAAa,aAC1C,SAAS,QAAQ,kBAAkB,UAAU,QAAQ;CAEzD;CAEA,MAAM,eAAe,OAAmB,IAAI;CAC5C,aAAa,gBAAgB;EAC3B,IAAI,cAAc;GAChB,IAAI,CAAC,cAAc,QAA2B,qBAAqB,GACjE;GAGF,IAAI;GACJ,MAAM,eAAe;GAErB,IAAI,OAAO,iBAAiB,UAAU;IACpC,MAAM,mBAAmB,eAAe;IACxC,IAAI,cAAc,KAAA,KAAa,mBAAmB,WAChD,eAAe;IAEjB,MACE,cAAc,KAAA,KAAa,mBAAmB,YAAY,YAAY;GAC1E,OAAO,IAAI,OAAO,iBAAiB,YAAY,iBAAiB,IAAI;IAClE,MAAM,SAAS,sBAAsB,YAAY;IACjD,IAAI,WAAW,MACb;IAGF,MAAM,mBAAmB,SAAS;IAClC,IAAI,cAAc,KAAA,KAAa,mBAAmB,WAChD,eAAe;IAEjB,MACE,cAAc,KAAA,KAAa,mBAAmB,YAAY,YAAY;GAC1E,OACE,MAAM,YAAY,kBAAkB,WAAW,SAAS;GAG1D,MAAM,iBAAiB,IAAI,SAAS;GACpC,SAAS,GAAG;GACZ,gBACE;IAAE,YAAY,oBAAoB,GAAG;IAAG;IAAgB,OAAO;GAAe,GAC9E,EAAE,QAAQ,YAAmB,CAC/B;GACA,iBAAiB,aAAa,SAAS,SAAS,MAAM,MAAM,GAAG,CAAC;GAChE;EACF;EAEA,IAAI,CAAC,QAAQ,MAAyB,GACpC;EAGF,IAAI;EACJ,MAAM,wBAAwB,iBAAiB,MAAyB;EACxE,MAAM,gBAAgB,iBAAiB,UAAU;EACjD,MAAM,eAAe,KAAK,IAAI,uBAAuB,aAAa;EAClE,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,eAAe,MAAM,MAAM,OAAO,WAAW,YAAY,OAAO,MAAM,MAAM,IAC/E,MAAM,MAAM,kBAAkB,WAAW,SAAS;OAC7C,IAAI,cAAc,KAAA,GAAW;GAClC,MAAM,oBACH,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,aAAa,MAAM,KAAK;GAC5E,IAAI,mBAAmB,WACrB,eAAe;GAEjB,MAAM,oBAAoB,YAAY,mBAAmB;EAC3D,OACE,OAAO,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,aAAa,MAAM,KAAK;EAGlF,MAAM,iBAAiB,IAAI,QAAQ,YAAY;EAC/C,SAAS,WAAW,cAAc,CAAC;EACnC,gBACE;GAAE,YAAY,WAAW,cAAc;GAAG;GAAgB,OAAO;EAAe,GAChF,EAAE,QAAQ,YAAmB,CAC/B;EACA,iBAAiB,aAAa,SAAS,SAAS,MAAM,MAAM,GAAG,CAAC;CAClE;CAEA,MAAM,eAAe,OAAmB,IAAI;CAC5C,aAAa,gBAAgB;EAC3B,IAAI,cAAc;GAChB,IAAI,CAAC,cAAc,QAA2B,qBAAqB,GACjE;GAGF,IAAI;GACJ,MAAM,WACJ,cAAc,KAAA,IAAY,YAAY,CAAC,wBAAwB,OAAO,CAAC,IAAI,KAAA;GAC7E,MAAM,eAAe;GAErB,IAAI,OAAO,iBAAiB,UAAU;IACpC,MAAM,mBAAmB,eAAe;IACxC,IAAI,aAAa,KAAA,KAAa,mBAAmB,UAC/C,eAAe;IAEjB,MAAM,aAAa,KAAA,KAAa,mBAAmB,WAAW,WAAW;GAC3E,OAAO,IAAI,OAAO,iBAAiB,YAAY,iBAAiB,IAAI;IAClE,MAAM,SAAS,sBAAsB,YAAY;IACjD,IAAI,WAAW,MACb;IAGF,MAAM,mBAAmB,SAAS;IAClC,IAAI,aAAa,KAAA,KAAa,mBAAmB,UAC/C,eAAe;IAEjB,MAAM,aAAa,KAAA,KAAa,mBAAmB,WAAW,WAAW;GAC3E,OACE,MAAM,YAAY,kBAAkB,UAAU,SAAS;GAGzD,MAAM,iBAAiB,IAAI,SAAS;GACpC,SAAS,GAAG;GACZ,gBACE;IAAE,YAAY,oBAAoB,GAAG;IAAG;IAAgB,OAAO;GAAe,GAC9E,EAAE,QAAQ,YAAmB,CAC/B;GACA,iBAAiB,aAAa,SAAS,SAAS,MAAM,MAAM,GAAG,CAAC;GAChE;EACF;EAEA,IAAI,CAAC,QAAQ,MAAyB,GACpC;EAGF,IAAI;EACJ,MAAM,WACJ,cAAc,KAAA,IAAY,YAAY,CAAC,wBAAwB,IAAI,OAAO;EAC5E,MAAM,wBAAwB,iBAAiB,MAAyB;EACxE,MAAM,gBAAgB,iBAAiB,UAAU;EACjD,MAAM,eAAe,KAAK,IAAI,uBAAuB,aAAa;EAClE,MAAM,SAAS,MAAM;EAErB,IAAK,CAAC,eAAe,MAAM,KAAK,OAAO,WAAW,YAAa,OAAO,MAAM,MAAM,GAChF,MAAM,MAAM,kBAAkB,UAAU,SAAS;OAC5C;GACL,MAAM,oBACH,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,aAAa,MAAM,KAAK;GAC5E,IAAI,aAAa,KAAA,KAAa,mBAAmB,UAC/C,eAAe;GAEjB,MAAM,aAAa,KAAA,KAAa,mBAAmB,WAAW,WAAW;EAC3E;EAEA,MAAM,iBAAiB,IAAI,QAAQ,YAAY;EAC/C,SAAS,WAAW,cAAc,CAAC;EACnC,gBACE;GAAE,YAAY,WAAW,cAAc;GAAG;GAAgB,OAAO;EAAe,GAChF,EAAE,QAAQ,YAAmB,CAC/B;EACA,iBAAiB,aAAa,SAAS,SAAS,MAAM,MAAM,GAAG,CAAC;CAClE;CAEA,MAAM,eAAe,UAAkD;EACrE,MAAM,aAAa,MAAM,cAAc,QAAQ,MAAM;EACrD,MAAM,oBAAoB,OAAO,oBAAoB;EACrD,MAAM,uBAAuB,4BAA4B,CAAC,KAAK,GAAG,EAAA,CAAG,QAClE,MAAM,MAAM,iBACf;EAEA,IAAI,oBAAoB,MAAM,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG;GAC3D,MAAM,eAAe;GACrB,IAAI,eAAe;GACnB,oBAAoB,SAAS,MAAM;IACjC,eAAe,aAAa,MAAM,CAAC,CAAC,CAAC,KAAK,iBAAiB;GAC7D,CAAC;GAED,MAAM,QAAQ,SAAS;GACvB,IAAI,OAAO;IACT,MAAM,QAAQ,MAAM,kBAAkB;IACtC,MAAM,MAAM,MAAM,gBAAgB;IAClC,MAAM,eAAe,MAAM;IAC3B,MAAM,WACJ,aAAa,UAAU,GAAG,KAAK,IAAI,eAAe,aAAa,UAAU,GAAG;IAM9E,CAJ+B,OAAO,yBACpC,OAAO,iBAAiB,WACxB,OACF,CAAC,EAAE,IAAA,EACqB,KAAK,OAAO,QAAQ;IAC5C,MAAM,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;IAE1D,MAAM,YAAY,QAAQ,aAAa;IACvC,iBAAiB,aAAa,SAAS,GAAG,CAAC;GAC7C;EACF;EAEA,OAAO,UAAU,KAAY;CAC/B;CAEA,MAAM,iBAAiB,UAAiD;EACtE,YAAY,KAAK;EAEjB,IAAI,YAAY,CAAC,oBACf;EAGF,IAAI,MAAM,QAAQ,WAAW;GAC3B,MAAM,eAAe;GACrB,aAAa,UAAU;EACzB;EAEA,IAAI,MAAM,QAAQ,aAAa;GAC7B,MAAM,eAAe;GACrB,aAAa,UAAU;EACzB;CACF;CAEA,MAAM,wBAAwB,UAAiD;EAC7E,mBAAmB,KAAK;EACxB,IAAI,MAAM,QAAQ,aAAa;GAC7B,MAAM,QAAQ,SAAS;GACvB,IAAI,SAAS,MAAM,mBAAmB,KAAK,MAAM,mBAAmB,MAAM,cAAc;IACtF,MAAM,eAAe;IACrB,OAAO,iBAAiB,aAAa,CAAC,GAAG,CAAC;GAC5C;EACF;CACF;CAEA,MAAM,eAAe,UAA8C;EACjE,IAAI,kBACF,OAAO,iBAAiB,SAAS,SAAS,OAAO,GAAG,CAAC;EAEvD,UAAU,KAAK;CACjB;CAEA,MAAM,cAAc,UAA8C;EAChE,IAAI,iBAAiB;EAErB,IAAI,cAAc;GAChB,IAAI,kBAAkB,UAAU,OAAO,mBAAmB,UACxD,iBAAiB,YAAY,gBAAgB,WAAW,SAAS;GAGnE,IAAI,2BAA2B,OAAO,mBAAmB,UACvD,iBAAiB,4BAA4B,gBAAgB;IAC3D,KAAK;IACL,KAAK;IACL;GACF,CAAC;EAEL,OAAO;GACL,IAAI,kBAAkB,UAAU,OAAO,mBAAmB,UACxD,iBAAiB,MAAM,gBAAgB,WAAW,SAAS;GAG7D,IACE,2BACA,OAAO,mBAAmB,YAC1B,iBAAiB,cAAc,IAAI,IAEnC,iBAAiB,sBAAsB,gBAAgB,WAAW,SAAS;EAE/E;EAEA,IAAI,WAAW,gBACb,SAAS,cAAc;EAGzB,SAAS,KAAK;CAChB;CAEA,UAAU,aAAa;EAAE,WAAW,aAAa;EAAS,WAAW,aAAa;CAAQ,CAAC;CAE3F,MAAM,sBAAsB,gBAAyB;EACnD,IAAI,aACF,aAAa,UAAU;OAEvB,aAAa,UAAU;EAEzB,aAAa,WAAW;CAC1B;CAEA,MAAM,cAAc,gBAAyB;EAC3C,mBAAmB,WAAW;EAE9B,IAAI,uBAAuB;GACzB,MAAM,WACJ,OAAO,qBAAqB,WACxB,mBACA,iBAAiB,aAAa,OAAO;GAC3C,iBAAiB,UAAU,OAAO,iBAAiB,WAAW,WAAW,GAAG,QAAQ;EACtF;CACF;CAEA,MAAM,UACJ,OACA,gBACG;EACH,MAAM,eAAe;EACrB,SAAS,SAAS,MAAM;EACxB,mBAAmB,WAAW;EAC9B,IAAI,uBACF,iBAAiB,UAAU,OAAO,iBAAiB,WAAW,WAAW,GAAG,aAAa;CAE7F;CAEA,MAAM,mBAAmB;EACvB,IAAI,iBAAiB,SACnB,OAAO,aAAa,iBAAiB,OAAO;EAE9C,iBAAiB,UAAU;EAC3B,aAAa,UAAU;CACzB;CAEA,MAAM,WACJ,qBAAC,OAAD;EAAK,GAAI,UAAU,UAAU;EAA7B,UAAA,CACE,oBAAC,gBAAD;GACE,GAAI,UAAU,SAAS;GACvB,UAAU;GACV,eAAA;GACA,UACE,YACC,OAAO,WAAW,YAAY,cAAc,KAAA,KAAa,UAAU,aACnE,OAAO,WAAW,YAAY,cAAc,KAAA,KAAa,UAAU;GAEtE,KAAK,EAAE,WAAW,KAAK;GACvB,cAAc,UAAU,MAAM,eAAe;GAC7C,gBAAgB,UAAU;IACxB,OAAO,OAAO,IAAI;GACpB;GACA,aAAa;GACb,gBAAgB;GAEhB,UAAA,oBAAC,oBAAD,EAAoB,WAAU,KAAM,CAAA;EACtB,CAAA,GAChB,oBAAC,gBAAD;GACE,GAAI,UAAU,SAAS;GACvB,UAAU;GACV,eAAA;GACA,UACE,YACC,OAAO,WAAW,YAAY,cAAc,KAAA,KAAa,UAAU,aACnE,OAAO,WAAW,YAAY,cAAc,KAAA,KAAa,UAAU;GAEtE,KAAK,EAAE,WAAW,OAAO;GACzB,cAAc,UAAU,MAAM,eAAe;GAC7C,gBAAgB,UAAU;IACxB,OAAO,OAAO,KAAK;GACrB;GACA,aAAa;GACb,gBAAgB;GAEhB,UAAA,oBAAC,oBAAD,EAAoB,WAAU,OAAQ,CAAA;EACxB,CAAA,CACb;;CAGP,OACE,oBAAC,WAAD;EACE,WAAW;EACI;EACf,WAAW,GAAGA,2BAAQ,MAAM,SAAS;EAC/B;EACN,GAAI;EACJ,WAAW,eAAe,YAAY;EAC5B;EACA;EACV,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,IAAI;EACxD,aAAa,aAAa,KAAK,QAAQ;EACvC,eAAe;EACf,cACE,gBACA,YACA,EAAE,eACE,cAAc,QAA2B,qBAAqB,IAC9D,QAAQ,MAAyB,KACjC,eACA,gBAAgB;EAEtB,YAAY;EACZ,QAAQ;EACE;EACV,kBAAiB;EACjB,cAAc,eAAe,IAAI,eAAe,eAAe;EAC/D,SAAS;EACT,SAAS;EACT,WAAW;EACX,kBAAkB;EAClB,2BAA2B,8BAA8B,WAAW,SAAS,KAAA;EAC7E,mBAAmB,qBAAqB,gCAAgC,QAAQ,KAAK;EAClE;EACO;EAC1B,QAAQ;EACI;EACZ,YAAY,QAAQ;GAElB,IAAI,EADgB,YAAY,UAAU,GAAG,IAAI,OAE/C,OAAO;GAGT,IAAI,kBAAkB,UACpB,OAAO;GAGT,IAAI,CAAC,cACH,OAAO,UAAU,IAAI,YAAY,WAAW,SAAS;GAGvD,IAAI,IAAI,UAAU,MAAM,IAAI,UAAU,KACpC,OAAO;GAGT,MAAM,SAAS,sBAAsB,IAAI,KAAK;GAE9C,IAAI,WAAW,MACb,OAAO;GAGT,QACG,cAAc,KAAA,KAAa,UAAU,eACrC,cAAc,KAAA,KAAa,UAAU;EAE1C;CACD,CAAA;AAEL,CACF;AAEA,YAAY,UAAU;CAAE,GAAG,UAAU;CAAS,GAAGA;AAAQ;AACzD,YAAY,eAAe;AAC3B,YAAY,cAAc"}
|
|
1
|
+
{"version":3,"file":"NumberInput.mjs","names":["classes"],"sources":["../../../src/components/NumberInput/NumberInput.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport cx from 'clsx';\nimport { NumberFormatValues, NumericFormat, OnValueChange } from 'react-number-format';\nimport { assignRef, clamp, useMergedRef, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n Factory,\n genericFactory,\n getSize,\n noop,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { __BaseInputProps, __InputStylesNames, InputVariant } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { UnstyledButton } from '../UnstyledButton';\nimport { getCaretPositionAfterPaste } from './get-caret-position-after-paste/get-caret-position-after-paste';\nimport { normalizePastedValue } from './normalize-pasted-value/normalize-pasted-value';\nimport { NumberInputChevron } from './NumberInputChevron';\nimport classes from './NumberInput.module.css';\n\n// Re for negative -0, -0., -0.0, -0.00, -0.000 ... strings\n// And for positive 0., 0.0, 0.00, 0.000 ... strings\nconst leadingDecimalZeroPattern = /^(0\\.0*|-0(\\.0*)?)$/;\n\n// Re for 01, 006, 00.02, -0010, -000.293 ... and negative counterparts\nconst leadingZerosPattern = /^-?0\\d+(\\.\\d+)?\\.?$/;\n\n// Re for decimal numbers with trailing zeros like 13.0, 13.00, 5.10 ... strings\nconst trailingZerosPattern = /\\.\\d*0$/;\n\n// Re for numbers with trailing decimal separator like 10. or -3.\nconst trailingDecimalSeparatorPattern = /^-?\\d+\\.$/;\n\nexport interface NumberInputHandlers {\n increment: () => void;\n decrement: () => void;\n}\n\nexport type NumberInputMode = 'number' | 'bigint';\nexport type NumberInputNumericType = number | bigint;\nexport type NumberInputValue<T extends NumberInputNumericType = number> = T | string;\ntype NumberInputNumericValue<T extends NumberInputNumericType = number> = T;\ntype InternalNumberInputValue = string | number | bigint;\n\nfunction isNumberString(value: unknown) {\n return typeof value === 'string' && value !== '' && !Number.isNaN(Number(value));\n}\n\nfunction isBigIntValue(value: unknown): value is bigint {\n return typeof value === 'bigint';\n}\n\nfunction canStep(value: number | string) {\n if (typeof value === 'number') {\n return value < Number.MAX_SAFE_INTEGER;\n }\n\n return value === '' || (isNumberString(value) && Number(value) < Number.MAX_SAFE_INTEGER);\n}\n\nfunction isValidBigIntString(value: string, allowNegative: boolean) {\n if (value === '') {\n return false;\n }\n\n if (value === '-') {\n return false;\n }\n\n if (!allowNegative && value.startsWith('-')) {\n return false;\n }\n\n return /^-?\\d+$/.test(value);\n}\n\nfunction canStepBigInt(value: bigint | string, allowNegative: boolean) {\n if (typeof value === 'bigint') {\n return true;\n }\n\n return value === '' || isValidBigIntString(value, allowNegative);\n}\n\nfunction parseBigIntFromString(value: string): bigint | null {\n if (!/^-?\\d+$/.test(value)) {\n return null;\n }\n\n try {\n return BigInt(value);\n } catch {\n return null;\n }\n}\n\nfunction toBigIntOrUndefined(value: unknown): bigint | undefined {\n if (typeof value === 'bigint') {\n return value;\n }\n\n if (typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value)) {\n return BigInt(value);\n }\n\n return undefined;\n}\n\nfunction clampBigInt(value: bigint, min?: bigint, max?: bigint) {\n if (min !== undefined && value < min) {\n return min;\n }\n\n if (max !== undefined && value > max) {\n return max;\n }\n\n return value;\n}\n\nfunction getTotalDigits(inputValue: string | number): number {\n // All digits must be counted, parseFloat precision depends\n // on the number of digits in the input, not only on the decimal scale\n return inputValue.toString().replace('.', '').length;\n}\n\nfunction isValidNumber(floatValue: number | undefined, value: string): floatValue is number {\n return (\n (typeof floatValue === 'number'\n ? floatValue < Number.MAX_SAFE_INTEGER\n : !Number.isNaN(Number(floatValue))) &&\n !Number.isNaN(floatValue) &&\n getTotalDigits(value) < 14 &&\n value !== ''\n );\n}\n\nfunction isInRange(value: number | undefined, min: number | undefined, max: number | undefined) {\n if (value === undefined) {\n return true;\n }\n\n const minValid = min === undefined || value >= min;\n const maxValid = max === undefined || value <= max;\n\n return minValid && maxValid;\n}\n\nexport type NumberInputStylesNames = 'controls' | 'control' | __InputStylesNames;\nexport type NumberInputCssVariables = {\n controls: '--ni-chevron-size';\n};\n\nexport interface NumberInputProps<T extends NumberInputNumericType = number>\n extends\n BoxProps,\n Omit<__BaseInputProps, 'pointer'>,\n StylesApiProps<NumberInputFactory>,\n ElementProps<\n 'input',\n 'size' | 'type' | 'onChange' | 'value' | 'defaultValue' | 'min' | 'max' | 'step'\n > {\n /** Controlled component value */\n value?: NumberInputValue<T>;\n\n /** Uncontrolled component default value */\n defaultValue?: NumberInputValue<T>;\n\n /** Called when value changes */\n onChange?: (value: NumberInputValue<T>) => void;\n\n /** Called when value changes with `react-number-format` payload */\n onValueChange?: OnValueChange;\n\n /** Determines whether leading zeros are allowed during input. If `false`, leading zeros are removed as you type (e.g., typing `007` results in `7`). Works in conjunction with `trimLeadingZeroesOnBlur`. @default true */\n allowLeadingZeros?: boolean;\n\n /** Determines whether negative numbers are allowed. If `false`, the input will not accept negative values, and the decrement button will stop at `0` (when `min` is not set). @default true */\n allowNegative?: boolean;\n\n /** Characters which when pressed result in a decimal separator. These characters will be replaced by the `decimalSeparator` in the input value. @default ['.', ','] */\n allowedDecimalSeparators?: string[];\n\n /** Limits the number of digits that can be entered after the decimal point @default Infinity */\n decimalScale?: number;\n\n /** Character used as a decimal separator. Generally used with `allowedDecimalSeparators` prop. @default '.' */\n decimalSeparator?: string;\n\n /** If `true`, automatically pads the decimal part with zeros to match `decimalScale` (e.g., with `decimalScale={2}`, typing `5.1` displays as `5.10`). Requires `decimalScale` to be set. @default false */\n fixedDecimalScale?: boolean;\n\n /** Prefix added before the input value */\n prefix?: string;\n\n /** Suffix added after the input value */\n suffix?: string;\n\n /** Defines the thousand grouping style. 'thousand' (1,000), 'lakh' (1,00,000), 'wan' (1,0000), 'none'. */\n thousandsGroupStyle?: 'thousand' | 'lakh' | 'wan' | 'none';\n\n /** A function to validate the input value. If this function returns `false`, the `onChange` will not be called and the input value will not change. */\n isAllowed?: (values: NumberFormatValues) => boolean;\n\n /** Advanced: Set to `true` if you're passing numeric strings (e.g., `\"12345\"`) and using formatting props like `prefix` or `suffix`. In most cases, you don't need this prop. See [react-number-format docs](https://www.npmjs.com/package/react-number-format) for details. @default false */\n valueIsNumericString?: boolean;\n\n /** Controls input `type` attribute @default 'text' */\n type?: 'text' | 'tel' | 'password';\n\n /** A character used to separate thousands */\n thousandSeparator?: string | boolean;\n\n /** Minimum possible value */\n min?: NumberInputNumericValue<T>;\n\n /** Maximum possible value */\n max?: NumberInputNumericValue<T>;\n\n /** Number by which value will be incremented/decremented with up/down controls and keyboard arrows @default 1 */\n step?: NumberInputNumericValue<T>;\n\n /** If set, the up/down controls are hidden @default false */\n hideControls?: boolean;\n\n /** Controls how values are clamped to the `min`/`max` range:\n * - `'blur'` (default): User can type any value, but it's clamped when the input loses focus\n * - `'strict'`: User cannot type values outside the range\n * - `'none'`: No clamping; `min`/`max` only apply to increment/decrement controls and arrow keys\n */\n clampBehavior?: 'strict' | 'blur' | 'none';\n\n /** If set, decimal values are allowed @default true */\n allowDecimal?: boolean;\n\n /** Increment/decrement handlers */\n handlersRef?: React.Ref<NumberInputHandlers | undefined>;\n\n /** Value used when incrementing/decrementing an empty input. If `min` is set and `startValue < min`, `min` is used instead. @default 0 */\n startValue?: NumberInputNumericValue<T>;\n\n /** Interval in milliseconds between value steps when increment/decrement button is held down. Can be a number or a function `(stepCount) => number` for dynamic intervals. Requires `stepHoldDelay` to be set. @default undefined */\n stepHoldInterval?: number | ((stepCount: number) => number);\n\n /** Initial delay in milliseconds before stepping the value. */\n stepHoldDelay?: number;\n\n /** If set, up/down keyboard events increment/decrement value @default true */\n withKeyboardEvents?: boolean;\n\n /** If set, leading zeros are removed on blur. For example, `00100` -> `100` @default true */\n trimLeadingZeroesOnBlur?: boolean;\n\n /** If set, all text is selected when the input receives focus @default false */\n selectAllOnFocus?: boolean;\n\n /** Called when the increment button or arrow up key is pressed and the value has reached the maximum */\n onMinReached?: () => void;\n\n /** Called when the decrement button or arrow down key is pressed and the value has reached the minimum */\n onMaxReached?: () => void;\n}\n\nexport type NumberInputFactory = Factory<{\n props: NumberInputProps;\n ref: HTMLInputElement;\n stylesNames: NumberInputStylesNames;\n vars: NumberInputCssVariables;\n variant: InputVariant;\n signature: <T extends NumberInputNumericType = number>(\n props: NumberInputProps<T>\n ) => React.JSX.Element;\n}>;\n\nconst defaultProps = {\n size: 'sm',\n step: 1,\n clampBehavior: 'blur',\n allowDecimal: true,\n allowNegative: true,\n withKeyboardEvents: true,\n allowLeadingZeros: true,\n trimLeadingZeroesOnBlur: true,\n startValue: 0,\n allowedDecimalSeparators: ['.', ','],\n} satisfies Partial<NumberInputProps<number | bigint>>;\n\nconst varsResolver = createVarsResolver<NumberInputFactory>((_, { size }) => ({\n controls: {\n '--ni-chevron-size': getSize(size, 'ni-chevron-size'),\n },\n}));\n\nfunction withTrailingSeparator(value: number, hasTrailingDecimalSeparator: boolean) {\n return hasTrailingDecimalSeparator ? `${value}.` : value;\n}\n\ninterface SanitizeInputOnBlurOptions {\n min: number | undefined;\n max: number | undefined;\n trim: boolean;\n clamp: boolean;\n}\n\nfunction sanitizeInputOnBlur(value: string, options: SanitizeInputOnBlurOptions) {\n const hasTrailingDecimalSeparator = trailingDecimalSeparatorPattern.test(value);\n const trimmed = options.trim ? value.replace(/^0+(?=\\d)/, '') : value;\n const parsedValue = parseFloat(trimmed);\n\n if (Number.isNaN(parsedValue)) {\n return trimmed;\n }\n\n if (!options.clamp) {\n return options.trim ? withTrailingSeparator(parsedValue, hasTrailingDecimalSeparator) : value;\n }\n\n const clamped =\n parsedValue > Number.MAX_SAFE_INTEGER && options.max !== undefined\n ? options.max\n : clamp(parsedValue, options.min, options.max);\n\n if (!options.trim && clamped === parsedValue) {\n return value;\n }\n\n return withTrailingSeparator(clamped, hasTrailingDecimalSeparator);\n}\n\nfunction clampAndSanitizeBigIntInput(\n sanitizedValue: string,\n options: { min?: bigint; max?: bigint; clampBehavior: NumberInputProps['clampBehavior'] }\n) {\n if (sanitizedValue === '' || sanitizedValue === '-') {\n return sanitizedValue;\n }\n\n const parsed = parseBigIntFromString(sanitizedValue);\n\n if (parsed === null) {\n return sanitizedValue;\n }\n\n return options.clampBehavior === 'blur' ? clampBigInt(parsed, options.min, options.max) : parsed;\n}\n\nexport const NumberInput = genericFactory<NumberInputFactory>(\n <T extends NumberInputNumericType = number>(_props: NumberInputProps<T>) => {\n const props = useProps(\n ['Input', 'InputWrapper', 'NumberInput'],\n defaultProps as Partial<NumberInputProps>,\n _props as unknown as NumberInputProps\n );\n const {\n className,\n classNames,\n styles,\n unstyled,\n vars,\n onChange,\n onValueChange,\n value,\n defaultValue,\n max,\n min,\n step,\n hideControls,\n rightSection,\n isAllowed,\n clampBehavior,\n onBlur,\n allowDecimal,\n decimalScale,\n onKeyDown,\n onKeyDownCapture,\n handlersRef,\n startValue,\n disabled,\n rightSectionPointerEvents,\n allowNegative,\n readOnly,\n size,\n rightSectionWidth,\n stepHoldInterval,\n stepHoldDelay,\n allowLeadingZeros,\n withKeyboardEvents,\n trimLeadingZeroesOnBlur,\n allowedDecimalSeparators,\n selectAllOnFocus,\n onMinReached,\n onMaxReached,\n onFocus,\n attributes,\n ref,\n ...others\n } = props;\n const allowNegativeResolved = allowNegative ?? true;\n const allowLeadingZerosResolved = allowLeadingZeros ?? true;\n\n const getStyles = useStyles<NumberInputFactory>({\n name: 'NumberInput',\n classes,\n props: props as NumberInputProps,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<NumberInputFactory>({\n classNames,\n styles,\n props: props as NumberInputProps,\n });\n\n const valueModeRef = useRef<NumberInputMode>(\n isBigIntValue(value) || isBigIntValue(defaultValue) ? 'bigint' : 'number'\n );\n\n if (isBigIntValue(value)) {\n valueModeRef.current = 'bigint';\n } else if (typeof value === 'number') {\n valueModeRef.current = 'number';\n }\n\n const isBigIntMode = valueModeRef.current === 'bigint';\n\n const [_value, setValue] = useUncontrolled<InternalNumberInputValue>({\n value: value as InternalNumberInputValue | undefined,\n defaultValue: defaultValue as InternalNumberInputValue | undefined,\n finalValue: '',\n onChange: onChange as ((value: InternalNumberInputValue) => void) | undefined,\n });\n\n const shouldUseStepInterval = stepHoldDelay !== undefined && stepHoldInterval !== undefined;\n const inputRef = useRef<HTMLInputElement>(null);\n const onStepTimeoutRef = useRef<number | null>(null);\n const stepCountRef = useRef<number>(0);\n\n const minNumber = typeof min === 'number' ? min : undefined;\n const maxNumber = typeof max === 'number' ? max : undefined;\n const stepNumber = typeof step === 'number' ? step : defaultProps.step;\n const startValueNumber = typeof startValue === 'number' ? startValue : defaultProps.startValue;\n\n const minBigInt = toBigIntOrUndefined(min);\n const maxBigInt = toBigIntOrUndefined(max);\n const stepBigInt = toBigIntOrUndefined(step) ?? BigInt(1);\n const startValueBigInt = toBigIntOrUndefined(startValue) ?? BigInt(0);\n\n const parseBigIntOrString = (inputValue: string): bigint | string => {\n if (\n !isValidBigIntString(inputValue, allowNegativeResolved) ||\n (allowLeadingZerosResolved && leadingZerosPattern.test(inputValue))\n ) {\n return inputValue;\n }\n\n const parsed = parseBigIntFromString(inputValue);\n return parsed ?? inputValue;\n };\n\n const getBigIntFloatValue = (inputValue: bigint) => {\n const numericValue = Number(inputValue);\n return Number.isSafeInteger(numericValue) ? numericValue : undefined;\n };\n\n const handleValueChange: OnValueChange = (payload, event) => {\n if (event.source === 'event') {\n if (isBigIntMode) {\n setValue(parseBigIntOrString(payload.value));\n } else {\n setValue(\n isValidNumber(payload.floatValue, payload.value) &&\n !leadingDecimalZeroPattern.test(payload.value) &&\n !(allowLeadingZerosResolved ? leadingZerosPattern.test(payload.value) : false) &&\n !trailingZerosPattern.test(payload.value) &&\n !trailingDecimalSeparatorPattern.test(payload.value)\n ? payload.floatValue\n : payload.value\n );\n }\n }\n onValueChange?.(payload, event);\n };\n\n const getDecimalPlaces = (inputValue: number | string): number => {\n const match = String(inputValue).match(/(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/);\n if (!match) {\n return 0;\n }\n return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));\n };\n\n const adjustCursor = (position?: number) => {\n if (inputRef.current && typeof position !== 'undefined') {\n inputRef.current.setSelectionRange(position, position);\n }\n };\n\n const incrementRef = useRef<() => void>(noop);\n incrementRef.current = () => {\n if (isBigIntMode) {\n if (!canStepBigInt(_value as bigint | string, allowNegativeResolved)) {\n return;\n }\n\n let val: bigint;\n const currentValue = _value;\n\n if (typeof currentValue === 'bigint') {\n const incrementedValue = currentValue + stepBigInt;\n if (maxBigInt !== undefined && incrementedValue > maxBigInt) {\n onMaxReached?.();\n }\n val =\n maxBigInt !== undefined && incrementedValue > maxBigInt ? maxBigInt : incrementedValue;\n } else if (typeof currentValue === 'string' && currentValue !== '') {\n const parsed = parseBigIntFromString(currentValue);\n if (parsed === null) {\n return;\n }\n\n const incrementedValue = parsed + stepBigInt;\n if (maxBigInt !== undefined && incrementedValue > maxBigInt) {\n onMaxReached?.();\n }\n val =\n maxBigInt !== undefined && incrementedValue > maxBigInt ? maxBigInt : incrementedValue;\n } else {\n val = clampBigInt(startValueBigInt, minBigInt, maxBigInt);\n }\n\n const formattedValue = val.toString();\n setValue(val);\n onValueChange?.(\n { floatValue: getBigIntFloatValue(val), formattedValue, value: formattedValue },\n { source: 'increment' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n return;\n }\n\n if (!canStep(_value as number | string)) {\n return;\n }\n\n let val: number;\n const currentValuePrecision = getDecimalPlaces(_value as number | string);\n const stepPrecision = getDecimalPlaces(stepNumber);\n const maxPrecision = Math.max(currentValuePrecision, stepPrecision);\n const factor = 10 ** maxPrecision;\n\n if (!isNumberString(_value) && (typeof _value !== 'number' || Number.isNaN(_value))) {\n val = clamp(startValueNumber, minNumber, maxNumber);\n } else if (maxNumber !== undefined) {\n const incrementedValue =\n (Math.round(Number(_value) * factor) + Math.round(stepNumber * factor)) / factor;\n if (incrementedValue > maxNumber) {\n onMaxReached?.();\n }\n val = incrementedValue <= maxNumber ? incrementedValue : maxNumber;\n } else {\n val = (Math.round(Number(_value) * factor) + Math.round(stepNumber * factor)) / factor;\n }\n\n const formattedValue = val.toFixed(maxPrecision);\n setValue(parseFloat(formattedValue));\n onValueChange?.(\n { floatValue: parseFloat(formattedValue), formattedValue, value: formattedValue },\n { source: 'increment' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n };\n\n const decrementRef = useRef<() => void>(noop);\n decrementRef.current = () => {\n if (isBigIntMode) {\n if (!canStepBigInt(_value as bigint | string, allowNegativeResolved)) {\n return;\n }\n\n let val: bigint;\n const minValue =\n minBigInt !== undefined ? minBigInt : !allowNegativeResolved ? BigInt(0) : undefined;\n const currentValue = _value;\n\n if (typeof currentValue === 'bigint') {\n const decrementedValue = currentValue - stepBigInt;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n } else if (typeof currentValue === 'string' && currentValue !== '') {\n const parsed = parseBigIntFromString(currentValue);\n if (parsed === null) {\n return;\n }\n\n const decrementedValue = parsed - stepBigInt;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n } else {\n val = clampBigInt(startValueBigInt, minValue, maxBigInt);\n }\n\n const formattedValue = val.toString();\n setValue(val);\n onValueChange?.(\n { floatValue: getBigIntFloatValue(val), formattedValue, value: formattedValue },\n { source: 'decrement' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n return;\n }\n\n if (!canStep(_value as number | string)) {\n return;\n }\n\n let val: number;\n const minValue =\n minNumber !== undefined ? minNumber : !allowNegativeResolved ? 0 : Number.MIN_SAFE_INTEGER;\n const currentValuePrecision = getDecimalPlaces(_value as number | string);\n const stepPrecision = getDecimalPlaces(stepNumber);\n const maxPrecision = Math.max(currentValuePrecision, stepPrecision);\n const factor = 10 ** maxPrecision;\n\n if ((!isNumberString(_value) && typeof _value !== 'number') || Number.isNaN(_value)) {\n val = clamp(startValueNumber, minValue, maxNumber);\n } else {\n const decrementedValue =\n (Math.round(Number(_value) * factor) - Math.round(stepNumber * factor)) / factor;\n if (minValue !== undefined && decrementedValue < minValue) {\n onMinReached?.();\n }\n val = minValue !== undefined && decrementedValue < minValue ? minValue : decrementedValue;\n }\n\n const formattedValue = val.toFixed(maxPrecision);\n setValue(parseFloat(formattedValue));\n onValueChange?.(\n { floatValue: parseFloat(formattedValue), formattedValue, value: formattedValue },\n { source: 'decrement' as any }\n );\n setTimeout(() => adjustCursor(inputRef.current?.value.length), 0);\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n const pastedText = event.clipboardData.getData('text');\n const _decimalSeparator = others.decimalSeparator || '.';\n const _thousandSeparator =\n others.thousandSeparator === true\n ? ','\n : others.thousandSeparator === false\n ? undefined\n : others.thousandSeparator;\n const modifiedText = normalizePastedValue(pastedText, {\n decimalSeparator: _decimalSeparator,\n thousandSeparator: _thousandSeparator,\n allowedDecimalSeparators: allowedDecimalSeparators || ['.', ','],\n thousandsGroupStyle: others.thousandsGroupStyle,\n });\n\n if (modifiedText !== pastedText) {\n event.preventDefault();\n\n const input = inputRef.current;\n if (input) {\n const start = input.selectionStart ?? 0;\n const end = input.selectionEnd ?? 0;\n const currentValue = input.value;\n const newValue =\n currentValue.substring(0, start) + modifiedText + currentValue.substring(end);\n\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value'\n )?.set;\n nativeInputValueSetter?.call(input, newValue);\n input.dispatchEvent(new Event('change', { bubbles: true }));\n\n const rawCaret = start + modifiedText.length;\n setTimeout(\n () =>\n adjustCursor(\n getCaretPositionAfterPaste(newValue, rawCaret, input.value, _decimalSeparator)\n ),\n 0\n );\n }\n }\n\n others.onPaste?.(event as any);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n\n if (readOnly || !withKeyboardEvents) {\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n incrementRef.current?.();\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n decrementRef.current?.();\n }\n };\n\n const handleKeyDownCapture = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDownCapture?.(event);\n if (event.key === 'Backspace') {\n const input = inputRef.current;\n if (input && input.selectionStart === 0 && input.selectionStart === input.selectionEnd) {\n event.preventDefault();\n window.setTimeout(() => adjustCursor(0), 0);\n }\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n if (selectAllOnFocus) {\n window.setTimeout(() => inputRef.current?.select(), 0);\n }\n onFocus?.(event);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n let sanitizedValue = _value;\n\n if (isBigIntMode) {\n if (clampBehavior === 'blur' && typeof sanitizedValue === 'bigint') {\n sanitizedValue = clampBigInt(sanitizedValue, minBigInt, maxBigInt);\n }\n\n if (trimLeadingZeroesOnBlur && typeof sanitizedValue === 'string') {\n sanitizedValue = clampAndSanitizeBigIntInput(sanitizedValue, {\n min: minBigInt,\n max: maxBigInt,\n clampBehavior,\n });\n }\n } else if (typeof sanitizedValue === 'number') {\n if (clampBehavior === 'blur') {\n sanitizedValue = clamp(sanitizedValue, minNumber, maxNumber);\n }\n } else if (typeof sanitizedValue === 'string') {\n sanitizedValue = sanitizeInputOnBlur(sanitizedValue, {\n min: minNumber,\n max: maxNumber,\n trim: !!trimLeadingZeroesOnBlur && getDecimalPlaces(sanitizedValue) < 15,\n clamp: clampBehavior === 'blur',\n });\n }\n\n if (_value !== sanitizedValue) {\n setValue(sanitizedValue);\n }\n\n onBlur?.(event);\n };\n\n assignRef(handlersRef, { increment: incrementRef.current, decrement: decrementRef.current });\n\n const onStepHandleChange = (isIncrement: boolean) => {\n if (isIncrement) {\n incrementRef.current?.();\n } else {\n decrementRef.current?.();\n }\n stepCountRef.current += 1;\n };\n\n const onStepLoop = (isIncrement: boolean) => {\n onStepHandleChange(isIncrement);\n\n if (shouldUseStepInterval) {\n const interval =\n typeof stepHoldInterval === 'number'\n ? stepHoldInterval\n : stepHoldInterval(stepCountRef.current);\n onStepTimeoutRef.current = window.setTimeout(() => onStepLoop(isIncrement), interval);\n }\n };\n\n const onStep = (\n event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,\n isIncrement: boolean\n ) => {\n event.preventDefault();\n inputRef.current?.focus();\n onStepHandleChange(isIncrement);\n if (shouldUseStepInterval) {\n onStepTimeoutRef.current = window.setTimeout(() => onStepLoop(isIncrement), stepHoldDelay);\n }\n };\n\n const onStepDone = () => {\n if (onStepTimeoutRef.current) {\n window.clearTimeout(onStepTimeoutRef.current);\n }\n onStepTimeoutRef.current = null;\n stepCountRef.current = 0;\n };\n\n const controls = (\n <div {...getStyles('controls')}>\n <UnstyledButton\n {...getStyles('control')}\n tabIndex={-1}\n aria-hidden\n disabled={\n disabled ||\n (typeof _value === 'number' && maxNumber !== undefined && _value >= maxNumber) ||\n (typeof _value === 'bigint' && maxBigInt !== undefined && _value >= maxBigInt)\n }\n mod={{ direction: 'up' }}\n onMouseDown={(event) => event.preventDefault()}\n onPointerDown={(event) => {\n onStep(event, true);\n }}\n onPointerUp={onStepDone}\n onPointerLeave={onStepDone}\n >\n <NumberInputChevron direction=\"up\" />\n </UnstyledButton>\n <UnstyledButton\n {...getStyles('control')}\n tabIndex={-1}\n aria-hidden\n disabled={\n disabled ||\n (typeof _value === 'number' && minNumber !== undefined && _value <= minNumber) ||\n (typeof _value === 'bigint' && minBigInt !== undefined && _value <= minBigInt)\n }\n mod={{ direction: 'down' }}\n onMouseDown={(event) => event.preventDefault()}\n onPointerDown={(event) => {\n onStep(event, false);\n }}\n onPointerUp={onStepDone}\n onPointerLeave={onStepDone}\n >\n <NumberInputChevron direction=\"down\" />\n </UnstyledButton>\n </div>\n );\n\n return (\n <InputBase\n component={NumericFormat}\n allowNegative={allowNegative}\n className={cx(classes.root, className)}\n size={size}\n {...others}\n inputMode={isBigIntMode ? 'numeric' : 'decimal'}\n readOnly={readOnly}\n disabled={disabled}\n value={typeof _value === 'bigint' ? _value.toString() : _value}\n getInputRef={useMergedRef(ref, inputRef)}\n onValueChange={handleValueChange}\n rightSection={\n hideControls ||\n readOnly ||\n !(isBigIntMode\n ? canStepBigInt(_value as bigint | string, allowNegativeResolved)\n : canStep(_value as number | string))\n ? rightSection\n : rightSection || controls\n }\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n __staticSelector=\"NumberInput\"\n decimalScale={isBigIntMode ? 0 : allowDecimal ? decimalScale : 0}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n onKeyDownCapture={handleKeyDownCapture}\n rightSectionPointerEvents={rightSectionPointerEvents ?? (disabled ? 'none' : undefined)}\n rightSectionWidth={rightSectionWidth ?? `var(--ni-right-section-width-${size || 'sm'})`}\n allowLeadingZeros={allowLeadingZeros}\n allowedDecimalSeparators={allowedDecimalSeparators}\n onBlur={handleBlur}\n attributes={attributes}\n isAllowed={(val) => {\n const userAllowed = isAllowed ? isAllowed(val) : true;\n if (!userAllowed) {\n return false;\n }\n\n if (clampBehavior !== 'strict') {\n return true;\n }\n\n if (!isBigIntMode) {\n return isInRange(val.floatValue, minNumber, maxNumber);\n }\n\n if (val.value === '' || val.value === '-') {\n return true;\n }\n\n const parsed = parseBigIntFromString(val.value);\n\n if (parsed === null) {\n return true;\n }\n\n return (\n (minBigInt === undefined || parsed >= minBigInt) &&\n (maxBigInt === undefined || parsed <= maxBigInt)\n );\n }}\n />\n );\n }\n);\n\nNumberInput.classes = { ...InputBase.classes, ...classes };\nNumberInput.varsResolver = varsResolver;\nNumberInput.displayName = '@mantine/core/NumberInput';\n\nexport namespace NumberInput {\n export type Props<T extends NumberInputNumericType = number> = NumberInputProps<T>;\n export type StylesNames = NumberInputStylesNames;\n export type Factory = NumberInputFactory;\n export type CssVariables = NumberInputCssVariables;\n export type Handlers = NumberInputHandlers;\n}\n"],"mappings":"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"}
|
package/esm/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.ts
|
|
3
|
+
function isSignificant(char, decimalSeparator) {
|
|
4
|
+
return /\d/.test(char) || char === decimalSeparator;
|
|
5
|
+
}
|
|
6
|
+
function getCaretPositionAfterPaste(rawValue, rawCaret, formattedValue, decimalSeparator) {
|
|
7
|
+
let remaining = 0;
|
|
8
|
+
for (let i = 0; i < rawCaret && i < rawValue.length; i += 1) if (isSignificant(rawValue[i], decimalSeparator)) remaining += 1;
|
|
9
|
+
if (remaining === 0) return Math.min(rawCaret, formattedValue.length);
|
|
10
|
+
for (let i = 0; i < formattedValue.length; i += 1) if (isSignificant(formattedValue[i], decimalSeparator)) {
|
|
11
|
+
remaining -= 1;
|
|
12
|
+
if (remaining === 0) return i + 1;
|
|
13
|
+
}
|
|
14
|
+
return formattedValue.length;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getCaretPositionAfterPaste };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=get-caret-position-after-paste.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-caret-position-after-paste.mjs","names":[],"sources":["../../../../src/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.ts"],"sourcesContent":["function isSignificant(char: string, decimalSeparator: string) {\n return /\\d/.test(char) || char === decimalSeparator;\n}\n\nexport function getCaretPositionAfterPaste(\n rawValue: string,\n rawCaret: number,\n formattedValue: string,\n decimalSeparator: string\n) {\n let remaining = 0;\n for (let i = 0; i < rawCaret && i < rawValue.length; i += 1) {\n if (isSignificant(rawValue[i], decimalSeparator)) {\n remaining += 1;\n }\n }\n\n if (remaining === 0) {\n return Math.min(rawCaret, formattedValue.length);\n }\n\n for (let i = 0; i < formattedValue.length; i += 1) {\n if (isSignificant(formattedValue[i], decimalSeparator)) {\n remaining -= 1;\n if (remaining === 0) {\n return i + 1;\n }\n }\n }\n\n return formattedValue.length;\n}\n"],"mappings":";;AAAA,SAAS,cAAc,MAAc,kBAA0B;CAC7D,OAAO,KAAK,KAAK,IAAI,KAAK,SAAS;AACrC;AAEA,SAAgB,2BACd,UACA,UACA,gBACA,kBACA;CACA,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,IAAI,SAAS,QAAQ,KAAK,GACxD,IAAI,cAAc,SAAS,IAAI,gBAAgB,GAC7C,aAAa;CAIjB,IAAI,cAAc,GAChB,OAAO,KAAK,IAAI,UAAU,eAAe,MAAM;CAGjD,KAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK,GAC9C,IAAI,cAAc,eAAe,IAAI,gBAAgB,GAAG;EACtD,aAAa;EACb,IAAI,cAAc,GAChB,OAAO,IAAI;CAEf;CAGF,OAAO,eAAe;AACxB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/NumberInput/normalize-pasted-value/normalize-pasted-value.ts
|
|
3
|
+
function countTrailingDigits(value, from) {
|
|
4
|
+
let count = 0;
|
|
5
|
+
while (from + count < value.length && /\d/.test(value[from + count])) count += 1;
|
|
6
|
+
return count;
|
|
7
|
+
}
|
|
8
|
+
function normalizePastedValue(value, { decimalSeparator, thousandSeparator, allowedDecimalSeparators, thousandsGroupStyle }) {
|
|
9
|
+
const candidates = new Set([...allowedDecimalSeparators, decimalSeparator].filter((s) => s.length === 1));
|
|
10
|
+
const chars = value.split("");
|
|
11
|
+
const occurrences = chars.reduce((acc, char, index) => {
|
|
12
|
+
if (candidates.has(char)) acc.push(index);
|
|
13
|
+
return acc;
|
|
14
|
+
}, []);
|
|
15
|
+
if (occurrences.length === 0) return value;
|
|
16
|
+
const lastIndex = occurrences[occurrences.length - 1];
|
|
17
|
+
const lastChar = chars[lastIndex];
|
|
18
|
+
const lastCharCount = occurrences.filter((index) => chars[index] === lastChar).length;
|
|
19
|
+
const lastGroupSize = thousandsGroupStyle === "wan" ? 4 : 3;
|
|
20
|
+
let decimalIndex = -1;
|
|
21
|
+
if (lastCharCount === 1) {
|
|
22
|
+
if (lastChar === decimalSeparator) decimalIndex = lastIndex;
|
|
23
|
+
else if (lastChar === thousandSeparator) decimalIndex = countTrailingDigits(value, lastIndex + 1) === lastGroupSize ? -1 : lastIndex;
|
|
24
|
+
else decimalIndex = lastIndex;
|
|
25
|
+
}
|
|
26
|
+
return chars.map((char, index) => {
|
|
27
|
+
if (index === decimalIndex) return decimalSeparator;
|
|
28
|
+
if (candidates.has(char) && char !== thousandSeparator) return "";
|
|
29
|
+
return char;
|
|
30
|
+
}).join("");
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { normalizePastedValue };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=normalize-pasted-value.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-pasted-value.mjs","names":[],"sources":["../../../../src/components/NumberInput/normalize-pasted-value/normalize-pasted-value.ts"],"sourcesContent":["export interface NormalizePastedValueOptions {\n decimalSeparator: string;\n thousandSeparator?: string;\n allowedDecimalSeparators: string[];\n thousandsGroupStyle?: 'thousand' | 'lakh' | 'wan' | 'none';\n}\n\nfunction countTrailingDigits(value: string, from: number) {\n let count = 0;\n while (from + count < value.length && /\\d/.test(value[from + count])) {\n count += 1;\n }\n return count;\n}\n\nexport function normalizePastedValue(\n value: string,\n {\n decimalSeparator,\n thousandSeparator,\n allowedDecimalSeparators,\n thousandsGroupStyle,\n }: NormalizePastedValueOptions\n) {\n const candidates = new Set(\n [...allowedDecimalSeparators, decimalSeparator].filter((s) => s.length === 1)\n );\n const chars = value.split('');\n const occurrences = chars.reduce<number[]>((acc, char, index) => {\n if (candidates.has(char)) {\n acc.push(index);\n }\n return acc;\n }, []);\n\n if (occurrences.length === 0) {\n return value;\n }\n\n const lastIndex = occurrences[occurrences.length - 1];\n const lastChar = chars[lastIndex];\n const lastCharCount = occurrences.filter((index) => chars[index] === lastChar).length;\n const lastGroupSize = thousandsGroupStyle === 'wan' ? 4 : 3;\n\n let decimalIndex = -1;\n if (lastCharCount === 1) {\n if (lastChar === decimalSeparator) {\n decimalIndex = lastIndex;\n } else if (lastChar === thousandSeparator) {\n decimalIndex = countTrailingDigits(value, lastIndex + 1) === lastGroupSize ? -1 : lastIndex;\n } else {\n decimalIndex = lastIndex;\n }\n }\n\n return chars\n .map((char, index) => {\n if (index === decimalIndex) {\n return decimalSeparator;\n }\n\n if (candidates.has(char) && char !== thousandSeparator) {\n return '';\n }\n\n return char;\n })\n .join('');\n}\n"],"mappings":";;AAOA,SAAS,oBAAoB,OAAe,MAAc;CACxD,IAAI,QAAQ;CACZ,OAAO,OAAO,QAAQ,MAAM,UAAU,KAAK,KAAK,MAAM,OAAO,MAAM,GACjE,SAAS;CAEX,OAAO;AACT;AAEA,SAAgB,qBACd,OACA,EACE,kBACA,mBACA,0BACA,uBAEF;CACA,MAAM,aAAa,IAAI,IACrB,CAAC,GAAG,0BAA0B,gBAAgB,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,CAAC,CAC9E;CACA,MAAM,QAAQ,MAAM,MAAM,EAAE;CAC5B,MAAM,cAAc,MAAM,QAAkB,KAAK,MAAM,UAAU;EAC/D,IAAI,WAAW,IAAI,IAAI,GACrB,IAAI,KAAK,KAAK;EAEhB,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,IAAI,YAAY,WAAW,GACzB,OAAO;CAGT,MAAM,YAAY,YAAY,YAAY,SAAS;CACnD,MAAM,WAAW,MAAM;CACvB,MAAM,gBAAgB,YAAY,QAAQ,UAAU,MAAM,WAAW,QAAQ,CAAC,CAAC;CAC/E,MAAM,gBAAgB,wBAAwB,QAAQ,IAAI;CAE1D,IAAI,eAAe;CACnB,IAAI,kBAAkB,GAAG;EACvB,IAAI,aAAa,kBACf,eAAe;OACV,IAAI,aAAa,mBACtB,eAAe,oBAAoB,OAAO,YAAY,CAAC,MAAM,gBAAgB,KAAK;OAElF,eAAe;CAEnB;CAEA,OAAO,MACJ,KAAK,MAAM,UAAU;EACpB,IAAI,UAAU,cACZ,OAAO;EAGT,IAAI,WAAW,IAAI,IAAI,KAAK,SAAS,mBACnC,OAAO;EAGT,OAAO;CACT,CAAC,CAAC,CACD,KAAK,EAAE;AACZ"}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
|
-
import { flushSync } from "react-dom";
|
|
4
3
|
//#region packages/@mantine/core/src/components/OverflowList/use-dimensions.tsx
|
|
5
4
|
function useDimensions(elementRef) {
|
|
6
5
|
const resizeObserverRef = useRef(null);
|
|
7
6
|
const [dimensions, setDimensions] = useState(null);
|
|
8
7
|
useEffect(() => {
|
|
9
8
|
if (!elementRef.current) return;
|
|
9
|
+
let frame = 0;
|
|
10
10
|
resizeObserverRef.current = new ResizeObserver((entries) => {
|
|
11
11
|
if (entries[0]) {
|
|
12
12
|
const entry = entries[0];
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
contentHeight: entry.contentRect.height
|
|
19
|
-
});
|
|
13
|
+
const nextDimensions = {
|
|
14
|
+
width: entry.borderBoxSize[0]?.inlineSize ?? entry.target.clientWidth,
|
|
15
|
+
height: entry.borderBoxSize[0]?.blockSize ?? entry.target.clientHeight,
|
|
16
|
+
contentWidth: entry.contentRect.width,
|
|
17
|
+
contentHeight: entry.contentRect.height
|
|
20
18
|
};
|
|
21
|
-
|
|
19
|
+
cancelAnimationFrame(frame);
|
|
20
|
+
frame = requestAnimationFrame(() => setDimensions(nextDimensions));
|
|
22
21
|
}
|
|
23
22
|
});
|
|
24
23
|
resizeObserverRef.current.observe(elementRef.current);
|
|
25
24
|
return () => {
|
|
25
|
+
cancelAnimationFrame(frame);
|
|
26
26
|
if (resizeObserverRef.current) {
|
|
27
27
|
resizeObserverRef.current.disconnect();
|
|
28
28
|
resizeObserverRef.current = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-dimensions.mjs","names":[],"sources":["../../../src/components/OverflowList/use-dimensions.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\
|
|
1
|
+
{"version":3,"file":"use-dimensions.mjs","names":[],"sources":["../../../src/components/OverflowList/use-dimensions.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\n\ninterface ResizeObserverDimensions {\n width: number;\n height: number;\n contentWidth: number;\n contentHeight: number;\n}\nexport function useDimensions<T extends HTMLElement | null>(\n elementRef: React.RefObject<T>\n): ResizeObserverDimensions | null {\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const [dimensions, setDimensions] = useState<ResizeObserverDimensions | null>(null);\n\n useEffect(() => {\n if (!elementRef.current) {\n return;\n }\n\n // The observer watches the same element that the measuring cycle resizes.\n // Updating dimensions synchronously inside the callback resizes an element\n // whose notification is being delivered, which browsers report as\n // \"ResizeObserver loop completed with undelivered notifications\"\n // (a window `error` event). Defer the update to the next frame instead.\n let frame = 0;\n\n resizeObserverRef.current = new ResizeObserver((entries) => {\n if (entries[0]) {\n const entry = entries[0];\n const nextDimensions = {\n width: entry.borderBoxSize[0]?.inlineSize ?? entry.target.clientWidth,\n height: entry.borderBoxSize[0]?.blockSize ?? entry.target.clientHeight,\n contentWidth: entry.contentRect.width,\n contentHeight: entry.contentRect.height,\n };\n\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => setDimensions(nextDimensions));\n }\n });\n\n resizeObserverRef.current.observe(elementRef.current);\n\n return () => {\n cancelAnimationFrame(frame);\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n resizeObserverRef.current = null;\n }\n };\n }, [elementRef.current]);\n\n return dimensions;\n}\n"],"mappings":";;;AAQA,SAAgB,cACd,YACiC;CACjC,MAAM,oBAAoB,OAA8B,IAAI;CAC5D,MAAM,CAAC,YAAY,iBAAiB,SAA0C,IAAI;CAElF,gBAAgB;EACd,IAAI,CAAC,WAAW,SACd;EAQF,IAAI,QAAQ;EAEZ,kBAAkB,UAAU,IAAI,gBAAgB,YAAY;GAC1D,IAAI,QAAQ,IAAI;IACd,MAAM,QAAQ,QAAQ;IACtB,MAAM,iBAAiB;KACrB,OAAO,MAAM,cAAc,EAAE,EAAE,cAAc,MAAM,OAAO;KAC1D,QAAQ,MAAM,cAAc,EAAE,EAAE,aAAa,MAAM,OAAO;KAC1D,cAAc,MAAM,YAAY;KAChC,eAAe,MAAM,YAAY;IACnC;IAEA,qBAAqB,KAAK;IAC1B,QAAQ,4BAA4B,cAAc,cAAc,CAAC;GACnE;EACF,CAAC;EAED,kBAAkB,QAAQ,QAAQ,WAAW,OAAO;EAEpD,aAAa;GACX,qBAAqB,KAAK;GAC1B,IAAI,kBAAkB,SAAS;IAC7B,kBAAkB,QAAQ,WAAW;IACrC,kBAAkB,UAAU;GAC9B;EACF;CACF,GAAG,CAAC,WAAW,OAAO,CAAC;CAEvB,OAAO;AACT"}
|
|
@@ -70,6 +70,7 @@ function usePopover(options) {
|
|
|
70
70
|
onChange: options.onChange
|
|
71
71
|
});
|
|
72
72
|
const previouslyOpened = useRef(_opened);
|
|
73
|
+
const measuredAfterShowRef = useRef(false);
|
|
73
74
|
const [lockedPlacement, setLockedPlacement] = useState(null);
|
|
74
75
|
const lockEnabled = options.preventPositionChangeWhenVisible !== false;
|
|
75
76
|
const wasOpenedRef = useRef(_opened);
|
|
@@ -77,6 +78,12 @@ function usePopover(options) {
|
|
|
77
78
|
wasOpenedRef.current = _opened;
|
|
78
79
|
if (_opened && lockedPlacement !== null) setLockedPlacement(null);
|
|
79
80
|
}
|
|
81
|
+
const previousPositionRef = useRef(options.position);
|
|
82
|
+
if (options.position !== previousPositionRef.current) {
|
|
83
|
+
previousPositionRef.current = options.position;
|
|
84
|
+
measuredAfterShowRef.current = false;
|
|
85
|
+
if (lockedPlacement !== null) setLockedPlacement(null);
|
|
86
|
+
}
|
|
80
87
|
const resetLockedPlacement = useCallback(() => setLockedPlacement(null), []);
|
|
81
88
|
const onClose = () => {
|
|
82
89
|
if (_opened && !options.disabled) setOpened(false);
|
|
@@ -103,7 +110,6 @@ function usePopover(options) {
|
|
|
103
110
|
floating.elements.reference,
|
|
104
111
|
floating.elements.floating
|
|
105
112
|
]);
|
|
106
|
-
const measuredAfterShowRef = useRef(false);
|
|
107
113
|
useIsomorphicEffect(() => {
|
|
108
114
|
if (!_opened) {
|
|
109
115
|
measuredAfterShowRef.current = false;
|