Skip to content

Commit

Permalink
feat: allow update or reset with index
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Apr 1, 2024
1 parent 5aff42c commit c105cd1
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
8 changes: 5 additions & 3 deletions packages/conform-dom/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
isPrefix,
setValue,
normalize,
formatName,
} from './formdata';
import {
type FieldElement,
Expand Down Expand Up @@ -289,7 +290,7 @@ function getDefaultKey(
>((result, [key, value]) => {
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
result[formatPaths([...getPaths(key), i])] = generateId();
result[formatName(key, i)] = generateId();
}
}

Expand Down Expand Up @@ -327,7 +328,8 @@ function handleIntent<Error>(
break;
}
case 'update': {
const { name, validated, value } = intent.payload;
const { validated, value } = intent.payload;
const name = formatName(intent.payload.name, intent.payload.index);

if (typeof value !== 'undefined') {
updateValue(meta, name ?? '', serialize(value));
Expand Down Expand Up @@ -362,7 +364,7 @@ function handleIntent<Error>(
break;
}
case 'reset': {
const name = intent.payload.name ?? '';
const name = formatName(intent.payload.name, intent.payload.index);
const value = getValue(meta.defaultValue, name);

updateValue(meta, name, value);
Expand Down
11 changes: 10 additions & 1 deletion packages/conform-dom/formdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function getFormData(
* const paths = getPaths('todos[0].content'); // ['todos', 0, 'content']
* ```
*/
export function getPaths(name: string): Array<string | number> {
export function getPaths(name: string | undefined): Array<string | number> {
if (!name) {
return [];
}
Expand Down Expand Up @@ -72,6 +72,15 @@ export function formatPaths(paths: Array<string | number>): string {
}, '');
}

/**
* Format based on a prefix and a path
*/
export function formatName(prefix: string | undefined, path?: string | number) {
return typeof path !== 'undefined'
? formatPaths([...getPaths(prefix), path])
: prefix ?? '';
}

/**
* Check if a name match the prefix paths
*/
Expand Down
37 changes: 27 additions & 10 deletions packages/conform-dom/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
setValue,
isPrefix,
getValue,
formatName,
} from './formdata';
import { invariant } from './util';

Expand Down Expand Up @@ -164,7 +165,7 @@ export function parse<FormValue, FormError>(
if (intent) {
switch (intent.type) {
case 'update': {
const { name } = intent.payload;
const name = formatName(intent.payload.name, intent.payload.index);
const value = serialize(intent.payload.value);

if (typeof value !== 'undefined') {
Expand All @@ -178,7 +179,7 @@ export function parse<FormValue, FormError>(
break;
}
case 'reset': {
const { name } = intent.payload;
const name = formatName(intent.payload.name, intent.payload.index);

if (name) {
setValue(context.payload, name, () => undefined);
Expand Down Expand Up @@ -308,18 +309,34 @@ export type ValidateIntent<Schema = any> = {

export type ResetIntent<Schema = any> = {
type: 'reset';
payload: {
name?: FieldName<Schema>;
};
payload:
| {
name?: FieldName<Schema>;
index?: never;
}
| {
name: FieldName<Schema>;
index: Schema extends Array<unknown> ? number : never;
};
};

export type UpdateIntent<Schema = unknown> = {
type: 'update';
payload: {
name?: FieldName<Schema>;
value?: NonNullable<DefaultValue<Schema>>;
validated?: boolean;
};
payload:
| {
name?: FieldName<Schema>;
index?: never;
value?: NonNullable<DefaultValue<Schema>>;
validated?: boolean;
}
| {
name: FieldName<Schema>;
index: Schema extends Array<unknown> ? number : never;
value?: NonNullable<
DefaultValue<Schema extends Array<infer Item> ? Item : unknown>
>;
validated?: boolean;
};
};

export type RemoveIntent<Schema extends Array<any> = any> = {
Expand Down
6 changes: 4 additions & 2 deletions playground/app/routes/simple-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ export default function SimpleList() {
<button
className="rounded-md border p-2 hover:border-black"
{...form.update.getButtonProps({
name: task.name,
name: fields.items.name,
index,
value: '',
validated: false,
})}
Expand All @@ -99,7 +100,8 @@ export default function SimpleList() {
<button
className="rounded-md border p-2 hover:border-black"
{...form.reset.getButtonProps({
name: task.name,
name: fields.items.name,
index,
})}
>
Reset
Expand Down
1 change: 1 addition & 0 deletions tests/conform-dom.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ describe('conform-dom', () => {
});

test('getPaths()', () => {
expect(getPaths(undefined)).toEqual([]);
expect(getPaths('')).toEqual([]);
expect(getPaths('title')).toEqual(['title']);
expect(getPaths('123')).toEqual(['123']);
Expand Down

0 comments on commit c105cd1

Please sign in to comment.