@designbyadrian/react-interactive-input 2.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,14 @@ interface InteractiveInputProps extends React.InputHTMLAttributes<HTMLInputEleme
10
10
  value?: number;
11
11
  }
12
12
  /**
13
- * Main component for the InteractiveInput
13
+ * Main component for the InteractiveInput.
14
+ *
15
+ * Click and drag horizontally to scrub the value; a plain click focuses the
16
+ * field for manual text editing (drags while focused select text instead of
17
+ * scrubbing). Scrubbing works with mouse, touch and pen via Pointer Events,
18
+ * survives the pointer leaving the element thanks to pointer capture, applies
19
+ * modifier keys (read live from each pointer event) and can be cancelled with
20
+ * Escape, restoring the value from before the drag.
14
21
  */
15
- export default function InteractiveInput({ value, modifiers, style: _style, ...props }: InteractiveInputProps): import("react/jsx-runtime").JSX.Element;
22
+ export default function InteractiveInput({ value, modifiers, style: _style, onBlur, onFocus, onKeyDown, onPointerCancel, onPointerDown, onPointerMove, onPointerUp, ...props }: InteractiveInputProps): import("react").JSX.Element;
16
23
  export {};
@@ -1,13 +1,25 @@
1
1
  import { type MaskFunction } from './masks';
2
2
  interface MaskedInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
3
3
  /**
4
- * Masking function to apply to the input value. Defaults to `numberMask` which ensures that the input value is a valid number, including negative numbers.
4
+ * Masking function applied to the input text. Receives the raw text and the
5
+ * previous (valid) text, and returns the text to display. Defaults to
6
+ * `maskNumber`, which accepts complete and in-progress decimal numbers,
7
+ * including negative ones.
5
8
  */
6
9
  mask?: MaskFunction;
7
10
  value?: string;
8
11
  }
9
12
  /**
10
- * A React input component featuring input masking specifically designed to address limitations with negative numbers in standard HTML input elements. This component ensures that negative values are properly formatted and accepted by the input field, preventing unexpected behavior or errors when handling signed numbers.
13
+ * A React input component featuring input masking specifically designed to
14
+ * address limitations with negative numbers in standard HTML input elements.
15
+ *
16
+ * The displayed text is owned locally while the field is focused, so
17
+ * in-progress states like "", "-" or "1." are never overwritten by a
18
+ * controlled host echoing parsed values back. The `value` prop is synced to
19
+ * the display only while the field is not focused.
20
+ *
21
+ * All change events delivered to `onChange` are genuine React ChangeEvents
22
+ * whose `target.value` is the canonical (dot-decimal) string.
11
23
  */
12
24
  declare const MaskedInput: import("react").ForwardRefExoticComponent<MaskedInputProps & import("react").RefAttributes<HTMLInputElement>>;
13
25
  export default MaskedInput;
@@ -1,2 +1,9 @@
1
- export type MaskFunction = (rawValue: string) => string;
2
- export declare function createNumberMask(): (rawValue: string) => string;
1
+ export type MaskFunction = (rawValue: string, previousValue: string) => string;
2
+ /**
3
+ * Pure number mask: returns the raw value when it is a valid (possibly
4
+ * in-progress) decimal number, otherwise returns the previous valid value.
5
+ *
6
+ * Being pure, it holds no internal state, so mask behavior can never leak
7
+ * between input instances.
8
+ */
9
+ export declare const maskNumber: MaskFunction;
@@ -1,2 +1,26 @@
1
- export declare const getDecimalPlaces: (step: number) => number;
2
- export declare const createChangeEvent: (e: React.ChangeEvent<HTMLInputElement>, value: string) => React.ChangeEvent<HTMLInputElement>;
1
+ export declare const getDecimalPlaces: (value: number) => number;
2
+ /**
3
+ * Convert display text to the canonical machine format: dot decimal
4
+ * separator, mirroring how native number inputs expose a locale-independent
5
+ * DOM value.
6
+ */
7
+ export declare const toCanonicalText: (text: string) => string;
8
+ /** Parse display text (dot or comma decimal separator) into a number. */
9
+ export declare const parseNumber: (text: string) => number;
10
+ /** Format a numeric value as canonical display text. Non-finite values become "". */
11
+ export declare const formatNumber: (value: number) => string;
12
+ /**
13
+ * Normalize an in-progress editing string into its canonical representation:
14
+ * collapses leading zeros ("007" becomes "7"), strips trailing decimal
15
+ * separators ("1." becomes "1") and lone minus signs ("-" becomes ""), and
16
+ * converts a comma decimal separator to a dot. Unparseable text becomes "".
17
+ */
18
+ export declare const normalizeNumberText: (text: string) => string;
19
+ /**
20
+ * Set an input's value through the native HTMLInputElement value setter and
21
+ * dispatch a bubbling `input` event. Using the prototype setter bypasses
22
+ * React's internal value tracking, so React treats the dispatched event like
23
+ * genuine user input and fires `onChange` with a real ChangeEvent whose
24
+ * target is the actual input element.
25
+ */
26
+ export declare const setNativeValue: (input: HTMLInputElement, value: string) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@designbyadrian/react-interactive-input",
3
- "version": "2.0.3",
3
+ "version": "3.0.0",
4
4
  "description": "Adjust values in numeric input boxes by clicking and dragging horizontally, just like in Blender and similar 3D applications.",
