@tanstack/form-core 1.11.2 → 1.12.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/src/FormApi.ts CHANGED
@@ -2125,6 +2125,32 @@ export class FormApi<
2125
2125
  this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')
2126
2126
  }
2127
2127
 
2128
+ /**
2129
+ * Clear all values within an array field.
2130
+ */
2131
+ clearFieldValues = <TField extends DeepKeysOfType<TFormData, any[]>>(
2132
+ field: TField,
2133
+ opts?: UpdateMetaOptions,
2134
+ ) => {
2135
+ const fieldValue = this.getFieldValue(field)
2136
+
2137
+ const lastIndex = Array.isArray(fieldValue)
2138
+ ? Math.max((fieldValue as unknown[]).length - 1, 0)
2139
+ : null
2140
+
2141
+ this.setFieldValue(field, [] as any, opts)
2142
+
2143
+ if (lastIndex !== null) {
2144
+ for (let i = 0; i <= lastIndex; i++) {
2145
+ const fieldKey = `${field}[${i}]`
2146
+ this.deleteField(fieldKey as never)
2147
+ }
2148
+ }
2149
+
2150
+ // validate array change
2151
+ this.validateField(field, 'change')
2152
+ }
2153
+
2128
2154
  /**
2129
2155
  * Resets the field value and meta to default state
2130
2156
  */
package/src/utils.ts CHANGED
@@ -135,11 +135,13 @@ export function deleteBy(obj: any, _path: any) {
135
135
  return doDelete(obj)
136
136
  }
137
137
 
138
- const reFindNumbers0 = /^(\d*)$/gm
139
- const reFindNumbers1 = /\.(\d*)\./gm
140
- const reFindNumbers2 = /^(\d*)\./gm
141
- const reFindNumbers3 = /\.(\d*$)/gm
142
- const reFindMultiplePeriods = /\.{2,}/gm
138
+ const reLineOfOnlyDigits = /^(\d+)$/gm
139
+ // the second dot must be in a lookahead or the engine
140
+ // will skip subsequent numbers (like foo.0.1.)
141
+ const reDigitsBetweenDots = /\.(\d+)(?=\.)/gm
142
+ const reStartWithDigitThenDot = /^(\d+)\./gm
143
+ const reDotWithDigitsToEnd = /\.(\d+$)/gm
144
+ const reMultipleDots = /\.{2,}/gm
143
145
 
144
146
  const intPrefix = '__int__'
145
147
  const intReplace = `${intPrefix}$1`
@@ -156,21 +158,25 @@ export function makePathArray(str: string | Array<string | number>) {
156
158
  throw new Error('Path must be a string.')
157
159
  }
158
160
 
159
- return str
160
- .replace(/\[/g, '.')
161
- .replace(/\]/g, '')
162
- .replace(reFindNumbers0, intReplace)
163
- .replace(reFindNumbers1, `.${intReplace}.`)
164
- .replace(reFindNumbers2, `${intReplace}.`)
165
- .replace(reFindNumbers3, `.${intReplace}`)
166
- .replace(reFindMultiplePeriods, '.')
167
- .split('.')
168
- .map((d) => {
169
- if (d.indexOf(intPrefix) === 0) {
170
- return parseInt(d.substring(intPrefix.length), 10)
171
- }
172
- return d
173
- })
161
+ return (
162
+ str
163
+ // Leading `[` may lead to wrong parsing down the line
164
+ // (Example: '[0][1]' should be '0.1', not '.0.1')
165
+ .replace(/(^\[)|]/gm, '')
166
+ .replace(/\[/g, '.')
167
+ .replace(reLineOfOnlyDigits, intReplace)
168
+ .replace(reDigitsBetweenDots, `.${intReplace}.`)
169
+ .replace(reStartWithDigitThenDot, `${intReplace}.`)
170
+ .replace(reDotWithDigitsToEnd, `.${intReplace}`)
171
+ .replace(reMultipleDots, '.')
172
+ .split('.')
173
+ .map((d) => {
174
+ if (d.indexOf(intPrefix) === 0) {
175
+ return parseInt(d.substring(intPrefix.length), 10)
176
+ }
177
+ return d
178
+ })
179
+ )
174
180
  }
175
181
 
176
182
  /**