diff --git a/README.md b/README.md index ccc0a952..f69556ef 100644 --- a/README.md +++ b/README.md @@ -185,14 +185,14 @@ function MyComponent() { export const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; }; ``` @@ -391,14 +391,14 @@ API is same as for Next.js version, except can pass options from [NavigateOption export const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; }; diff --git a/packages/example-nextjs14/src/app/(tests)/useSharedState/page.tsx b/packages/example-nextjs14/src/app/(tests)/useSharedState/page.tsx index 1ba292f8..783a666e 100644 --- a/packages/example-nextjs14/src/app/(tests)/useSharedState/page.tsx +++ b/packages/example-nextjs14/src/app/(tests)/useSharedState/page.tsx @@ -53,6 +53,7 @@ const FirstComponent = () => { onChange={(ev) => setState((curr) => ({ ...curr, agree: ev.target.checked })) } + data-testid="agree_to_terms" > diff --git a/packages/example-nextjs14/src/app/Form-for-test.tsx b/packages/example-nextjs14/src/app/Form-for-test.tsx index 7baf6a35..d7fdf466 100644 --- a/packages/example-nextjs14/src/app/Form-for-test.tsx +++ b/packages/example-nextjs14/src/app/Form-for-test.tsx @@ -72,7 +72,7 @@ export const Form = ({ const onChangeTerms = React.useCallback( (ev: React.ChangeEvent) => { - setUrl({ 'agree to terms': ev.target.checked }); + setUrl({ agree_to_terms: ev.target.checked }); }, [setUrl], ); @@ -107,15 +107,18 @@ export const Form = ({ type="number" value={urlState.age} onChange={onChangeAge} + name="name" /> - + diff --git a/packages/example-nextjs14/src/app/Form.tsx b/packages/example-nextjs14/src/app/Form.tsx index c6d3e9bf..9cb1d780 100644 --- a/packages/example-nextjs14/src/app/Form.tsx +++ b/packages/example-nextjs14/src/app/Form.tsx @@ -15,7 +15,7 @@ export const Form = ({ searchParams?: object; ghLink: string }) => { - const { state, updateUrl } = useUrlState({ + const { urlState, setUrl } = useUrlState({ defaultState: form, searchParams, }); @@ -23,35 +23,35 @@ export const Form = ({ const onChangeAge = React.useCallback( (ev: React.ChangeEvent) => { const val = +ev.target.value; - updateUrl({ age: val ? val : undefined }); + setUrl({ age: val ? val : undefined }); }, - [updateUrl], + [setUrl], ); const onChangeName = React.useCallback( (ev: React.ChangeEvent) => { - updateUrl({ name: ev.target.value }); + setUrl({ name: ev.target.value }); }, - [updateUrl], + [setUrl], ); const onChangeTerms = React.useCallback( (ev: React.ChangeEvent) => { - updateUrl({ 'agree to terms': ev.target.checked }); + setUrl({ agree_to_terms: ev.target.checked }); }, - [updateUrl], + [setUrl], ); const onChangeTags = React.useCallback( (tag: (typeof tags)[number]) => { - updateUrl((curr) => ({ + setUrl((curr) => ({ ...curr, tags: curr.tags.find((t) => t.id === tag.id) ? curr.tags.filter((t) => t.id !== tag.id) : curr.tags.concat(tag), })); }, - [updateUrl], + [setUrl], ); return ( @@ -65,8 +65,9 @@ export const Form = ({ @@ -74,22 +75,24 @@ export const Form = ({ @@ -97,7 +100,7 @@ export const Form = ({
{tags.map((tag) => ( t.id === tag.id)} + active={!!urlState.tags.find((t) => t.id === tag.id)} text={tag.value.text} onClick={() => onChangeTags(tag)} key={tag.id} diff --git a/packages/example-nextjs14/src/app/components/CodeBlocksNext.tsx b/packages/example-nextjs14/src/app/components/CodeBlocksNext.tsx index 4d3ffa80..11dbef9f 100644 --- a/packages/example-nextjs14/src/app/components/CodeBlocksNext.tsx +++ b/packages/example-nextjs14/src/app/components/CodeBlocksNext.tsx @@ -12,14 +12,14 @@ export const CodeBlocks = () => { content={`export const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; };`} /> diff --git a/packages/example-nextjs14/src/app/components/CodeBlocksRR.tsx b/packages/example-nextjs14/src/app/components/CodeBlocksRR.tsx index 773bcd25..4db3b24e 100644 --- a/packages/example-nextjs14/src/app/components/CodeBlocksRR.tsx +++ b/packages/example-nextjs14/src/app/components/CodeBlocksRR.tsx @@ -12,14 +12,14 @@ export const CodeBlocksRR = () => { content={`export const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; };`} /> diff --git a/packages/example-nextjs15/src/app/(tests)/useSharedState/page.tsx b/packages/example-nextjs15/src/app/(tests)/useSharedState/page.tsx index 1ba292f8..783a666e 100644 --- a/packages/example-nextjs15/src/app/(tests)/useSharedState/page.tsx +++ b/packages/example-nextjs15/src/app/(tests)/useSharedState/page.tsx @@ -53,6 +53,7 @@ const FirstComponent = () => { onChange={(ev) => setState((curr) => ({ ...curr, agree: ev.target.checked })) } + data-testid="agree_to_terms" >
diff --git a/packages/example-nextjs15/src/app/Form-for-test.tsx b/packages/example-nextjs15/src/app/Form-for-test.tsx index a6314d2d..f332eca9 100644 --- a/packages/example-nextjs15/src/app/Form-for-test.tsx +++ b/packages/example-nextjs15/src/app/Form-for-test.tsx @@ -71,7 +71,7 @@ export const Form = ({ const onChangeTerms = React.useCallback( (ev: React.ChangeEvent) => { - setUrl({ 'agree to terms': ev.target.checked }); + setUrl({ agree_to_terms: ev.target.checked }); }, [setUrl], ); @@ -110,12 +110,13 @@ export const Form = ({ /> - + diff --git a/packages/example-react-router6/src/FewComponents/Component.tsx b/packages/example-react-router6/src/FewComponents/Component.tsx index afa235ae..e2dbe090 100644 --- a/packages/example-react-router6/src/FewComponents/Component.tsx +++ b/packages/example-react-router6/src/FewComponents/Component.tsx @@ -5,7 +5,7 @@ import { useUrlState } from "state-in-url/react-router"; import { stateShape } from "./stateShape"; export const Component = () => { - const { state, updateUrl } = useUrlState({ + const { urlState, setUrl } = useUrlState({ defaultState: stateShape, replace: false, }); @@ -14,9 +14,9 @@ export const Component = () => {

Per page select

diff --git a/packages/example-react/src/App.tsx b/packages/example-react/src/App.tsx index 5e209433..0a014880 100644 --- a/packages/example-react/src/App.tsx +++ b/packages/example-react/src/App.tsx @@ -36,7 +36,10 @@ const FirstComponent = () => { setState(curr => ({ ...curr, agree: ev.target.checked }))}> + onChange={ev => setState(curr => ({ ...curr, agree: ev.target.checked }))} + data-testid="agree_to_terms" + > +
} diff --git a/packages/shared/form.ts b/packages/shared/form.ts index 3d4fd6c6..bba24ffc 100644 --- a/packages/shared/form.ts +++ b/packages/shared/form.ts @@ -1,13 +1,13 @@ export const form: Form = { name: "", age: undefined, - "agree to terms": false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - "agree to terms": boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date; iso?: string } }[]; }; diff --git a/packages/urlstate/parseSPObj.test.ts b/packages/urlstate/parseSPObj.test.ts index 3ca35830..97797a8b 100644 --- a/packages/urlstate/parseSPObj.test.ts +++ b/packages/urlstate/parseSPObj.test.ts @@ -3,12 +3,12 @@ import { parseSPObj } from './parseSPObj'; describe('should decode server components searchParams', () => { it('without errors', () => { const sp = { - 'agree to terms': 'true', + agree_to_terms: 'true', tags: "[{'id':'3','value':{'text':'TailwindCSS','time':'2024-07-07T13:51:18.069Z'}}]", }; const expected = { ...form, - 'agree to terms': true, + agree_to_terms: true, tags: [ { id: '3', @@ -22,12 +22,12 @@ describe('should decode server components searchParams', () => { it('invalid string', () => { const sp = { - 'agree to terms': 'true', + agree_to_terms: 'true', tags: "[{'id':'3','value':{'text':'TailwindC", }; const expected = { ...form, - 'agree to terms': true, + agree_to_terms: true, tags: [], }; @@ -38,13 +38,13 @@ describe('should decode server components searchParams', () => { const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; }; diff --git a/packages/urlstate/useSharedState/useSharedState.test.ts b/packages/urlstate/useSharedState/useSharedState.test.ts index 7c1ecc6c..4e9c00b1 100644 --- a/packages/urlstate/useSharedState/useSharedState.test.ts +++ b/packages/urlstate/useSharedState/useSharedState.test.ts @@ -255,13 +255,13 @@ describe('useSharedState', () => { export const form: Form = { name: '', age: undefined, - 'agree to terms': false, + agree_to_terms: false, tags: [], }; type Form = { name: string; age?: number; - 'agree to terms': boolean; + agree_to_terms: boolean; tags: { id: string; value: { text: string; time: Date } }[]; }; diff --git a/tests/useSharedState/main.spec.ts b/tests/useSharedState/main.spec.ts index 7e908dac..1ae02995 100644 --- a/tests/useSharedState/main.spec.ts +++ b/tests/useSharedState/main.spec.ts @@ -31,12 +31,12 @@ test.describe('main tests', () => { await page.getByLabel('name').focus(); await page .getByLabel('name') - .pressSequentially(values.name, { delay: 150 }); + .pressSequentially(values.name, { delay: 5 }); await page.getByLabel('age').focus(); await page .getByLabel('age') - .pressSequentially(values.age, { delay: 150 }); - await page.getByRole('checkbox', { name: 'agree' }).click(); + .pressSequentially(values.age, { delay: 5 }); + await page.getByTestId('agree_to_terms').click({ force: true }); await expect(page.getByTestId('parsed')).toHaveText(expectedText); await expect(page.getByTestId('name-input')).toHaveValue(values.name); @@ -44,7 +44,7 @@ test.describe('main tests', () => { await page.getByTestId('name-input').focus(); await page .getByTestId('name-input') - .pressSequentially(' test ', { delay: 150 }); + .pressSequentially(' test ', { delay: 5 }); const name = `${values.name} test `; await expect(page.getByLabel('name')).toHaveValue(name); await expect(page.getByTestId('parsed')).toContainText( diff --git a/tests/useUrlState/history.spec.ts b/tests/useUrlState/history.spec.ts index 6e4d9270..662d07e6 100644 --- a/tests/useUrlState/history.spec.ts +++ b/tests/useUrlState/history.spec.ts @@ -31,7 +31,7 @@ const urls = [ const expectedText = `{ "name": "${name}", - "agree to terms": false, + "agree_to_terms": false, "tags": [] }`; @@ -52,7 +52,7 @@ const urls = [ await page.goForward(); await expect(page.getByTestId('parsed')).toHaveText(`{ "name": "${name}", - "agree to terms": false, + "agree_to_terms": false, "tags": [] }`); diff --git a/tests/useUrlState/main.spec.ts b/tests/useUrlState/main.spec.ts index 2c6da46b..7861405f 100644 --- a/tests/useUrlState/main.spec.ts +++ b/tests/useUrlState/main.spec.ts @@ -16,11 +16,11 @@ const delay = 1 test.describe('main tests', () => { const expectedUrl = - '?name=%27My+Name%27&age=33&agree+to+terms=true&tags=%5B%7B%27id%27%3A%271%27%2C%27value%27%3A%7B%27text%27%3A%27React.js%27%2C%27time%27%3A%272024-07-17T04%3A53%3A17.000Z%27%7D%7D%5D'; + '?name=%27My+Name%27&age=33&agree_to_terms=true&tags=%5B%7B%27id%27%3A%271%27%2C%27value%27%3A%7B%27text%27%3A%27React.js%27%2C%27time%27%3A%272024-07-17T04%3A53%3A17.000Z%27%7D%7D%5D'; const expectedText = `{ "name": "My Name", "age": 33, - "agree to terms": true, + "agree_to_terms": true, "tags": [ { "id": "1", @@ -90,7 +90,7 @@ test.describe('main tests', () => { await page .getByLabel('age') .pressSequentially(values.age, { delay }); - await page.getByRole('checkbox', { name: 'agree to terms' }).click(); + await page.getByTestId('agree_to_terms').click(); await page.waitForTimeout(400); await page.getByText('React.js').click(); diff --git a/tests/useUrlState/updateUrl.spec.ts b/tests/useUrlState/updateUrl.spec.ts index f9bdc69b..5ddd8350 100644 --- a/tests/useUrlState/updateUrl.spec.ts +++ b/tests/useUrlState/updateUrl.spec.ts @@ -26,7 +26,7 @@ const delay = 1 const expectedText = `{ "name": "My Name", - "agree to terms": false, + "agree_to_terms": false, "tags": [ { "id": "1", @@ -50,7 +50,7 @@ const delay = 1 await expect(page.getByTestId('parsed')).toHaveText(`{ "name": "", - "agree to terms": false, + "agree_to_terms": false, "tags": [] }`); }); @@ -72,7 +72,7 @@ test.describe('update', () => { const expectedText = `{ "name": "My Name", - "agree to terms": false, + "agree_to_terms": false, "tags": [ { "id": "1", @@ -97,7 +97,7 @@ test.describe('update', () => { await expect(page.getByTestId('parsed')).toHaveText(`{ "name": "My Name", "age": 55, - "agree to terms": false, + "agree_to_terms": false, "tags": [ { "id": "1", @@ -132,7 +132,7 @@ test.describe('update', () => { const expectedText = `{ "name": "My Name", - "agree to terms": false, + "agree_to_terms": false, "tags": [ { "id": "3", @@ -171,7 +171,7 @@ test.describe('update', () => { const expectedText = `{ "name": "My Name", - "agree to terms": false, + "agree_to_terms": false, "tags": [] }`;