@fiscozen/input 0.1.16 → 1.0.0-next.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.
@@ -0,0 +1,247 @@
1
+ import { IconButtonVariant } from '@fiscozen/button';
2
+ import { IconSize, IconVariant } from '@fiscozen/icons';
3
+
4
+ export type InputEnvironment = "backoffice" | "frontoffice";
5
+ type FzInputProps = {
6
+ /**
7
+ * Text label displayed above the input field. Overridden by label slot if provided.
8
+ */
9
+ label?: string;
10
+ /**
11
+ * Environment determining input size and styling
12
+ * @default 'frontoffice'
13
+ */
14
+ environment?: InputEnvironment;
15
+ /**
16
+ * Visual size affecting height, padding, and text size
17
+ *
18
+ * @deprecated Use the 'environment' prop instead. This prop will be removed in a future version.
19
+ * Size values map to environments: sm/md → backoffice, lg → frontoffice
20
+ */
21
+ size?: "sm" | "md" | "lg";
22
+ /**
23
+ * Placeholder text shown when input is empty. Behavior differs based on variant.
24
+ */
25
+ placeholder?: string;
26
+ /**
27
+ * Marks input as required. Adds asterisk to label and sets native required attribute.
28
+ * @default false
29
+ */
30
+ required?: boolean;
31
+ /**
32
+ * Disables input interaction and applies disabled styling
33
+ * @default false
34
+ */
35
+ disabled?: boolean;
36
+ /**
37
+ * Shows error state with red border and enables errorMessage slot display
38
+ * @default false
39
+ */
40
+ error?: boolean;
41
+ /**
42
+ * Font Awesome icon name displayed on the left side of input
43
+ */
44
+ leftIcon?: string;
45
+ /**
46
+ * Visual style variant for left icon (solid, regular, light, etc.)
47
+ */
48
+ leftIconVariant?: IconVariant;
49
+ /**
50
+ * Button variant for left icon when rendered as clickable button
51
+ */
52
+ leftIconButtonVariant?: IconButtonVariant;
53
+ /**
54
+ * Accessible label for left icon when clickable. Required for screen reader accessibility.
55
+ */
56
+ leftIconAriaLabel?: string;
57
+ /**
58
+ * Font Awesome icon name displayed on the right side of input
59
+ */
60
+ rightIcon?: string;
61
+ /**
62
+ * Additional CSS classes applied to right icon container
63
+ */
64
+ rightIconClass?: string;
65
+ /**
66
+ * Size override for right icon. If not provided, uses input size mapping.
67
+ * @deprecated This prop is deprecated and will be removed in a future version.
68
+ * Icons now have a fixed size of "md". This prop will be ignored.
69
+ */
70
+ rightIconSize?: IconSize;
71
+ /**
72
+ * Visual style variant for right icon (solid, regular, light, etc.)
73
+ */
74
+ rightIconVariant?: IconVariant;
75
+ /**
76
+ * Renders right icon as clickable button instead of static icon
77
+ * @default false
78
+ */
79
+ rightIconButton?: boolean;
80
+ /**
81
+ * Button variant for right icon when rightIconButton is true
82
+ * @default 'invisible'
83
+ */
84
+ rightIconButtonVariant?: IconButtonVariant;
85
+ /**
86
+ * Accessible label for right icon when clickable. Required for screen reader accessibility.
87
+ */
88
+ rightIconAriaLabel?: string;
89
+ /**
90
+ * Font Awesome icon name displayed as second icon on the right side of input.
91
+ * Priority order: secondRightIcon > rightIcon > valid
92
+ */
93
+ secondRightIcon?: string;
94
+ /**
95
+ * Additional CSS classes applied to second right icon container
96
+ */
97
+ secondRightIconClass?: string;
98
+ /**
99
+ * Visual style variant for second right icon (solid, regular, light, etc.)
100
+ */
101
+ secondRightIconVariant?: IconVariant;
102
+ /**
103
+ * Renders second right icon as clickable button instead of static icon
104
+ * @default false
105
+ */
106
+ secondRightIconButton?: boolean;
107
+ /**
108
+ * Button variant for second right icon when secondRightIconButton is true
109
+ * @default 'invisible'
110
+ */
111
+ secondRightIconButtonVariant?: IconButtonVariant;
112
+ /**
113
+ * Accessible label for second right icon when clickable. Required for screen reader accessibility.
114
+ */
115
+ secondRightIconAriaLabel?: string;
116
+ /**
117
+ * Native HTML input type. Determines keyboard layout and validation behavior
118
+ * @default 'text'
119
+ */
120
+ type?: "text" | "password" | "email" | "number" | "tel" | "url";
121
+ /**
122
+ * Shows success checkmark icon on the right when true. Takes precedence over rightIcon
123
+ * @default false
124
+ */
125
+ valid?: boolean;
126
+ /**
127
+ * Visual presentation style. 'floating-label' moves placeholder above input when focused/filled
128
+ * @default 'normal'
129
+ */
130
+ variant?: 'normal' | 'floating-label';
131
+ /**
132
+ * HTML5 pattern attribute for native browser validation
133
+ */
134
+ pattern?: string;
135
+ /**
136
+ * Native name attribute for form submission and identification
137
+ */
138
+ name?: string;
139
+ /**
140
+ * Native readonly attribute. Prevents user input while keeping field focusable
141
+ * @default false
142
+ */
143
+ readonly?: boolean;
144
+ /**
145
+ * Native maxlength attribute. Limits maximum number of characters
146
+ */
147
+ maxlength?: number;
148
+ /**
149
+ * Additional CSS classes applied to left icon container
150
+ */
151
+ leftIconClass?: string;
152
+ };
153
+ interface FzCurrencyInputProps extends Omit<FzInputProps, "type" | "modelValue" | "rightIcon" | "rightIconSize" | "rightIconVariant" | "rightIconButton" | "rightIconButtonVariant" | "rightIconAriaLabel" | "rightIconClass" | "secondRightIcon" | "secondRightIconClass" | "secondRightIconVariant" | "secondRightIconButton" | "secondRightIconButtonVariant" | "secondRightIconAriaLabel"> {
154
+ /**
155
+ * The v-model value.
156
+ *
157
+ * **Type assertion**: This prop accepts `number | string | undefined | null` as input,
158
+ * but the component **always emits** `number | undefined | null` (never `string`).
159
+ * Strings are automatically parsed (Italian format: "1.234,56" → 1234.56) and converted
160
+ * to numbers internally.
161
+ *
162
+ * **nullOnEmpty**: When `nullOnEmpty` is `true`, empty input emits `null` instead of `undefined`.
163
+ *
164
+ * **Deprecation**: String values are deprecated and will be removed in a future version.
165
+ * A console warning is shown when strings are used. Please use `number | undefined | null` instead
166
+ * for type safety and future compatibility.
167
+ *
168
+ * @example
169
+ * ```vue
170
+ * <!-- ✅ Recommended: number | undefined | null -->
171
+ * <script setup>
172
+ * const amount = ref<number | undefined>(undefined);
173
+ * </script>
174
+ * <template>
175
+ * <FzCurrencyInput v-model="amount" />
176
+ * </template>
177
+ *
178
+ * <!-- ✅ With nullOnEmpty: number | null -->
179
+ * <script setup>
180
+ * const amount = ref<number | null>(null);
181
+ * </script>
182
+ * <template>
183
+ * <FzCurrencyInput v-model="amount" :nullOnEmpty="true" />
184
+ * </template>
185
+ *
186
+ * <!-- ⚠️ Deprecated: string (still works but shows warning) -->
187
+ * <script setup>
188
+ * const amount = ref<string>("1234,56");
189
+ * </script>
190
+ * <template>
191
+ * <FzCurrencyInput v-model="amount" />
192
+ * </template>
193
+ * ```
194
+ */
195
+ modelValue?: number | string | undefined | null;
196
+ /**
197
+ * Converts empty input to null instead of undefined.
198
+ * When true, empty input (v-model undefined) will emit null instead of undefined.
199
+ * @default false
200
+ */
201
+ nullOnEmpty?: boolean;
202
+ /**
203
+ * Converts empty input to 0 instead of undefined.
204
+ * When true, empty input (v-model undefined) will emit 0 instead of undefined.
205
+ * @default false
206
+ */
207
+ zeroOnEmpty?: boolean;
208
+ /**
209
+ * Minimum decimal places in formatted output
210
+ * @default 2
211
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
212
+ */
213
+ minimumFractionDigits?: number;
214
+ /**
215
+ * Maximum decimal places in formatted output
216
+ * @default 2
217
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#digit_options
218
+ */
219
+ maximumFractionDigits?: number;
220
+ /**
221
+ * Minimum allowed value. Values below this are clamped to min
222
+ */
223
+ min?: number;
224
+ /**
225
+ * Maximum allowed value. Values above this are clamped to max
226
+ */
227
+ max?: number;
228
+ /**
229
+ * Step increment for arrow buttons. When forceStep is true, values are rounded to nearest step multiple
230
+ * @default 1
231
+ */
232
+ step?: number;
233
+ /**
234
+ * Enforces quantization: values are automatically rounded to nearest step multiple
235
+ * @default false
236
+ */
237
+ forceStep?: boolean;
238
+ /**
239
+ * Custom accessible label for step up button. If not provided, uses default label.
240
+ */
241
+ stepUpAriaLabel?: string;
242
+ /**
243
+ * Custom accessible label for step down button. If not provided, uses default label.
244
+ */
245
+ stepDownAriaLabel?: string;
246
+ }
247
+ export { FzInputProps, FzCurrencyInputProps };
@@ -0,0 +1,27 @@
1
+ import { ToRefs, Ref, ComputedRef } from 'vue';
2
+ import { FzInputProps, InputEnvironment } from './types';
3
+
4
+ /**
5
+ * Composable for managing FzInput component styles and computed classes
6
+ *
7
+ * Handles dynamic styling based on props, environment, variant, and state.
8
+ * Returns computed classes for container, label, input, help text, and error messages.
9
+ *
10
+ * @param props - Reactive props from FzInput component
11
+ * @param container - Reference to container DOM element
12
+ * @param model - Reactive model value (string | undefined)
13
+ * @param effectiveEnvironment - Computed effective environment (backoffice | frontoffice)
14
+ * @param isFocused - Reactive flag indicating if input is focused
15
+ * @returns Object containing computed classes and style-related properties
16
+ */
17
+ export default function useInputStyle(props: ToRefs<FzInputProps>, container: Ref<HTMLElement | null>, model: Ref<string | undefined>, effectiveEnvironment: ComputedRef<InputEnvironment>, isFocused: Ref<boolean>): {
18
+ staticContainerClass: string;
19
+ computedContainerClass: ComputedRef<(string | undefined)[]>;
20
+ computedLabelClass: ComputedRef<string[]>;
21
+ staticInputClass: string;
22
+ computedInputClass: ComputedRef<string[]>;
23
+ computedHelpClass: ComputedRef<string[]>;
24
+ computedErrorClass: ComputedRef<string[]>;
25
+ containerWidth: ComputedRef<string>;
26
+ showNormalPlaceholder: ComputedRef<boolean>;
27
+ };
@@ -0,0 +1,21 @@
1
+ import { InputEnvironment } from './types';
2
+
3
+ type InputSize = "sm" | "md" | "lg";
4
+ /**
5
+ * Maps deprecated InputSize to InputEnvironment
6
+ *
7
+ * Used for backward compatibility when size prop is provided instead of environment.
8
+ * Size values map to environments: sm/md → backoffice, lg → frontoffice
9
+ */
10
+ export declare const sizeToEnvironmentMapping: Record<InputSize, InputEnvironment>;
11
+ /**
12
+ * Generates a unique ID for input components.
13
+ *
14
+ * @returns Unique input ID with "fz-input" prefix
15
+ *
16
+ * @example
17
+ * generateInputId() // "fz-input-97123456-a8d3k"
18
+ * generateInputId() // "fz-input-97123457-k2m9p"
19
+ */
20
+ export declare function generateInputId(): string;
21
+ export {};
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .fz-icon-button-wrapper[data-v-b4be112d]>button{gap:0!important;min-width:0!important}.fz-icon-button-wrapper--backoffice[data-v-b4be112d]>button{padding-left:5px;padding-right:5px}.fz-icon-button-wrapper--frontoffice[data-v-b4be112d]>button{padding-left:11px;padding-right:11px}.fz-container[data-v-ad2af2dd]{display:flex}.fz-container--vertical[data-v-ad2af2dd]{flex-direction:column}.fz-container--horizontal[data-v-ad2af2dd]{flex-direction:row;flex-wrap:nowrap}.fz-container.align-items-start[data-v-ad2af2dd]{align-items:flex-start}.fz-container.align-items-center[data-v-ad2af2dd]{align-items:center}.fz-container.align-items-end[data-v-ad2af2dd]{align-items:flex-end}.fz-container.align-items-stretch[data-v-ad2af2dd]{align-items:stretch}.fz-container.align-items-baseline[data-v-ad2af2dd]{align-items:baseline}.fz-container--horizontal.layout-expand-first[data-v-ad2af2dd]>*:first-child{flex-grow:1}.fz-container--horizontal.layout-expand-all[data-v-ad2af2dd]>*{flex-grow:1}.fz-container--horizontal.layout-space-between[data-v-ad2af2dd]{justify-content:space-between}.fz-container--vertical.gap-main-content-sm[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--main-content-sm, 32px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-main-content-base[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--main-content-base, 48px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-main-content-lg[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--main-content-lg, 64px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-none[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--section-content-none, 0px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-xs[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--section-content-xs, 8px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-sm[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--section-content-sm, 16px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-base[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--section-content-base, 24px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-lg[data-v-ad2af2dd]>p+p{margin-top:calc((0px - var(--section-content-lg, 32px)) + var(--paragraph-gap, 8px))}.fz-container--horizontal[data-v-ad2af2dd]>p+p{margin-top:0}.fz-button-group[data-v-00e5427e]>*:nth-child(1):nth-last-child(2),.fz-button-group[data-v-00e5427e]>*:nth-child(1):nth-last-child(2)~*{flex-basis:50%;flex-grow:0;flex-shrink:1}.fz-button-group[data-v-00e5427e]>*:nth-child(1):nth-last-child(3),.fz-button-group[data-v-00e5427e]>*:nth-child(1):nth-last-child(3)~*{flex-basis:33.333%;flex-grow:0;flex-shrink:1}.fz-button-group.fz-button-group--md[data-v-00e5427e]{justify-content:flex-end!important}.fz-button-group.fz-button-group--md[data-v-00e5427e]>*{flex-basis:initial!important;flex-grow:0!important;flex-shrink:0!important}.fz-button-group[data-v-00e5427e]>.fz-icon-button-wrapper{flex-basis:initial!important;flex-grow:0!important;flex-shrink:0!important}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiscozen/input",
3
- "version": "0.1.16",
3
+ "version": "1.0.0-next.0",
4
4
  "description": "Design System Input component",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -9,9 +9,9 @@
9
9
  "peerDependencies": {
10
10
  "tailwindcss": "^3.4.1",
11
11
  "vue": "^3.4.13",
12
- "@fiscozen/composables": "^0.1.36",
13
- "@fiscozen/button": "^0.1.12",
14
- "@fiscozen/icons": "^0.1.28"
12
+ "@fiscozen/button": "^1.0.1-next.1",
13
+ "@fiscozen/composables": "^0.1.39-next.0",
14
+ "@fiscozen/icons": "^0.1.36"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@rushstack/eslint-patch": "^1.3.3",
@@ -29,9 +29,9 @@
29
29
  "vite-plugin-dts": "^3.8.3",
30
30
  "vitest": "^1.2.0",
31
31
  "vue-tsc": "^1.8.25",
32
- "@fiscozen/tsconfig": "^0.1.0",
32
+ "@fiscozen/prettier-config": "^0.1.0",
33
33
  "@fiscozen/eslint-config": "^0.1.0",
34
- "@fiscozen/prettier-config": "^0.1.0"
34
+ "@fiscozen/tsconfig": "^0.1.0"
35
35
  },
36
36
  "license": "MIT",
37
37
  "scripts": {