@fiscozen/input 3.4.4 → 3.5.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.
@@ -1,7 +1,37 @@
1
1
  import { IconButtonVariant } from '@fiscozen/button';
2
2
  import { IconSize, IconVariant } from '@fiscozen/icons';
3
3
  export type InputEnvironment = "backoffice" | "frontoffice";
4
- type FzInputProps = {
4
+ /**
5
+ * Input type. Native HTML types render the corresponding `<input type>`;
6
+ * `currency` renders a text input with locale-aware currency formatting,
7
+ * validation and step controls (see FzInput docs).
8
+ */
9
+ export type FzInputType = "text" | "password" | "email" | "number" | "tel" | "url" | "search" | "file" | "currency";
10
+ /**
11
+ * Exposed instance shape of FzInput (template ref type).
12
+ * Use this instead of `InstanceType<typeof FzInput>`: FzInput is a generic
13
+ * component, so its type is a call signature and InstanceType does not apply.
14
+ */
15
+ export interface FzInputInstance {
16
+ inputRef: HTMLInputElement | null;
17
+ containerRef: HTMLElement | null;
18
+ }
19
+ /**
20
+ * Maps the input `type` to the v-model value type.
21
+ *
22
+ * - `type="currency"` → `number | null | undefined` (numbers in, numbers out)
23
+ * - any other type → `string | undefined`
24
+ *
25
+ * The conditional is deliberately non-distributive (`[TType] extends ["currency"]`):
26
+ * when `type` is bound dynamically the inferred type parameter is the whole
27
+ * `FzInputType` union and the model falls back to `string` — only a literal
28
+ * `type="currency"` switches the v-model to numbers. At runtime a dynamic
29
+ * "currency" type still behaves numerically.
30
+ */
31
+ export type FzInputModelValue<TType extends FzInputType = FzInputType> = [
32
+ TType
33
+ ] extends ["currency"] ? number | null | undefined : string | undefined;
34
+ type FzInputProps<TType extends FzInputType = FzInputType> = {
5
35
  /**
6
36
  * Custom DOM id for the underlying `<input>`. When provided, the same value is
7
37
  * used for the `<label>`'s `for` attribute so the label-input binding stays
@@ -119,10 +149,12 @@ type FzInputProps = {
119
149
  */
120
150
  secondRightIconAriaLabel?: string;
121
151
  /**
122
- * Native HTML input type. Determines keyboard layout and validation behavior
152
+ * Input type. Native HTML types determine keyboard layout and validation behavior.
153
+ * `currency` enables locale-aware currency formatting with step controls;
154
+ * with `type="currency"` the v-model is `number | null | undefined` instead of `string`.
123
155
  * @default 'text'
124
156
  */
125
- type?: "text" | "password" | "email" | "number" | "tel" | "url";
157
+ type?: TType;
126
158
  /**
127
159
  * Shows success checkmark icon on the right when true. Takes precedence over rightIcon
128
160
  * @default false
@@ -204,8 +236,69 @@ type FzInputProps = {
204
236
  * Additional CSS classes applied to left icon container
205
237
  */
206
238
  leftIconClass?: string;
239
+ /**
240
+ * Minimum allowed value. For `type="currency"` values below this are clamped to min;
241
+ * for `type="number"` it is forwarded to the native `min` attribute.
242
+ */
243
+ min?: number;
244
+ /**
245
+ * Maximum allowed value. For `type="currency"` values above this are clamped to max;
246
+ * for `type="number"` it is forwarded to the native `max` attribute.
247
+ */
248
+ max?: number;
249
+ /**
250
+ * Step increment for the up/down arrow controls shown with `type="currency"` and
251
+ * `type="number"`. For `type="number"` it is also forwarded to the native `step` attribute.
252
+ * When forceStep is true (currency only), values are rounded to the nearest step multiple.
253
+ * @default 1
254
+ */
255
+ step?: number;
256
+ /**
257
+ * Enforces quantization for `type="currency"`: values are automatically rounded
258
+ * to the nearest step multiple
259
+ * @default false
260
+ */
261
+ forceStep?: boolean;
262
+ /**
263
+ * Minimum decimal places in formatted output (`type="currency"` only)
264
+ * @default 2
265
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
266
+ */
267
+ minimumFractionDigits?: number;
268
+ /**
269
+ * Maximum decimal places in formatted output (`type="currency"` only)
270
+ * @default 2
271
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
272
+ */
273
+ maximumFractionDigits?: number;
274
+ /**
275
+ * Converts empty input to null instead of undefined (`type="currency"` only).
276
+ * When true, empty input will emit null instead of undefined.
277
+ * @default false
278
+ */
279
+ nullOnEmpty?: boolean;
280
+ /**
281
+ * Converts empty input to 0 instead of undefined (`type="currency"` only).
282
+ * When true, empty input will emit 0 instead of undefined.
283
+ * @default false
284
+ */
285
+ zeroOnEmpty?: boolean;
286
+ /**
287
+ * Custom accessible label for the step up button shown with `type="currency"`
288
+ * and `type="number"`. If not provided, uses a default label based on step.
289
+ */
290
+ stepUpAriaLabel?: string;
291
+ /**
292
+ * Custom accessible label for the step down button shown with `type="currency"`
293
+ * and `type="number"`. If not provided, uses a default label based on step.
294
+ */
295
+ stepDownAriaLabel?: string;
207
296
  };
208
- interface FzCurrencyInputProps extends Omit<FzInputProps, "type" | "modelValue" | "rightIcon" | "rightIconSize" | "rightIconVariant" | "rightIconButton" | "rightIconButtonVariant" | "rightIconAriaLabel" | "rightIconClass" | "secondRightIcon" | "secondRightIconClass" | "secondRightIconVariant" | "secondRightIconButton" | "secondRightIconButtonVariant" | "secondRightIconAriaLabel"> {
297
+ /**
298
+ * @deprecated FzCurrencyInput is deprecated: use `FzInput` with `type="currency"` instead.
299
+ * This interface is kept for backwards compatibility until the migration is complete.
300
+ */
301
+ interface FzCurrencyInputProps extends Omit<FzInputProps<"currency">, "type" | "modelValue" | "rightIcon" | "rightIconSize" | "rightIconVariant" | "rightIconButton" | "rightIconButtonVariant" | "rightIconAriaLabel" | "rightIconClass" | "secondRightIcon" | "secondRightIconClass" | "secondRightIconVariant" | "secondRightIconButton" | "secondRightIconButtonVariant" | "secondRightIconAriaLabel"> {
209
302
  /**
210
303
  * The v-model value.
211
304
  *
@@ -248,55 +341,5 @@ interface FzCurrencyInputProps extends Omit<FzInputProps, "type" | "modelValue"
248
341
  * ```
249
342
  */
250
343
  modelValue?: number | string | undefined | null;
251
- /**
252
- * Converts empty input to null instead of undefined.
253
- * When true, empty input (v-model undefined) will emit null instead of undefined.
254
- * @default false
255
- */
256
- nullOnEmpty?: boolean;
257
- /**
258
- * Converts empty input to 0 instead of undefined.
259
- * When true, empty input (v-model undefined) will emit 0 instead of undefined.
260
- * @default false
261
- */
262
- zeroOnEmpty?: boolean;
263
- /**
264
- * Minimum decimal places in formatted output
265
- * @default 2
266
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
267
- */
268
- minimumFractionDigits?: number;
269
- /**
270
- * Maximum decimal places in formatted output
271
- * @default 2
272
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
273
- */
274
- maximumFractionDigits?: number;
275
- /**
276
- * Minimum allowed value. Values below this are clamped to min
277
- */
278
- min?: number;
279
- /**
280
- * Maximum allowed value. Values above this are clamped to max
281
- */
282
- max?: number;
283
- /**
284
- * Step increment for arrow buttons. When forceStep is true, values are rounded to nearest step multiple
285
- * @default 1
286
- */
287
- step?: number;
288
- /**
289
- * Enforces quantization: values are automatically rounded to nearest step multiple
290
- * @default false
291
- */
292
- forceStep?: boolean;
293
- /**
294
- * Custom accessible label for step up button. If not provided, uses default label.
295
- */
296
- stepUpAriaLabel?: string;
297
- /**
298
- * Custom accessible label for step down button. If not provided, uses default label.
299
- */
300
- stepDownAriaLabel?: string;
301
344
  }
302
345
  export { FzInputProps, FzCurrencyInputProps };
@@ -0,0 +1,59 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ /**
3
+ * Subset of FzInput props the currency behavior depends on.
4
+ * Matches the prop names/semantics of the former FzCurrencyInput component.
5
+ */
6
+ export interface UseCurrencyInputProps {
7
+ /** Minimum allowed value. Values below this are clamped to min */
8
+ min?: number;
9
+ /** Maximum allowed value. Values above this are clamped to max */
10
+ max?: number;
11
+ /** Step increment for arrow buttons. When forceStep is true, values are rounded to nearest step multiple */
12
+ step?: number;
13
+ /** Enforces quantization: values are automatically rounded to nearest step multiple */
14
+ forceStep?: boolean;
15
+ /** Minimum decimal places in formatted output */
16
+ minimumFractionDigits?: number;
17
+ /** Maximum decimal places in formatted output */
18
+ maximumFractionDigits?: number;
19
+ /** Converts empty input to null instead of undefined */
20
+ nullOnEmpty?: boolean;
21
+ /** Converts empty input to 0 instead of undefined */
22
+ zeroOnEmpty?: boolean;
23
+ /** Native readonly attribute */
24
+ readonly?: boolean;
25
+ /** Disables input interaction */
26
+ disabled?: boolean;
27
+ }
28
+ export interface UseCurrencyInputOptions {
29
+ /** Reactive props object (the component's props proxy) */
30
+ props: UseCurrencyInputProps;
31
+ /**
32
+ * The numeric v-model ref. Accepts `number | string | null | undefined` for
33
+ * retrocompatibility, but the composable always writes `number | null | undefined`.
34
+ */
35
+ model: Ref<number | string | null | undefined>;
36
+ /** Whether currency behavior is active (i.e. FzInput type === "currency") */
37
+ enabled: ComputedRef<boolean>;
38
+ }
39
+ /**
40
+ * Currency input behavior for FzInput with `type="currency"`.
41
+ *
42
+ * Manages a display string (`displayValue`) bound to the native input and keeps it
43
+ * in sync with the numeric v-model: number formatting via Intl.NumberFormat with
44
+ * Italian locale separators, input normalization/filtering, min/max clamping and
45
+ * step quantization. Formatting and quantization happen on blur; while focused the
46
+ * raw value is shown for editing.
47
+ *
48
+ * Ported from the FzCurrencyInput component, which is now a thin deprecated
49
+ * wrapper around `<FzInput type="currency">`.
50
+ */
51
+ export default function useCurrencyInput(options: UseCurrencyInputOptions): {
52
+ displayValue: Ref<string | undefined, string | undefined>;
53
+ handleDisplayUpdate: (newValue: string | undefined) => void;
54
+ handleKeydown: (e: KeyboardEvent) => void;
55
+ handlePaste: (e: ClipboardEvent) => void;
56
+ handleFocus: () => void;
57
+ handleBlur: () => void;
58
+ stepBy: (direction: 1 | -1) => void;
59
+ };
@@ -1,19 +1,25 @@
1
1
  import { ToRefs, Ref, ComputedRef } from 'vue';
2
2
  import { FzInputProps, InputEnvironment } from './types';
3
+ /**
4
+ * The subset of FzInput props that drive styling. Styling is independent of the
5
+ * input `type`, so this is intentionally decoupled from `FzInputProps<TType>`'s
6
+ * generic parameter — only these visual-state props are read here.
7
+ */
8
+ type FzInputStyleProps = Pick<FzInputProps, "variant" | "disabled" | "readonly" | "error" | "highlighted" | "aiReasoning">;
3
9
  /**
4
10
  * Composable for managing FzInput component styles and computed classes
5
11
  *
6
12
  * Handles dynamic styling based on props, environment, variant, and state.
7
13
  * Returns computed classes for container, label, input, help text, and error messages.
8
14
  *
9
- * @param props - Reactive props from FzInput component
15
+ * @param props - Reactive styling props from FzInput component
10
16
  * @param container - Reference to container DOM element
11
17
  * @param model - Reactive model value (string | undefined)
12
18
  * @param effectiveEnvironment - Computed effective environment (backoffice | frontoffice)
13
19
  * @param isFocused - Reactive flag indicating if input is focused
14
20
  * @returns Object containing computed classes and style-related properties
15
21
  */
16
- export default function useInputStyle(props: ToRefs<FzInputProps>, container: Ref<HTMLElement | null>, model: Ref<string | undefined>, effectiveEnvironment: ComputedRef<InputEnvironment>, isFocused: Ref<boolean>): {
22
+ export default function useInputStyle(props: ToRefs<FzInputStyleProps>, container: Ref<HTMLElement | null>, model: Ref<string | undefined>, effectiveEnvironment: ComputedRef<InputEnvironment>, isFocused: Ref<boolean>): {
17
23
  staticContainerClass: string;
18
24
  computedContainerClass: ComputedRef<string[]>;
19
25
  computedLabelClass: ComputedRef<string[]>;
@@ -23,3 +29,4 @@ export default function useInputStyle(props: ToRefs<FzInputProps>, container: Re
23
29
  computedErrorClass: ComputedRef<string[]>;
24
30
  showNormalPlaceholder: ComputedRef<boolean>;
25
31
  };
32
+ export {};
@@ -1,5 +1,19 @@
1
1
  import { InputEnvironment } from './types';
2
2
  type InputSize = "sm" | "md" | "lg";
3
+ /**
4
+ * Whether `text` matches the native floating-point grammar exactly (no
5
+ * trimming: padded or grouped content is rejected by some browsers and
6
+ * blanked out by others, so it cannot be considered natively safe).
7
+ */
8
+ export declare const isNativeFloatString: (text: string) => boolean;
9
+ /**
10
+ * Parses clipboard text into a finite number, accepting the same formats as
11
+ * currency-mode paste (Italian "1.234,56", comma decimals, padded whitespace).
12
+ *
13
+ * @returns The parsed number, or null when the text cannot be interpreted as
14
+ * a finite number
15
+ */
16
+ export declare const parseClipboardNumber: (text: string) => number | null;
3
17
  /**
4
18
  * Maps deprecated InputSize to InputEnvironment
5
19
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiscozen/input",
3
- "version": "3.4.4",
3
+ "version": "3.5.0",
4
4
  "description": "Design System Input component",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -32,9 +32,9 @@
32
32
  "vite-plugin-dts": "^4.5.0",
33
33
  "vitest": "^4.1.1",
34
34
  "vue-tsc": "^2.2.12",
35
+ "@fiscozen/tsconfig": "^0.1.0",
35
36
  "@fiscozen/prettier-config": "^0.1.0",
36
- "@fiscozen/eslint-config": "^0.1.0",
37
- "@fiscozen/tsconfig": "^0.1.0"
37
+ "@fiscozen/eslint-config": "^0.1.0"
38
38
  },
39
39
  "license": "MIT",
40
40
  "scripts": {