5
5
  "keywords": [
6
6
  "react",
@@ -26,6 +26,8 @@
26
26
  "build-storybook": "storybook build",
27
27
  "build": "vite build && tsc --project tsconfig.json",
28
28
  "build:types": "tsc --emitDeclarationOnly",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
29
31
  "prepublishOnly": "npm run build",
30
32
  "deploy-storybook": "npm run build-storybook && touch ./storybook-static/.nojekyll && gh-pages -d storybook-static -t true"
31
33
  },
@@ -44,27 +46,35 @@
44
46
  "dist/types"
45
47
  ],
46
48
  "peerDependencies": {
47
- "react": "^18.2.0",
48
- "react-dom": "^18.2.0"
49
+ "react": "^19.0.0",
50
+ "react-dom": "^19.0.0"
49
51
  },
50
52
  "devDependencies": {
51
- "@chromatic-com/storybook": "3.2.2",
52
- "@storybook/addon-a11y": "^8.5.0-alpha.3",
53
- "@storybook/addon-essentials": "8.5.0-alpha.3",
54
- "@storybook/addon-interactions": "8.5.0-alpha.3",
55
- "@storybook/addon-links": "8.5.0-alpha.3",
56
- "@storybook/addon-onboarding": "8.5.0-alpha.3",
57
- "@storybook/blocks": "8.5.0-alpha.3",
58
- "@storybook/react": "8.5.0-alpha.3",
59
- "@storybook/react-vite": "8.5.0-alpha.3",
60
- "@storybook/test": "8.5.0-alpha.3",
61
- "@types/react": "18.3.12",
62
- "@vitejs/plugin-react": "4.3.3",
63
- "eslint": "9.14.0",
64
- "gh-pages": "6.2.0",
65
- "storybook": "8.5.0-alpha.3",
66
- "typescript": "5.6.3",
67
- "vite": "5.4.10"
53
+ "@chromatic-com/storybook": "^3.2.6",
54
+ "@testing-library/dom": "^10.4.0",
55
+ "@testing-library/react": "^16.2.0",
56
+ "@testing-library/user-event": "^14.6.1",
57
+ "@storybook/addon-a11y": "^8.6.9",
58
+ "@storybook/addon-essentials": "^8.6.9",
59
+ "@storybook/addon-interactions": "^8.6.9",
60
+ "@storybook/addon-links": "^8.6.9",
61
+ "@storybook/addon-onboarding": "^8.6.9",
62
+ "@storybook/blocks": "^8.6.9",
63
+ "@storybook/react": "^8.6.9",
64
+ "@storybook/react-vite": "^8.6.9",
65
+ "@storybook/test": "^8.6.9",
66
+ "@types/react": "^19.0.12",
67
+ "@types/react-dom": "^19.0.4",
68
+ "@vitejs/plugin-react": "^4.3.4",
69
+ "eslint": "^9.23.0",
70
+ "gh-pages": "^6.3.0",
71
+ "jsdom": "^26.0.0",
72
+ "react": "^19.0.0",
73
+ "react-dom": "^19.0.0",
74
+ "storybook": "^8.6.9",
75
+ "typescript": "^5.8.2",
76
+ "vite": "^6.2.3",
77
+ "vitest": "^3.0.9"
68
78
  },
69
79
  "engines": {
70
80
  "node": ">=20.0.0"