Skip to content

Commit

Permalink
refine implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Feb 25, 2024
1 parent 9f16078 commit 5bda67e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 38 deletions.
81 changes: 43 additions & 38 deletions packages/conform-dom/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ export type FormContext<
onInput(event: Event): void;
onBlur(event: Event): void;
onUpdate(options: Partial<FormOptions<Schema, FormError, FormValue>>): void;
observe(): () => void;
subscribe(
callback: () => void,
getSubject?: () => SubscriptionSubject | undefined,
Expand Down Expand Up @@ -542,44 +543,6 @@ export function createFormContext<
let meta = createFormMeta(options);
let state = createFormState(meta);

if (typeof MutationObserver !== 'undefined') {
console.log('MutationObserver is supported');
let observer = new MutationObserver((mutations) => {
const form = getFormElement();

if (!form) {
return;
}

for (const mutation of mutations) {
const nodes =
mutation.type === 'childList'
? [...mutation.addedNodes, ...mutation.removedNodes]
: [mutation.target];

for (const node of nodes) {
const element = isFieldElement(node)
? node
: node instanceof HTMLElement
? node.querySelector<FieldElement>('input,select,textarea')
: null;

if (element?.form === form) {
updateFormValue(form);
return;
}
}
}
});

observer.observe(document, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ['form', 'name'],
});
}

function getFormElement(): HTMLFormElement | null {
return document.forms.namedItem(latestOptions.formId);
}
Expand Down Expand Up @@ -990,6 +953,47 @@ export function createFormContext<
});
}

function observe() {
const observer = new MutationObserver((mutations) => {
const form = getFormElement();

if (!form) {
return;
}

for (const mutation of mutations) {
const nodes =
mutation.type === 'childList'
? [...mutation.addedNodes, ...mutation.removedNodes]
: [mutation.target];

for (const node of nodes) {
const element = isFieldElement(node)
? node
: node instanceof HTMLElement
? node.querySelector<FieldElement>('input,select,textarea')
: null;

if (element?.form === form) {
updateFormValue(form);
return;
}
}
}
});

observer.observe(document, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ['form', 'name'],
});

return () => {
observer.disconnect();
};
}

return {
get formId() {
return latestOptions.formId;
Expand All @@ -1008,5 +1012,6 @@ export function createFormContext<
subscribe,
getState,
getSerializedState,
observe,
};
}
2 changes: 2 additions & 0 deletions packages/conform-react/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,13 @@ export function useForm<
);

useSafeLayoutEffect(() => {
const disconnect = context.observe();
document.addEventListener('input', context.onInput);
document.addEventListener('focusout', context.onBlur);
document.addEventListener('reset', context.onReset);

return () => {
disconnect();
document.removeEventListener('input', context.onInput);
document.removeEventListener('focusout', context.onBlur);
document.removeEventListener('reset', context.onReset);
Expand Down

0 comments on commit 5bda67e

Please # to comment.