Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
[feat] useIsDirtyState (#12)
Browse files Browse the repository at this point in the history
* Add Test

* Add Implementation
  • Loading branch information
AsPulse authored Mar 12, 2023
1 parent f2081e5 commit c00a19a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
22 changes: 20 additions & 2 deletions src/component/sugarform/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
import { useRef } from 'react';
import type { Dispatch, SetStateAction } from 'react';
import { useRef, useState } from 'react';
import { SugarFormError } from '../../util/error';
import type { Sugar, SugarValue } from '../sugar';
import { createEmptySugar } from '../sugar/create';

export const useSugarForm = <T,>({ defaultValue }:{ defaultValue: T }): {
sugar: Sugar<T>,
render: () => SugarValue<T>
render: () => SugarValue<T>,
useIsDirtyState: () => boolean,
} => {
const sugar = useRef<Sugar<T>>();
sugar.current ??= createEmptySugar('', defaultValue);

const isDirtyStateRef = useRef<undefined | Dispatch<SetStateAction<boolean>>>(undefined);

if (!sugar.current.mounted) {
sugar.current.upstream.listen('updateDirty', ({ isDirty }) => {
isDirtyStateRef.current?.(isDirty);
});
}

return {
sugar: sugar.current,
render: (): SugarValue<T> => {
const sugarValue = sugar.current;
if (sugarValue === undefined || !sugarValue.mounted) throw new SugarFormError('SF0021', 'Path: <TopLevel>');
return sugarValue.get();
},
useIsDirtyState: (): boolean => {
const [ isDirtyState, setIsDirtyState ] = useState<boolean>(false);
if (isDirtyStateRef.current === undefined) {
isDirtyStateRef.current = setIsDirtyState;
}
return isDirtyState;
},
};
};
30 changes: 28 additions & 2 deletions tests/useSugarForm.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { describe, it } from '@jest/globals';
import { renderHook } from '@testing-library/react';
import { act, renderHook } from '@testing-library/react';
import type { Sugar, SugarValue } from '../src/component/sugar';
import { useSugarForm } from '../src/component/sugarform';

describe('useSugarForm', () => {

it('should work', () => {
const { result: { current: { sugar, render } } } =
renderHook(() => useSugarForm<{ a: 'foo' }>({ defaultValue: { a: 'foo' } }));
renderHook(() => useSugarForm<{ a: string }>({ defaultValue: { a: 'foo' } }));

const { result: { current: { fields: { a } } } } =
renderHook(() => sugar.useObject({}));
Expand All @@ -25,4 +25,30 @@ describe('useSugarForm', () => {
});
});

it('should work with isDirtyState', () => {

const { result: { current: { sugar, useIsDirtyState } } } =
renderHook(() => useSugarForm<{ a: string }>({ defaultValue: { a: 'foo' } }));

const { result: { current: { fields: { a } } } } =
renderHook(() => sugar.useObject({}));

const { result: { current: { onBlur } } } = renderHook(() => a.useFromRef({
get: () => ({ success: true, value: 'foo' }),
set: () => null,
}));

const { result: isDirtyResult } = renderHook(() => useIsDirtyState());

expect(isDirtyResult.current).toBe(false);

act(() => {
if (a.mounted) a.get = (): SugarValue<string> => ({ success: true, value: 'bar' });
onBlur();
});

expect(isDirtyResult.current).toBe(true);

});

});

0 comments on commit c00a19a

Please sign in to comment.