@ttoss/forms 0.43.0 → 0.43.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/README.md CHANGED
@@ -39,13 +39,9 @@ export const FormComponent = () => {
39
39
  resolver: zodResolver(schema),
40
40
  });
41
41
 
42
- const onSubmit = (data) => {
43
- console.log(data);
44
- };
45
-
46
42
  return (
47
43
  <I18nProvider>
48
- <Form {...formMethods} onSubmit={onSubmit}>
44
+ <Form {...formMethods} onSubmit={(data) => console.log(data)}>
49
45
  <FormFieldInput name="firstName" label="First Name" />
50
46
  <FormFieldInput name="age" label="Age" type="number" />
51
47
  <FormFieldCheckbox name="receiveEmails" label="Receive Emails" />
@@ -56,169 +52,40 @@ export const FormComponent = () => {
56
52
  };
57
53
  ```
58
54
 
59
- ## React Hook Form Integration
60
-
61
- All React Hook Form APIs are re-exported from `@ttoss/forms`, including hooks like `useForm`, `useController`, `useFieldArray`, and `useFormContext`. See the [React Hook Form documentation](https://react-hook-form.com/docs) for complete API details.
55
+ All React Hook Form APIs (`useForm`, `useController`, `useFieldArray`, `useFormContext`, etc.) are re-exported from `@ttoss/forms`. See the [React Hook Form documentation](https://react-hook-form.com/docs) for details.
62
56
 
63
57
  ## Zod Validation (Recommended)
64
58
 
65
- Import `z` and `zodResolver` directly from `@ttoss/forms` for schema validation using [Zod](https://zod.dev/):
66
-
67
- ```tsx
68
- import { Form, FormFieldInput, useForm, z, zodResolver } from '@ttoss/forms';
69
-
70
- const schema = z.object({
71
- firstName: z.string().min(1, 'First name is required'),
72
- });
73
-
74
- const MyForm = () => {
75
- const formMethods = useForm({
76
- resolver: zodResolver(schema),
77
- });
78
-
79
- return (
80
- <Form {...formMethods} onSubmit={(data) => console.log(data)}>
81
- <FormFieldInput name="firstName" label="First Name" defaultValue="" />
82
- <Button type="submit">Submit</Button>
83
- </Form>
84
- );
85
- };
86
- ```
87
-
88
- ### Validation Messages
89
-
90
- Invalid fields display default error messages like "Field is required". These messages are defined using i18n and can be customized for each locale.
91
-
92
- #### Default Zod Messages
93
-
94
- The package provides internationalized default messages for common Zod validation errors. These are automatically extracted when you run `pnpm run i18n`:
95
-
96
- - **Required field**: `"Field is required"`
97
- - **Type mismatch**: `"Invalid Value for Field of type {expected}"`
98
- - **Minimum length**: `"Field must be at least {min} characters"`
99
-
100
- To customize these messages for your locale, extract the i18n messages and translate them in your application's i18n files (e.g., `i18n/compiled/pt-BR.json`). See the [i18n-CLI documentation](https://ttoss.dev/docs/modules/packages/i18n-cli/) for more details.
59
+ Import `z` and `zodResolver` directly from `@ttoss/forms`. Invalid fields display i18n-backed default messages (`"Field is required"`, `"Invalid Value for Field of type {expected}"`, `"Field must be at least {min} characters"`). Run `pnpm run i18n` to extract them and translate per locale in your app's i18n files. See the [i18n-CLI documentation](https://ttoss.dev/docs/modules/packages/i18n-cli/) for details.
101
60
 
102
61
  ### Custom Validations
103
62
 
104
- The package extends Zod with custom validation methods for Brazilian documents:
105
-
106
- #### CPF Validation
63
+ The package extends Zod with custom validation methods:
107
64
 
108
65
  ```tsx
109
- import { z } from '@ttoss/forms';
66
+ import { z, passwordSchema } from '@ttoss/forms';
110
67
 
111
68
  const schema = z.object({
112
- cpf: z.string().cpf(), // Uses default message: "Invalid CPF"
113
- // Or with custom message:
114
- cpfCustom: z.string().cpf('CPF inválido'),
69
+ cpf: z.string().cpf(), // "Invalid CPF"
70
+ cnpj: z.string().cnpj('Invalid CNPJ'), // custom message
71
+ password: passwordSchema({ required: true }), // min 8 chars
72
+ optionalPassword: passwordSchema(), // empty or min 8 chars
115
73
  });
116
74
  ```
117
75
 
118
- #### CNPJ Validation
119
-
120
- ````
121
-
122
- ```tsx
123
- import { z } from '@ttoss/forms';
124
-
125
- const schema = z.object({
126
- cnpj: z.string().cnpj(), // Uses default message: "Invalid CNPJ"
127
- // Or with custom message:
128
- cnpjCustom: z.string().cnpj('CNPJ inválido'),
129
- });
130
- ````
131
-
132
- #### Password Validation
133
-
134
- ```tsx
135
- import { passwordSchema } from '@ttoss/forms';
136
- import { z } from '@ttoss/forms';
137
-
138
- const schema = z.object({
139
- // Required password (minimum 8 characters)
140
- password: passwordSchema({ required: true }),
141
-
142
- // Optional password (accepts empty string or minimum 8 characters)
143
- optionalPassword: passwordSchema(),
144
- });
145
- ```
76
+ Also exports `isCnpjValid(cnpj: string)` for standalone validation.
146
77
 
147
78
  ## Yup Validation (Deprecated)
148
79
 
149
- > **DEPRECATION WARNING:** Yup support is deprecated and will be removed in a future major version. Please migrate to Zod for new projects. Existing Yup schemas will continue to work, but we recommend planning your migration to Zod.
150
-
151
- For legacy projects still using Yup, you can import `yup` and `yupResolver` from `@ttoss/forms`:
152
-
153
- ```tsx
154
- import { Form, FormFieldInput, useForm, yup, yupResolver } from '@ttoss/forms';
155
-
156
- const schema = yup.object({
157
- firstName: yup.string().required(),
158
- });
159
-
160
- const MyForm = () => {
161
- const formMethods = useForm({
162
- resolver: yupResolver(schema),
163
- });
164
-
165
- return (
166
- <Form {...formMethods} onSubmit={(data) => console.log(data)}>
167
- <FormFieldInput name="firstName" label="First Name" />
168
- <Button type="submit">Submit</Button>
169
- </Form>
170
- );
171
- };
172
- ```
80
+ > **DEPRECATION WARNING:** Yup support will be removed in a future major version. `yup` and `yupResolver` are still exported from `@ttoss/forms` for legacy projects, but new projects should use Zod.
173
81
 
174
82
  ## Validation Approaches
175
83
 
176
- There are two ways to validate form fields in `@ttoss/forms`: schema-based validation using Zod schemas with `zodResolver`, and field-level validation using the `rules` prop on individual form fields.
177
-
178
- **IMPORTANT:** You cannot mix both validation methods for the same field—choose either schema-based or field-level validation per field.
179
-
180
- **When to use schema validation:**
181
-
182
- - Cross-field validation
183
- - Complex business logic
184
- - Reusable validation patterns
185
- - Type-safe validation with TypeScript
186
-
187
- **When to use `rules`:**
188
-
189
- - Simple, field-specific validations
190
- - Dynamic validation based on component state
191
- - Quick prototyping
192
- - Single-field conditional logic
84
+ There are two ways to validate form fields choose one per field, they cannot be mixed.
193
85
 
194
- ### 1. Schema-based Validation (Recommended)
86
+ **Schema-based validation** (`zodResolver`) is recommended for cross-field validation, complex business logic, and reusable/type-safe schemas.
195
87
 
196
- Use Zod schemas with `zodResolver` for complex validation logic:
197
-
198
- ```tsx
199
- import { z, zodResolver } from '@ttoss/forms';
200
-
201
- const schema = z.object({
202
- email: z.string().email(),
203
- age: z.number().min(18).max(100),
204
- });
205
-
206
- const formMethods = useForm({
207
- resolver: zodResolver(schema),
208
- });
209
- ```
210
-
211
- **Advantages:**
212
-
213
- - Centralized validation logic
214
- - Type-safe with TypeScript
215
- - Reusable schemas
216
- - Complex validation patterns
217
- - Schema composition
218
-
219
- ### 2. Field-level Validation
220
-
221
- Use the `rules` prop on individual form fields for simpler validations:
88
+ **Field-level validation** (`rules` prop) suits simple, field-specific cases:
222
89
 
223
90
  ```tsx
224
91
  <FormFieldInput
@@ -226,358 +93,78 @@ Use the `rules` prop on individual form fields for simpler validations:
226
93
  label="Username"
227
94
  rules={{
228
95
  required: 'Username is required',
229
- minLength: {
230
- value: 3,
231
- message: 'Username must be at least 3 characters',
232
- },
96
+ minLength: { value: 3, message: 'Min 3 characters' },
233
97
  pattern: {
234
98
  value: /^[a-zA-Z0-9_]+$/,
235
- message: 'Only letters, numbers, and underscores allowed',
236
- },
237
- }}
238
- />
239
-
240
- <FormFieldInput
241
- name="email"
242
- label="Email"
243
- rules={{
244
- required: 'Email is required',
245
- validate: (value) => {
246
- return value.includes('@') || 'Invalid email format';
99
+ message: 'Letters, numbers, underscores only',
247
100
  },
248
101
  }}
249
102
  />
250
103
  ```
251
104
 
252
- **Available validation rules:**
253
-
254
- - `required`: Field is required (string message or boolean)
255
- - `min`: Minimum value (for numbers)
256
- - `max`: Maximum value (for numbers)
257
- - `minLength`: Minimum string length
258
- - `maxLength`: Maximum string length
259
- - `pattern`: RegExp pattern
260
- - `validate`: Custom validation function or object of functions
105
+ Available `rules` keys: `required`, `min`, `max`, `minLength`, `maxLength`, `pattern`, `validate`.
261
106
 
262
107
  ## Form Field Components
263
108
 
264
- All form field components share common props:
109
+ > **Interactive examples for every component are available at [storybook.ttoss.dev](https://storybook.ttoss.dev/) under the Forms section.**
110
+
111
+ All form field components share these common props:
265
112
 
266
113
  - `name` (required): Field name in the form
267
114
  - `label`: Field label text
268
- - `disabled`: Disables the field
115
+ - `disabled`: Disables the field (field-level overrides form-level `disabled`)
269
116
  - `defaultValue`: Initial field value
270
117
  - `tooltip`: Label tooltip configuration
271
118
  - `warning`: Warning message displayed below the field
272
- - `auxiliaryCheckbox`: Optional auxiliary checkbox configuration
119
+ - `auxiliaryCheckbox`: Optional checkbox rendered between the field and error message — useful for confirmation or terms acceptance. Props: `name`, `label`, `disabled`, `defaultValue`.
273
120
  - `sx`: Theme-UI styling object
274
121
 
275
- ### Disabling Form Fields
276
-
277
- You can disable form fields in two ways:
278
-
279
- **1. Disable the entire form:**
280
-
281
- Set `disabled: true` in `useForm` to disable all fields at once:
122
+ To disable all fields at once, pass `disabled` to `useForm`:
282
123
 
283
124
  ```tsx
284
- const formMethods = useForm({
285
- disabled: true, // Disables all fields
286
- });
287
- ```
288
-
289
- This is particularly useful for preventing user interaction during asynchronous operations:
290
-
291
- ```tsx
292
- const [isSubmitting, setIsSubmitting] = useState(false);
293
-
294
- const formMethods = useForm({
295
- disabled: isSubmitting, // Disable form during submission
296
- });
297
-
298
- const onSubmit = async (data) => {
299
- setIsSubmitting(true);
300
- await saveData(data);
301
- setIsSubmitting(false);
302
- };
303
- ```
304
-
305
- **2. Disable individual fields:**
306
-
307
- Use the `disabled` prop on specific form field components:
308
-
309
- ```tsx
310
- <FormFieldInput name="email" label="Email" disabled />
125
+ const formMethods = useForm({ disabled: isSubmitting });
311
126
  ```
312
127
 
313
- Field-level `disabled` props override the form-level setting:
128
+ ### Available Components
314
129
 
315
- ```tsx
316
- const formMethods = useForm({
317
- disabled: false,
318
- });
130
+ | Component | Description |
131
+ | --------------------------- | --------------------------------------------------------------------------------------------------- |
132
+ | `FormFieldInput` | Text input — supports all HTML input types |
133
+ | `FormFieldPassword` | Password input with show/hide toggle |
134
+ | `FormFieldTextarea` | Multi-line text input |
135
+ | `FormFieldCheckbox` | Single checkbox |
136
+ | `FormFieldSwitch` | Toggle switch |
137
+ | `FormFieldRadio` | Radio button group |
138
+ | `FormFieldRadioCard` | Radio buttons styled as cards |
139
+ | `FormFieldRadioCardIcony` | Radio cards with icon support |
140
+ | `FormFieldSelect` | Dropdown — defaults to first option; `placeholder` and `defaultValue` cannot be used together |
141
+ | `FormFieldSegmentedControl` | Segmented buttons wrapping `SegmentedControl` from `@ttoss/ui`; `variant` defaults to `"secondary"` |
142
+ | `FormFieldNumericFormat` | Numeric input with decimals/thousands formatting |
143
+ | `FormFieldCurrencyInput` | Currency input with locale-based separators (see below) |
144
+ | `FormFieldPatternFormat` | Input with custom format patterns |
145
+ | `FormFieldPhone` | Phone input with optional country-code dropdown (see below) |
146
+ | `FormFieldCreditCardNumber` | Credit card input with automatic formatting |
319
147
 
320
- // This field will be disabled even though the form is enabled
321
- <FormFieldInput name="id" label="ID" disabled />;
322
- ```
323
-
324
- ### Auxiliary Checkbox
325
-
326
- Form fields can include an optional auxiliary checkbox rendered between the field and error message. This is useful for input confirmation, terms acceptance, or conditional display of other fields.
327
-
328
- ```tsx
329
- <FormFieldInput
330
- name="email"
331
- label="Email"
332
- auxiliaryCheckbox={{
333
- name: 'confirmEmail',
334
- label: 'Send me promotional emails',
335
- }}
336
- />
337
- ```
338
-
339
- The auxiliary checkbox can be disabled independently of the main field:
340
-
341
- ```tsx
342
- <FormFieldInput
343
- name="email"
344
- label="Email"
345
- auxiliaryCheckbox={{
346
- name: 'confirmEmail',
347
- label: 'Send me promotional emails',
348
- disabled: true, // Checkbox is disabled, but email field is enabled
349
- }}
350
- />
351
- ```
352
-
353
- **Props for `auxiliaryCheckbox`:**
354
-
355
- - `name` (required): Field name for the checkbox
356
- - `label` (required): Checkbox label text
357
- - `disabled`: Disables the checkbox (independent of field disabled state)
358
- - `defaultValue`: Initial checkbox value
359
-
360
- The auxiliary checkbox's disabled state is the logical OR of its own `disabled` prop and the field's disabled state.
361
-
362
- ### FormFieldInput
363
-
364
- Text input field supporting all HTML input types.
365
-
366
- ```tsx
367
- <FormFieldInput
368
- name="email"
369
- label="Email"
370
- type="email"
371
- placeholder="Enter your email"
372
- />
373
- ```
374
-
375
- ### FormFieldPassword
376
-
377
- Password input with show/hide toggle.
378
-
379
- ```tsx
380
- <FormFieldPassword name="password" label="Password" />
381
- ```
148
+ ### FormFieldCurrencyInput Locale Separators
382
149
 
383
- ### FormFieldTextarea
384
-
385
- Multi-line text input.
386
-
387
- ```tsx
388
- <FormFieldTextarea name="description" label="Description" rows={4} />
389
- ```
390
-
391
- ### FormFieldCheckbox
392
-
393
- Single checkbox or checkbox group.
394
-
395
- ```tsx
396
- <FormFieldCheckbox name="terms" label="I accept the terms" />
397
- ```
398
-
399
- ### FormFieldSwitch
400
-
401
- Toggle switch component.
402
-
403
- ```tsx
404
- <FormFieldSwitch name="notifications" label="Enable notifications" />
405
- ```
406
-
407
- ### FormFieldRadio
408
-
409
- Radio button group.
410
-
411
- ```tsx
412
- const options = [
413
- { value: 'option1', label: 'Option 1' },
414
- { value: 'option2', label: 'Option 2' },
415
- ];
416
-
417
- <FormFieldRadio name="choice" label="Choose one" options={options} />;
418
- ```
419
-
420
- ### FormFieldRadioCard
421
-
422
- Radio buttons styled as cards.
423
-
424
- ```tsx
425
- <FormFieldRadioCard name="plan" label="Select Plan" options={options} />
426
- ```
427
-
428
- ### FormFieldRadioCardIcony
429
-
430
- Radio cards with icon support.
431
-
432
- ```tsx
433
- const options = [
434
- { value: 'card', label: 'Credit Card', icon: 'credit-card' },
435
- { value: 'bank', label: 'Bank Transfer', icon: 'bank' },
436
- ];
437
-
438
- <FormFieldRadioCardIcony
439
- name="payment"
440
- label="Payment Method"
441
- options={options}
442
- />;
443
- ```
444
-
445
- ### FormFieldSelect
446
-
447
- Dropdown select field.
448
-
449
- ```tsx
450
- const options = [
451
- { value: 'ferrari', label: 'Ferrari' },
452
- { value: 'mercedes', label: 'Mercedes' },
453
- { value: 'bmw', label: 'BMW' },
454
- ];
455
-
456
- <FormFieldSelect name="car" label="Choose a car" options={options} />;
457
- ```
458
-
459
- #### FormFieldSelect Default Values
460
-
461
- `FormFieldSelect` defaults to the first option or a specified `defaultValue`:
462
-
463
- ```tsx
464
- // Defaults to "Ferrari"
465
- <FormFieldSelect name="car" label="Cars" options={options} />
466
-
467
- // Defaults to "Mercedes"
468
- <FormFieldSelect
469
- name="car"
470
- label="Cars"
471
- options={options}
472
- defaultValue="Mercedes"
473
- />
474
- ```
475
-
476
- ### FormFieldSegmentedControl
477
-
478
- Segmented control field wrapping the `SegmentedControl` from `@ttoss/ui`. Use this field when you want a compact set of mutually-exclusive options presented as segmented buttons.
479
-
480
- Props are the common form field props plus any `SegmentedControl` props (except `value` and `className`). Notably, the `variant` prop is supported and defaults to `"secondary"` if not provided.
481
-
482
- ```tsx
483
- <FormFieldSegmentedControl
484
- name="viewMode"
485
- label="View"
486
- options={[
487
- { value: 'list', label: 'List' },
488
- { value: 'grid', label: 'Grid' },
489
- ]}
490
- variant="primary" // optional, defaults to "secondary"
491
- defaultValue="list"
492
- />
493
- ```
494
-
495
- When using a `placeholder`, an empty option is automatically added if not present:
496
-
497
- ```tsx
498
- <FormFieldSelect
499
- name="car"
500
- label="Cars"
501
- options={options}
502
- placeholder="Select a car"
503
- />
504
- ```
505
-
506
- **Note:** `placeholder` and `defaultValue` cannot be used together.
507
-
508
- For dynamic options from async data, reset the field after loading:
509
-
510
- ```tsx
511
- const { resetField } = useForm();
512
- const [options, setOptions] = useState([]);
513
-
514
- useEffect(() => {
515
- // Fetch options
516
- const fetchedOptions = await fetchData();
517
- setOptions(fetchedOptions);
518
- resetField('car', { defaultValue: 'Ferrari' });
519
- }, []);
520
- ```
521
-
522
- ### FormFieldNumericFormat
523
-
524
- Numeric input with formatting support (decimals, thousands separators).
525
-
526
- ```tsx
527
- <FormFieldNumericFormat
528
- name="price"
529
- label="Price"
530
- thousandSeparator=","
531
- decimalScale={2}
532
- />
533
- ```
534
-
535
- ### FormFieldCurrencyInput
536
-
537
- Currency input with locale-based formatting. The decimal and thousand separators are automatically determined by the locale set in the `I18nProvider`.
538
-
539
- ```tsx
540
- <FormFieldCurrencyInput name="amount" label="Amount" prefix="$" />
541
- ```
542
-
543
- #### Customizing Separators per Locale
544
-
545
- The component uses i18n messages to determine the decimal and thousand separators based on the current locale. You can customize these for each locale in your application:
546
-
547
- 1. First, extract the i18n messages by running `pnpm run i18n` in your package
548
- 2. In your application's i18n files (e.g., `i18n/compiled/pt-BR.json`), add the custom separators:
150
+ The decimal and thousand separators are driven by i18n. To customize per locale, add to your app's i18n file (e.g., `i18n/compiled/pt-BR.json`):
549
151
 
550
152
  ```json
551
153
  {
552
- "JnCaDG": ",", // Decimal separator (default: ".")
553
- "0+4wTp": "." // Thousand separator (default: ",")
154
+ "JnCaDG": ",",
155
+ "0+4wTp": "."
554
156
  }
555
157
  ```
556
158
 
557
- This approach allows each locale to define its own number formatting rules, which will be automatically applied to all currency inputs.
558
-
559
- For more information about the i18n workflow, see the [i18n-CLI documentation](https://ttoss.dev/docs/modules/packages/i18n-cli/).
560
-
561
- ### FormFieldPatternFormat
562
-
563
- Input with custom format patterns.
564
-
565
- ```tsx
566
- <FormFieldPatternFormat
567
- name="phone"
568
- label="Phone"
569
- format="+1 (###) ###-####"
570
- mask="_"
571
- />
572
- ```
573
-
574
- ### FormFieldCreditCardNumber
159
+ ### FormFieldPhone Key Props
575
160
 
576
- Credit card input with automatic formatting.
161
+ The submitted value always includes the country code prefix (e.g. `{ phone: '+15555555555' }`). When the user selects the **Manual** entry, the mask is removed and any international number can be typed freely.
577
162
 
578
- ```tsx
579
- <FormFieldCreditCardNumber name="cardNumber" label="Card Number" />
580
- ```
163
+ - `defaultCountryCode`: Initial calling code (e.g. `'+1'`). Defaults to the first entry in `countryCodeOptions`.
164
+ - `format`: Pattern string for the local number part (e.g. `'(###) ###-####'`).
165
+ - `countryCodeOptions`: Defaults to `COMMON_PHONE_COUNTRY_CODES`. Pass `[]` to hide the dropdown.
166
+ - `onCountryCodeChange`: Callback fired when the user picks a different country code.
167
+ - `countryCodeName`: Stores the selected country code as a separate form field (e.g. `{ phone: '+15555555555', countryCode: '+1' }`).
581
168
 
582
169
  ### Brazil-Specific Fields
583
170
 
@@ -591,161 +178,30 @@ import {
591
178
  } from '@ttoss/forms/brazil';
592
179
  ```
593
180
 
594
- #### FormFieldCEP
595
-
596
- Brazilian postal code (CEP) input with automatic formatting.
597
-
598
- ```tsx
599
- <FormFieldCEP name="cep" label="CEP" />
600
- ```
601
-
602
- #### FormFieldCNPJ
603
-
604
- Brazilian tax ID (CNPJ) input with validation and formatting.
605
-
606
- ```tsx
607
- <FormFieldCNPJ name="cnpj" label="CNPJ" />
608
- ```
609
-
610
- The package also exports `isCnpjValid(cnpj: string)` for standalone validation.
611
-
612
- #### FormFieldPhone
613
-
614
- Brazilian phone number input with formatting.
615
-
616
- ```tsx
617
- <FormFieldPhone name="phone" label="Phone" />
618
- ```
181
+ - `FormFieldCEP` — postal code with automatic formatting
182
+ - `FormFieldCNPJ` — tax ID with validation and formatting
183
+ - `FormFieldPhone` phone with `+55` country code pre-set
619
184
 
620
185
  ## FormGroup
621
186
 
622
- Groups related fields with an optional title, description, and layout direction.
623
-
624
- ```tsx
625
- <FormGroup title="Personal Information" direction="row">
626
- <FormFieldInput name="firstName" label="First Name" />
627
- <FormFieldInput name="lastName" label="Last Name" />
628
- </FormGroup>
629
-
630
- <FormGroup title="Address" description="Where we'll send your order">
631
- <FormFieldInput name="street" label="Street" />
632
- <FormFieldInput name="city" label="City" />
633
- </FormGroup>
634
- ```
635
-
636
- Nest `FormGroup` components to create hierarchical sections:
637
-
638
- ```tsx
639
- <FormGroup title="Personal details">
640
- <FormFieldInput name="firstName" label="First name" />
641
- <FormFieldInput name="lastName" label="Last name" />
642
-
643
- <FormGroup title="Address" direction="row">
644
- <FormFieldInput name="city" label="City" />
645
- <FormFieldInput name="zip" label="ZIP" />
646
- </FormGroup>
647
- </FormGroup>
648
- ```
649
-
650
- To display a group-level validation error (e.g. for an array field), pass the `name` prop:
651
-
652
- ```tsx
653
- <FormGroup name="items" title="Items">
654
- {fields.map((field, i) => (
655
- <FormFieldInput key={field.id} name={`items[${i}].value`} label="Value" />
656
- ))}
657
- </FormGroup>
658
- ```
187
+ Groups related fields with an optional title, description, and layout direction. Pass `name` to display a group-level validation error (e.g. for array fields).
659
188
 
660
- **Props:**
189
+ **Props:** `title`, `description`, `direction` (`'row'` | `'column'`, default `'column'`), `name`.
661
190
 
662
- - `title`: Optional heading displayed above the group's children
663
- - `description`: Optional description displayed below the title
664
- - `direction`: Layout direction (`'row'` | `'column'`, default: `'column'`)
665
- - `name`: Field name used to display a group-level validation error message
191
+ See [Storybook](https://storybook.ttoss.dev/?path=/story/forms-formgroup) for nested group examples.
666
192
 
667
193
  ## Multistep Forms
668
194
 
669
- Import from `@ttoss/forms/multistep-form`:
195
+ Import from `@ttoss/forms/multistep-form`. Each step provides its own `schema` (Zod) and `fields` (React elements); data is accumulated and passed to `onSubmit` on the final step.
670
196
 
671
197
  ```tsx
672
198
  import { MultistepForm } from '@ttoss/forms/multistep-form';
673
- import { FormFieldInput, z } from '@ttoss/forms';
674
-
675
- const steps = [
676
- {
677
- label: 'Step 1',
678
- question: 'What is your name?',
679
- fields: <FormFieldInput name="name" label="Name" />,
680
- schema: z.object({
681
- name: z.string().min(1, 'Name is required'),
682
- }),
683
- },
684
- {
685
- label: 'Step 2',
686
- question: 'How old are you?',
687
- fields: <FormFieldInput type="number" name="age" label="Age" />,
688
- defaultValues: { age: 18 },
689
- schema: z.object({
690
- age: z.number().min(18, 'Must be at least 18'),
691
- }),
692
- },
693
- ];
694
-
695
- const MyForm = () => {
696
- return (
697
- <MultistepForm
698
- steps={steps}
699
- onSubmit={(data) => console.log(data)}
700
- footer="© 2024 Company"
701
- header={{
702
- variant: 'logo',
703
- src: '/logo.png',
704
- onClose: () => console.log('closed'),
705
- }}
706
- />
707
- );
708
- };
709
199
  ```
710
200
 
711
- ### MultistepForm Props
712
-
713
- - `steps`: Array of step configurations
714
- - `onSubmit`: Handler called with complete form data
715
- - `footer`: Footer text
716
- - `header`: Header configuration (see below)
717
-
718
- ### Step Configuration
719
-
720
- Each step object contains:
201
+ **`MultistepForm` props:** `steps`, `onSubmit`, `footer`, `header`.
721
202
 
722
- - `label`: Step label for navigation
723
- - `question`: Question or instruction text
724
- - `fields`: React element(s) containing form fields
725
- - `schema`: Zod validation schema
726
- - `defaultValues`: Optional default values for step fields
203
+ **Step object:** `label`, `question`, `fields`, `schema`, `defaultValues`.
727
204
 
728
- ### Header Types
205
+ **`header` variants:** `{ variant: 'logo', src, onClose }` or `{ variant: 'titled', title, leftIcon, rightIcon, onLeftIconClick, onRightIconClick }`.
729
206
 
730
- **Logo Header:**
731
-
732
- ```tsx
733
- {
734
- variant: 'logo',
735
- src: '/path/to/logo.png',
736
- onClose: () => console.log('Close clicked')
737
- }
738
- ```
739
-
740
- **Titled Header:**
741
-
742
- ```tsx
743
- {
744
- variant: 'titled',
745
- title: 'Form Title',
746
- leftIcon: 'arrow-left',
747
- rightIcon: 'close',
748
- onLeftIconClick: () => console.log('Back'),
749
- onRightIconClick: () => console.log('Close')
750
- }
751
- ```
207
+ See [Storybook](https://storybook.ttoss.dev/?path=/story/forms-multistepform) for an interactive example.
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { FieldValues, FieldPath } from 'react-hook-form';
3
- import { a as FormFieldPatternFormatProps, F as FormFieldProps, d as FormFieldPhoneProps$1 } from '../FormFieldPhone-BKeOS0i6.js';
3
+ import { a as FormFieldPatternFormatProps, F as FormFieldProps, d as FormFieldPhoneProps$1 } from '../FormFieldPhone-Dp3kaJbz.js';
4
4
  import { PatternFormatProps, NumberFormatBaseProps } from 'react-number-format';
5
5
  import '@ttoss/ui';
6
6
  import 'react';
@@ -19,7 +19,7 @@ declare const FormFieldCPF: <TFieldValues extends FieldValues = FieldValues, TNa
19
19
  type FormFieldCPFOrCNPJProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = FormFieldProps<TFieldValues, TName> & Omit<NumberFormatBaseProps, 'name' | 'format'>;
20
20
  declare const FormFieldCPFOrCNPJ: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ disabled, ...props }: FormFieldCPFOrCNPJProps<TFieldValues, TName>) => react_jsx_runtime.JSX.Element;
21
21
 
22
- type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = Omit<FormFieldPhoneProps$1<TFieldValues, TName>, 'countryCode' | 'format'>;
22
+ type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = Omit<FormFieldPhoneProps$1<TFieldValues, TName>, 'defaultCountryCode' | 'format'>;
23
23
  /**
24
24
  * Brazilian phone number form field.
25
25
  *
@@ -109,11 +109,12 @@ declare const COMMON_PHONE_COUNTRY_CODES: CountryCodeOption[];
109
109
 
110
110
  type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = FormFieldProps<TFieldValues, TName> & Omit<PatternFormatProps, 'name' | 'format'> & {
111
111
  /**
112
- * The country calling code to display as a literal prefix in the input.
112
+ * The initial country calling code to display as a literal prefix in the input.
113
113
  * For example, '+55' for Brazil or '+1' for the United States.
114
114
  * Defaults to the first entry in `countryCodeOptions` when not provided.
115
+ * The component manages the selected code internally — no external state needed.
115
116
  */
116
- countryCode?: string;
117
+ defaultCountryCode?: string;
117
118
  /**
118
119
  * The pattern format for the local part of the phone number.
119
120
  * Accepts either a static string (e.g., '(##) #####-####') or a function
@@ -136,11 +137,25 @@ type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName e
136
137
  */
137
138
  countryCodeOptions?: CountryCodeOption[];
138
139
  /**
139
- * Called with the newly selected country code value when the user changes
140
- * the country code via the dropdown. Only relevant when
141
- * countryCodeOptions is non-empty.
140
+ * Optional callback fired with the newly selected country code value when
141
+ * the user changes the country code via the dropdown. The component
142
+ * manages the selected code internally, so this is only needed when the
143
+ * caller wants to react to country-code changes.
142
144
  */
143
145
  onCountryCodeChange?: (countryCode: string) => void;
146
+ /**
147
+ * When provided, the selected country code is stored as a separate field
148
+ * in the form under this name (e.g. `'countryCode'`). This allows the
149
+ * submitted form data to include both the full phone value and the
150
+ * selected calling code independently.
151
+ *
152
+ * @example
153
+ * ```tsx
154
+ * // Form data: { phone: '+15555555555', countryCode: '+1' }
155
+ * <FormFieldPhone name="phone" label="Phone" countryCodeName="countryCode" />
156
+ * ```
157
+ */
158
+ countryCodeName?: string;
144
159
  };
145
160
  /**
146
161
  * Generic phone number form field that supports an optional country code prefix.
@@ -168,26 +183,30 @@ type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName e
168
183
  *
169
184
  * @example
170
185
  * ```tsx
171
- * // Default: dropdown with COMMON_PHONE_COUNTRY_CODES, US (+1) pre-selected
172
- * <FormFieldPhone name="phone" label="Phone" countryCode="+1" />
186
+ * // Default: dropdown with COMMON_PHONE_COUNTRY_CODES, country code managed internally.
187
+ * // The submitted value includes the country code prefix (e.g. '+15555555555').
188
+ * <FormFieldPhone name="phone" label="Phone" />
173
189
  * ```
174
190
  *
175
191
  * @example
176
192
  * ```tsx
177
- * // Controlled country code submitted value includes the prefix
178
- * // e.g. { phone: '+15555555555' }
179
- * const [countryCode, setCountryCode] = React.useState('+1');
193
+ * // Set a custom initial country code; the component manages further changes.
194
+ * <FormFieldPhone name="phone" label="Phone" defaultCountryCode="+55" />
195
+ * ```
196
+ *
197
+ * @example
198
+ * ```tsx
199
+ * // Listen for country-code changes without managing state externally.
180
200
  * <FormFieldPhone
181
201
  * name="phone"
182
202
  * label="Phone"
183
- * countryCode={countryCode}
184
- * onCountryCodeChange={setCountryCode}
203
+ * onCountryCodeChange={(code) => console.log('selected', code)}
185
204
  * />
186
205
  * ```
187
206
  *
188
207
  * @example
189
208
  * ```tsx
190
- * // No dropdown — plain phone input; value includes the prefix
209
+ * // No dropdown — plain phone input; value includes the prefix.
191
210
  * // e.g. { phone: '+15555555555' }
192
211
  * <FormFieldPhone
193
212
  * name="phone"
@@ -211,7 +230,18 @@ type FormFieldPhoneProps<TFieldValues extends FieldValues = FieldValues, TName e
211
230
  * countryCodeOptions={[]}
212
231
  * />
213
232
  * ```
233
+ *
234
+ * @example
235
+ * ```tsx
236
+ * // Store the selected country code as a separate form field.
237
+ * // Submitted data: { phone: '+15555555555', countryCode: '+1' }
238
+ * <FormFieldPhone
239
+ * name="phone"
240
+ * label="Phone"
241
+ * countryCodeName="countryCode"
242
+ * />
243
+ * ```
214
244
  */
215
- declare const FormFieldPhone: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ disabled, countryCode: countryCodeProp, format, countryCodeOptions, onCountryCodeChange, ...props }: FormFieldPhoneProps<TFieldValues, TName>) => react_jsx_runtime.JSX.Element;
245
+ declare const FormFieldPhone: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ disabled, defaultCountryCode: countryCodeProp, format, countryCodeOptions, onCountryCodeChange, countryCodeName, ...props }: FormFieldPhoneProps<TFieldValues, TName>) => react_jsx_runtime.JSX.Element;
216
246
 
217
247
  export { type CountryCodeOption as C, type FormFieldProps as F, MANUAL_PHONE_COUNTRY_CODE as M, type FormFieldPatternFormatProps as a, FormField as b, FormFieldPatternFormat as c, type FormFieldPhoneProps as d, FormFieldPhone as e, COMMON_PHONE_COUNTRY_CODES as f };
@@ -1,6 +1,6 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
  import * as React from 'react';
3
- import { FormField, FormFieldCNPJ, FormFieldCPF, FormFieldPatternFormat, FormFieldPhone, __name, isCnpjValid, isCpfValid } from "../chunk-ZORKZWD7.js";
3
+ import { FormField, FormFieldCNPJ, FormFieldCPF, FormFieldPatternFormat, FormFieldPhone, __name, isCnpjValid, isCpfValid } from "../chunk-NEIQETLB.js";
4
4
 
5
5
  // src/Brazil/FormFieldCEP.tsx
6
6
  var FormFieldCEP = /* @__PURE__ */__name(({
@@ -84,7 +84,7 @@ var FormFieldPhone2 = /* @__PURE__ */__name(({
84
84
  }) => {
85
85
  return /* @__PURE__ */React.createElement(FormFieldPhone, {
86
86
  ...props,
87
- countryCode: BRAZIL_COUNTRY_CODE,
87
+ defaultCountryCode: BRAZIL_COUNTRY_CODE,
88
88
  format: getBrazilPhoneFormat,
89
89
  placeholder,
90
90
  countryCodeOptions
@@ -1,7 +1,7 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
  import * as React from 'react';
3
- import { Form, useForm, yupResolver } from "../chunk-4YLT3VPV.js";
4
- import { __name } from "../chunk-ZORKZWD7.js";
3
+ import { Form, useForm, yupResolver } from "../chunk-UT6OKRDR.js";
4
+ import { __name } from "../chunk-NEIQETLB.js";
5
5
 
6
6
  // src/MultistepForm/MultistepForm.tsx
7
7
  import { Flex as Flex6 } from "@ttoss/ui";
@@ -268,6 +268,59 @@ var FormFieldPatternFormat = /* @__PURE__ */__name(({
268
268
  });
269
269
  }, "FormFieldPatternFormat");
270
270
 
271
+ // src/FormFieldSelect.tsx
272
+ import { Select } from "@ttoss/ui";
273
+ var FormFieldSelect = /* @__PURE__ */__name(({
274
+ disabled,
275
+ ...props
276
+ }) => {
277
+ const {
278
+ label,
279
+ name,
280
+ labelTooltip,
281
+ warning,
282
+ sx,
283
+ css,
284
+ rules,
285
+ id,
286
+ defaultValue,
287
+ onBlur,
288
+ onChange,
289
+ ...selectProps
290
+ } = props;
291
+ return /* @__PURE__ */React.createElement(FormField, {
292
+ id,
293
+ label,
294
+ name,
295
+ labelTooltip,
296
+ warning,
297
+ sx,
298
+ css,
299
+ defaultValue,
300
+ rules,
301
+ disabled,
302
+ render: /* @__PURE__ */__name(({
303
+ field,
304
+ fieldState
305
+ }) => {
306
+ return /* @__PURE__ */React.createElement(Select, {
307
+ ...selectProps,
308
+ ...field,
309
+ onBlur: /* @__PURE__ */__name(e => {
310
+ field.onBlur();
311
+ onBlur?.(e);
312
+ }, "onBlur"),
313
+ onChange: /* @__PURE__ */__name(newValue => {
314
+ field.onChange(newValue);
315
+ onChange?.(newValue);
316
+ }, "onChange"),
317
+ isDisabled: disabled ?? field.disabled,
318
+ "aria-invalid": fieldState.error ? "true" : void 0
319
+ });
320
+ }, "render")
321
+ });
322
+ }, "FormFieldSelect");
323
+
271
324
  // src/phoneCountryCodes.ts
272
325
  var MANUAL_PHONE_COUNTRY_CODE = "manual";
273
326
  var COMMON_PHONE_COUNTRY_CODES = [{
@@ -336,12 +389,14 @@ var COMMON_PHONE_COUNTRY_CODES = [{
336
389
  }];
337
390
 
338
391
  // src/FormFieldPhone.tsx
339
- import { Box, Flex as Flex3, Input as Input2, Select } from "@ttoss/ui";
392
+ import { Box, Flex as Flex3, Input as Input2 } from "@ttoss/ui";
340
393
  import * as React4 from "react";
394
+ import { useFormContext as useFormContext3 } from "react-hook-form";
341
395
  import { NumericFormat, PatternFormat as PatternFormat2 } from "react-number-format";
342
396
  var PhoneDropdownWrapper = /* @__PURE__ */__name(({
343
397
  id,
344
- countryCode,
398
+ countryCodeFieldName,
399
+ defaultCountryCode,
345
400
  countryCodeOptions,
346
401
  disabled,
347
402
  onCountryCodeChange,
@@ -357,9 +412,10 @@ var PhoneDropdownWrapper = /* @__PURE__ */__name(({
357
412
  sx: {
358
413
  minWidth: "180px"
359
414
  }
360
- }, /* @__PURE__ */React4.createElement(Select, {
415
+ }, /* @__PURE__ */React4.createElement(FormFieldSelect, {
416
+ name: countryCodeFieldName,
417
+ defaultValue: defaultCountryCode,
361
418
  options: countryCodeOptions,
362
- value: countryCode,
363
419
  disabled,
364
420
  onChange: /* @__PURE__ */__name(value => {
365
421
  if (value !== void 0) {
@@ -377,10 +433,11 @@ var PhoneDropdownWrapper = /* @__PURE__ */__name(({
377
433
  }, "PhoneDropdownWrapper");
378
434
  var FormFieldPhone = /* @__PURE__ */__name(({
379
435
  disabled,
380
- countryCode: countryCodeProp,
436
+ defaultCountryCode: countryCodeProp,
381
437
  format,
382
438
  countryCodeOptions = COMMON_PHONE_COUNTRY_CODES,
383
439
  onCountryCodeChange,
440
+ countryCodeName,
384
441
  ...props
385
442
  }) => {
386
443
  const {
@@ -399,7 +456,15 @@ var FormFieldPhone = /* @__PURE__ */__name(({
399
456
  placeholder,
400
457
  ...patternFormatProps
401
458
  } = props;
402
- const countryCode = countryCodeProp ?? countryCodeOptions[0]?.value ?? void 0;
459
+ const {
460
+ watch
461
+ } = useFormContext3();
462
+ const countryCodeFieldName = countryCodeName ?? `${String(name)}CountryCode`;
463
+ const defaultCountryCode = countryCodeProp ?? countryCodeOptions[0]?.value ?? void 0;
464
+ const countryCode = watch(countryCodeFieldName) ?? defaultCountryCode;
465
+ const handleCountryCodeChange = /* @__PURE__ */__name(code => {
466
+ onCountryCodeChange?.(code);
467
+ }, "handleCountryCodeChange");
403
468
  const isManual = countryCode === MANUAL_PHONE_COUNTRY_CODE;
404
469
  const getFormat = /* @__PURE__ */__name(value => {
405
470
  const selectedOption = countryCodeOptions.find(opt => {
@@ -410,7 +475,16 @@ var FormFieldPhone = /* @__PURE__ */__name(({
410
475
  return countryCode && !isManual ? `${countryCode} ${baseFormat}` : baseFormat;
411
476
  }, "getFormat");
412
477
  const showDropdown = countryCodeOptions.length > 0;
413
- return /* @__PURE__ */React4.createElement(FormField, {
478
+ const hiddenCountryCodeSelect = !showDropdown && countryCodeName ? /* @__PURE__ */React4.createElement(Box, {
479
+ sx: {
480
+ display: "none"
481
+ }
482
+ }, /* @__PURE__ */React4.createElement(FormFieldSelect, {
483
+ name: countryCodeName,
484
+ defaultValue: defaultCountryCode,
485
+ options: []
486
+ })) : null;
487
+ return /* @__PURE__ */React4.createElement(React4.Fragment, null, hiddenCountryCodeSelect, /* @__PURE__ */React4.createElement(FormField, {
414
488
  id,
415
489
  label,
416
490
  name,
@@ -469,17 +543,18 @@ var FormFieldPhone = /* @__PURE__ */__name(({
469
543
  return inputNode;
470
544
  }
471
545
  return /* @__PURE__ */React4.createElement(PhoneDropdownWrapper, {
472
- countryCode,
546
+ countryCodeFieldName,
547
+ defaultCountryCode,
473
548
  countryCodeOptions,
474
549
  disabled: disabled ?? field.disabled,
475
- onCountryCodeChange,
550
+ onCountryCodeChange: handleCountryCodeChange,
476
551
  onPhoneReset: /* @__PURE__ */__name(() => {
477
552
  return field.onChange("");
478
553
  }, "onPhoneReset"),
479
554
  inputNode
480
555
  });
481
556
  }, "render")
482
- });
557
+ }));
483
558
  }, "FormFieldPhone");
484
559
 
485
560
  // src/Brazil/FormFieldCNPJ.tsx
@@ -654,4 +729,4 @@ var FormFieldCPF = /* @__PURE__ */__name(({
654
729
  }, "render")
655
730
  });
656
731
  }, "FormFieldCPF");
657
- export { __name, FormErrorMessage, FormField, FormFieldPatternFormat, MANUAL_PHONE_COUNTRY_CODE, COMMON_PHONE_COUNTRY_CODES, FormFieldPhone, isCnpjValid, FormFieldCNPJ, isCpfValid, FormFieldCPF };
732
+ export { __name, FormErrorMessage, FormField, FormFieldPatternFormat, FormFieldSelect, MANUAL_PHONE_COUNTRY_CODE, COMMON_PHONE_COUNTRY_CODES, FormFieldPhone, isCnpjValid, FormFieldCNPJ, isCpfValid, FormFieldCPF };
@@ -1,6 +1,6 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
  import * as React from 'react';
3
- import { FormErrorMessage, FormField, FormFieldPatternFormat, __name, isCnpjValid, isCpfValid } from "./chunk-ZORKZWD7.js";
3
+ import { FormErrorMessage, FormField, FormFieldPatternFormat, __name, isCnpjValid, isCpfValid } from "./chunk-NEIQETLB.js";
4
4
 
5
5
  // src/Form.tsx
6
6
  import { Box as Box2 } from "@ttoss/ui";
@@ -797,59 +797,6 @@ var FormFieldSegmentedControl = /* @__PURE__ */__name(({
797
797
  });
798
798
  }, "FormFieldSegmentedControl");
799
799
 
800
- // src/FormFieldSelect.tsx
801
- import { Select } from "@ttoss/ui";
802
- var FormFieldSelect = /* @__PURE__ */__name(({
803
- disabled,
804
- ...props
805
- }) => {
806
- const {
807
- label,
808
- name,
809
- labelTooltip,
810
- warning,
811
- sx,
812
- css,
813
- rules,
814
- id,
815
- defaultValue,
816
- onBlur,
817
- onChange,
818
- ...selectProps
819
- } = props;
820
- return /* @__PURE__ */React.createElement(FormField, {
821
- id,
822
- label,
823
- name,
824
- labelTooltip,
825
- warning,
826
- sx,
827
- css,
828
- defaultValue,
829
- rules,
830
- disabled,
831
- render: /* @__PURE__ */__name(({
832
- field,
833
- fieldState
834
- }) => {
835
- return /* @__PURE__ */React.createElement(Select, {
836
- ...selectProps,
837
- ...field,
838
- onBlur: /* @__PURE__ */__name(e => {
839
- field.onBlur();
840
- onBlur?.(e);
841
- }, "onBlur"),
842
- onChange: /* @__PURE__ */__name(newValue => {
843
- field.onChange(newValue);
844
- onChange?.(newValue);
845
- }, "onChange"),
846
- isDisabled: disabled ?? field.disabled,
847
- "aria-invalid": fieldState.error ? "true" : void 0
848
- });
849
- }, "render")
850
- });
851
- }, "FormFieldSelect");
852
-
853
800
  // src/FormFieldSwitch.tsx
854
801
  import { Switch } from "@ttoss/ui";
855
802
  var FormFieldSwitch = /* @__PURE__ */__name(({
@@ -1124,4 +1071,4 @@ import { yupResolver } from "@hookform/resolvers/yup";
1124
1071
  import { zodResolver } from "@hookform/resolvers/zod";
1125
1072
  import { Controller, FormProvider as FormProvider2, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch } from "react-hook-form";
1126
1073
  export * from "react-hook-form";
1127
- export { FormActions, useFormGroup, FormGroup, Form, FormFieldCheckbox, FormFieldCreditCardNumber, FormFieldNumericFormat, FormFieldCurrencyInput, FormFieldDatePicker, FormFieldInput, FormFieldPassword, FormFieldRadio, FormFieldRadioCard, FormFieldRadioCardIcony, FormFieldSegmentedControl, FormFieldSelect, FormFieldSwitch, FormFieldTextarea, yup2 as yup, z3 as z, yupResolver, zodResolver, Controller, FormProvider2 as FormProvider, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
1074
+ export { FormActions, useFormGroup, FormGroup, Form, FormFieldCheckbox, FormFieldCreditCardNumber, FormFieldNumericFormat, FormFieldCurrencyInput, FormFieldDatePicker, FormFieldInput, FormFieldPassword, FormFieldRadio, FormFieldRadioCard, FormFieldRadioCardIcony, FormFieldSegmentedControl, FormFieldSwitch, FormFieldTextarea, yup2 as yup, z3 as z, yupResolver, zodResolver, Controller, FormProvider2 as FormProvider, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
- import { Controller, Form, FormActions, FormFieldCheckbox, FormFieldCreditCardNumber, FormFieldCurrencyInput, FormFieldDatePicker, FormFieldInput, FormFieldNumericFormat, FormFieldPassword, FormFieldRadio, FormFieldRadioCard, FormFieldRadioCardIcony, FormFieldSegmentedControl, FormFieldSelect, FormFieldSwitch, FormFieldTextarea, FormGroup, FormProvider, useController, useFieldArray, useForm, useFormContext, useFormGroup, useFormState, useWatch, yup, yupResolver, z, zodResolver } from "./chunk-4YLT3VPV.js";
3
- import { COMMON_PHONE_COUNTRY_CODES, FormErrorMessage, FormField, FormFieldPatternFormat, FormFieldPhone, MANUAL_PHONE_COUNTRY_CODE } from "./chunk-ZORKZWD7.js";
2
+ import { Controller, Form, FormActions, FormFieldCheckbox, FormFieldCreditCardNumber, FormFieldCurrencyInput, FormFieldDatePicker, FormFieldInput, FormFieldNumericFormat, FormFieldPassword, FormFieldRadio, FormFieldRadioCard, FormFieldRadioCardIcony, FormFieldSegmentedControl, FormFieldSwitch, FormFieldTextarea, FormGroup, FormProvider, useController, useFieldArray, useForm, useFormContext, useFormGroup, useFormState, useWatch, yup, yupResolver, z, zodResolver } from "./chunk-UT6OKRDR.js";
3
+ import { COMMON_PHONE_COUNTRY_CODES, FormErrorMessage, FormField, FormFieldPatternFormat, FormFieldPhone, FormFieldSelect, MANUAL_PHONE_COUNTRY_CODE } from "./chunk-NEIQETLB.js";
4
4
  export { COMMON_PHONE_COUNTRY_CODES, Controller, Form, FormActions, FormErrorMessage, FormField, FormFieldCheckbox, FormFieldCreditCardNumber, FormFieldCurrencyInput, FormFieldDatePicker, FormFieldInput, FormFieldNumericFormat, FormFieldPassword, FormFieldPatternFormat, FormFieldPhone, FormFieldRadio, FormFieldRadioCard, FormFieldRadioCardIcony, FormFieldSegmentedControl, FormFieldSelect, FormFieldSwitch, FormFieldTextarea, FormGroup, FormProvider, MANUAL_PHONE_COUNTRY_CODE, useController, useFieldArray, useForm, useFormContext, useFormGroup, useFormState, useWatch, yup, yupResolver, z, zodResolver };
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@ import * as React from 'react';
4
4
  import { FieldValues, FormProviderProps, FieldName, FieldPath } from 'react-hook-form';
5
5
  export * from 'react-hook-form';
6
6
  export { Controller, FormProvider, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch } from 'react-hook-form';
7
- import { F as FormFieldProps, a as FormFieldPatternFormatProps } from './FormFieldPhone-BKeOS0i6.js';
8
- export { f as COMMON_PHONE_COUNTRY_CODES, C as CountryCodeOption, b as FormField, c as FormFieldPatternFormat, e as FormFieldPhone, d as FormFieldPhoneProps, M as MANUAL_PHONE_COUNTRY_CODE } from './FormFieldPhone-BKeOS0i6.js';
7
+ import { F as FormFieldProps, a as FormFieldPatternFormatProps } from './FormFieldPhone-Dp3kaJbz.js';
8
+ export { f as COMMON_PHONE_COUNTRY_CODES, C as CountryCodeOption, b as FormField, c as FormFieldPatternFormat, e as FormFieldPhone, d as FormFieldPhoneProps, M as MANUAL_PHONE_COUNTRY_CODE } from './FormFieldPhone-Dp3kaJbz.js';
9
9
  import { NumericFormatProps } from 'react-number-format';
10
10
  import { DateRange } from '@ttoss/components/DatePicker';
11
11
  import './typings.d-BzNUo1mD.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/forms",
3
- "version": "0.43.0",
3
+ "version": "0.43.2",
4
4
  "license": "MIT",
5
5
  "author": "ttoss",
6
6
  "contributors": [
@@ -40,9 +40,9 @@
40
40
  },
41
41
  "peerDependencies": {
42
42
  "react": ">=16.8.0",
43
- "@ttoss/react-i18n": "^2.1.0",
43
+ "@ttoss/components": "^2.13.2",
44
44
  "@ttoss/ui": "^6.8.0",
45
- "@ttoss/components": "^2.13.2"
45
+ "@ttoss/react-i18n": "^2.1.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/jest": "^30.0.0",
@@ -52,13 +52,13 @@
52
52
  "react-error-boundary": "^6.1.0",
53
53
  "tsup": "^8.5.1",
54
54
  "yup": "^1.7.1",
55
- "@ttoss/components": "^2.13.2",
55
+ "@ttoss/config": "^1.36.0",
56
56
  "@ttoss/i18n-cli": "^0.7.39",
57
57
  "@ttoss/react-i18n": "^2.1.0",
58
58
  "@ttoss/react-icons": "^0.6.0",
59
59
  "@ttoss/test-utils": "^4.1.0",
60
- "@ttoss/ui": "^6.8.0",
61
- "@ttoss/config": "^1.36.0"
60
+ "@ttoss/components": "^2.13.2",
61
+ "@ttoss/ui": "^6.8.0"
62
62
  },
63
63
  "publishConfig": {
64
64
  "access": "public",