Skip to content

Commit

Permalink
Interactivity API: merge new server-side rendered context on client-s…
Browse files Browse the repository at this point in the history
…ide navigation (#53853)

* Add failing test

* Fix the test

* Add changelog

* Fix lint error
  • Loading branch information
luisherranz authored Aug 22, 2023
1 parent 79ecdbb commit a325563
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,15 @@
</button>
</div>
</div>

<div
data-wp-interactive
data-wp-navigation-id="navigation"
data-wp-context='{ "text": "first page" }'
>
<div data-testid="navigation text" data-wp-text="context.text"></div>
<div data-testid="navigation new text" data-wp-text="context.newText"></div>
<button data-testid="toggle text" data-wp-on--click="actions.toggleText">Toggle Text</button>
<button data-testid="add new text" data-wp-on--click="actions.addNewText">Add new text</button>
<button data-testid="navigate" data-wp-on--click="actions.navigate">Navigate</button>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
( ( { wp } ) => {
const { store } = wp.interactivity;
const { store, navigate } = wp.interactivity;

const html = `
<div
data-wp-interactive
data-wp-navigation-id="navigation"
data-wp-context='{ "text": "second page" }'
>
<div data-testid="navigation text" data-wp-text="context.text"></div>
<div data-testid="navigation new text" data-wp-text="context.newText"></div>
<button data-testid="toggle text" data-wp-on--click="actions.toggleText">Toggle Text</button>
<button data-testid="add new text" data-wp-on--click="actions.addNewText">Add new text</button>
<button data-testid="navigate" data-wp-on--click="actions.navigate">Navigate</button>
</div>`;

store( {
derived: {
Expand All @@ -17,6 +30,18 @@
toggleContextText: ( { context } ) => {
context.text = context.text === 'Text 1' ? 'Text 2' : 'Text 1';
},
toggleText: ( { context } ) => {
context.text = "changed dynamically";
},
addNewText: ( { context } ) => {
context.newText = 'some new text';
},
navigate: () => {
navigate( window.location, {
force: true,
html,
} );
}
},
} );
} )( window );
4 changes: 4 additions & 0 deletions packages/interactivity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancements

- Merge new server-side rendered context on client-side navigation. ([#53853](https://github.com/WordPress/gutenberg/pull/53853))

## 2.1.0 (2023-08-16)

### New Features
Expand Down
26 changes: 15 additions & 11 deletions packages/interactivity/src/directives.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { useContext, useMemo, useEffect } from 'preact/hooks';
import { useContext, useMemo, useEffect, useRef } from 'preact/hooks';
import { deepSignal, peek } from 'deepsignal';

/**
Expand Down Expand Up @@ -36,20 +36,24 @@ export default () => {
'context',
( {
directives: {
context: { default: context },
context: { default: newContext },
},
props: { children },
context: inherited,
context: inheritedContext,
} ) => {
const { Provider } = inherited;
const inheritedValue = useContext( inherited );
const value = useMemo( () => {
const localValue = deepSignal( context );
mergeDeepSignals( localValue, inheritedValue );
return localValue;
}, [ context, inheritedValue ] );
const { Provider } = inheritedContext;
const inheritedValue = useContext( inheritedContext );
const currentValue = useRef( deepSignal( {} ) );
currentValue.current = useMemo( () => {
const newValue = deepSignal( newContext );
mergeDeepSignals( newValue, currentValue.current );
mergeDeepSignals( newValue, inheritedValue );
return newValue;
}, [ newContext, inheritedValue ] );

return <Provider value={ value }>{ children }</Provider>;
return (
<Provider value={ currentValue.current }>{ children }</Provider>
);
},
{ priority: 5 }
);
Expand Down
18 changes: 18 additions & 0 deletions test/e2e/specs/interactivity/directives-context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,22 @@ test.describe( 'data-wp-context', () => {
await expect( element ).toHaveText( 'Text 1' );
await expect( element ).toHaveAttribute( 'value', 'Text 1' );
} );

test( 'should replace values on navigation', async ( { page } ) => {
const element = page.getByTestId( 'navigation text' );
await expect( element ).toHaveText( 'first page' );
await page.getByTestId( 'toggle text' ).click();
await expect( element ).toHaveText( 'changed dynamically' );
await page.getByTestId( 'navigate' ).click();
await expect( element ).toHaveText( 'second page' );
} );

test( 'should preserve the previous context values', async ( { page } ) => {
const element = page.getByTestId( 'navigation new text' );
await expect( element ).toHaveText( '' );
await page.getByTestId( 'add new text' ).click();
await expect( element ).toHaveText( 'some new text' );
await page.getByTestId( 'navigate' ).click();
await expect( element ).toHaveText( 'some new text' );
} );
} );

0 comments on commit a325563

Please sign in to comment.