@tanstack/react-form 0.16.1 → 0.18.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-form",
3
- "version": "0.16.1",
3
+ "version": "0.18.0",
4
4
  "description": "Powerful, type-safe forms for React.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "@tanstack/react-store": "^0.3.1",
44
44
  "decode-formdata": "^0.4.0",
45
45
  "rehackt": "^0.0.3",
46
- "@tanstack/form-core": "0.16.1"
46
+ "@tanstack/form-core": "0.18.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "react": "^17.0.0 || ^18.0.0"
@@ -608,6 +608,102 @@ describe('useField', () => {
608
608
  expect(queryByText('A first name is required')).not.toBeInTheDocument()
609
609
  })
610
610
 
611
+ it('should handle arrays with primitive values', async () => {
612
+ const fn = vi.fn()
613
+ function Comp() {
614
+ const form = useForm({
615
+ defaultValues: {
616
+ people: [] as Array<string>,
617
+ },
618
+ onSubmit: ({ value }) => fn(value),
619
+ })
620
+
621
+ return (
622
+ <div>
623
+ <form
624
+ onSubmit={(e) => {
625
+ e.preventDefault()
626
+ e.stopPropagation()
627
+ void form.handleSubmit()
628
+ }}
629
+ >
630
+ <form.Field name="people">
631
+ {(field) => {
632
+ return (
633
+ <div>
634
+ {field.state.value.map((_, i) => {
635
+ return (
636
+ <form.Field key={i} name={`people[${i}]`}>
637
+ {(subField) => {
638
+ return (
639
+ <div>
640
+ <label>
641
+ <div>Name for person {i}</div>
642
+ <input
643
+ value={subField.state.value}
644
+ onChange={(e) =>
645
+ subField.handleChange(e.target.value)
646
+ }
647
+ />
648
+ </label>
649
+ <button
650
+ onClick={() => field.removeValue(i)}
651
+ type="button"
652
+ >
653
+ Remove person {i}
654
+ </button>
655
+ </div>
656
+ )
657
+ }}
658
+ </form.Field>
659
+ )
660
+ })}
661
+ <button onClick={() => field.pushValue('')} type="button">
662
+ Add person
663
+ </button>
664
+ </div>
665
+ )
666
+ }}
667
+ </form.Field>
668
+ <form.Subscribe
669
+ selector={(state) => [state.canSubmit, state.isSubmitting]}
670
+ children={([canSubmit, isSubmitting]) => (
671
+ <button type="submit" disabled={!canSubmit}>
672
+ {isSubmitting ? '...' : 'Submit'}
673
+ </button>
674
+ )}
675
+ />
676
+ </form>
677
+ </div>
678
+ )
679
+ }
680
+
681
+ const { getByText, findByLabelText, queryByText, findByText } = render(
682
+ <Comp />,
683
+ )
684
+
685
+ expect(queryByText('Name for person 0')).not.toBeInTheDocument()
686
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
687
+ await user.click(getByText('Add person'))
688
+ const input = await findByLabelText('Name for person 0')
689
+ expect(input).toBeInTheDocument()
690
+ await user.type(input, 'John')
691
+
692
+ await user.click(getByText('Add person'))
693
+ const input2 = await findByLabelText('Name for person 1')
694
+ expect(input).toBeInTheDocument()
695
+ await user.type(input2, 'Jack')
696
+
697
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
698
+ expect(queryByText('Name for person 1')).toBeInTheDocument()
699
+ await user.click(getByText('Remove person 1'))
700
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
701
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
702
+
703
+ await user.click(await findByText('Submit'))
704
+ expect(fn).toHaveBeenCalledWith({ people: ['John'] })
705
+ })
706
+
611
707
  it('should handle arrays with subvalues', async () => {
612
708
  const fn = vi.fn()
613
709
  function Comp() {
@@ -646,6 +742,12 @@ describe('useField', () => {
646
742
  }
647
743
  />
648
744
  </label>
745
+ <button
746
+ onClick={() => field.removeValue(i)}
747
+ type="button"
748
+ >
749
+ Remove person {i}
750
+ </button>
649
751
  </div>
650
752
  )
651
753
  }}
@@ -680,10 +782,23 @@ describe('useField', () => {
680
782
  )
681
783
 
682
784
  expect(queryByText('Name for person 0')).not.toBeInTheDocument()
785
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
683
786
  await user.click(getByText('Add person'))
684
787
  const input = await findByLabelText('Name for person 0')
685
788
  expect(input).toBeInTheDocument()
686
789
  await user.type(input, 'John')
790
+
791
+ await user.click(getByText('Add person'))
792
+ const input2 = await findByLabelText('Name for person 1')
793
+ expect(input).toBeInTheDocument()
794
+ await user.type(input2, 'Jack')
795
+
796
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
797
+ expect(queryByText('Name for person 1')).toBeInTheDocument()
798
+ await user.click(getByText('Remove person 1'))
799
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
800
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
801
+
687
802
  await user.click(await findByText('Submit'))
688
803
  expect(fn).toHaveBeenCalledWith({ people: [{ name: 'John', age: 0 }] })
689
804
  })