Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Use navigate function inside filter blocks #8524

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
5067e7a
Update Interactivity API
DAreRodz Jan 27, 2023
92d0d9d
Change `wp` prefixes to `woo`
DAreRodz Jan 27, 2023
0199ade
Use `woo` prefix for the directives runtime bundle
DAreRodz Jan 27, 2023
ceedc72
Merge branch 'trunk' into update/interactivity-api-prefixes
DAreRodz Feb 10, 2023
6277a3c
Update Interactivity API runtime
DAreRodz Feb 10, 2023
423c858
Hardcode php from interactivity API
DAreRodz Feb 14, 2023
9af6478
Temporarily add gutenberg plugin as dependency
DAreRodz Feb 14, 2023
36bd2c5
Merge branch 'trunk' into update/interactivity-api-store-ssr
DAreRodz Feb 20, 2023
78b7db2
Exclude Interactivity API files from phpcs checks
DAreRodz Feb 20, 2023
92f5a85
Update Interactivity API js files
DAreRodz Feb 20, 2023
0c11440
Update Interactivity API php files
DAreRodz Feb 21, 2023
97f39c1
Remove gutenberg from wp-env plugins
DAreRodz Feb 21, 2023
28dd2ad
Fix registered runtime paths
DAreRodz Feb 14, 2023
5453d6b
Fix prefixes when getting attributes in directives
DAreRodz Feb 14, 2023
1874a4c
Fix directive prefix in constants
DAreRodz Feb 21, 2023
e3df31b
Merge branch 'trunk' into update/interactivity-api-store-ssr
DAreRodz Feb 21, 2023
0cd9a23
Avoid a Fatal error when importing `wp-html`
DAreRodz Feb 21, 2023
68b0a66
Remove TODO comments from Interactivity API files
DAreRodz Feb 21, 2023
17fe079
Merge branch 'trunk' into update/interactivity-api-store-ssr
DAreRodz Feb 21, 2023
fa0ef8a
Merge branch 'trunk' into update/interactivity-api-store-ssr
DAreRodz Feb 22, 2023
92c93af
Merge branch 'trunk' into update/interactivity-api-store-ssr
DAreRodz Feb 23, 2023
0340765
Rename interactivity bundles
DAreRodz Feb 23, 2023
8334491
Output interactivity bundle as a global
DAreRodz Feb 23, 2023
1b4e78e
Export `navigate` from interactivity library
DAreRodz Feb 23, 2023
d1e714e
Use `navigate` inside filter's `changeUrl`
DAreRodz Feb 23, 2023
15cde85
Fixed typo in script dependency
DAreRodz Feb 23, 2023
283b593
Fix interactivity library name
DAreRodz Feb 23, 2023
bd4462c
Enable client-side navigation
DAreRodz Feb 23, 2023
80c8058
Merge branch 'trunk' into try/filters-with-client-side-navigation
DAreRodz Mar 13, 2023
1de0768
Add JS of `show`, `ignore` and `text` directives
DAreRodz Mar 13, 2023
60fda04
Remove tag directives
DAreRodz Mar 13, 2023
3879f80
Remove hydration to interactivity
DAreRodz Mar 13, 2023
ea15fc1
Merge branch 'trunk' into try/filters-with-client-side-navigation
DAreRodz Mar 13, 2023
d92c02d
Fix runtime script handles after merge
DAreRodz Mar 14, 2023
cee481b
Check if CSN is enabled before calling `navigate`
DAreRodz Mar 14, 2023
112567a
Merge branch 'trunk' into try/filters-with-client-side-navigation
DAreRodz Mar 14, 2023
92b9075
Fix path in require
DAreRodz Mar 14, 2023
7436e18
Fix runtime bundle names
DAreRodz Mar 14, 2023
521f3d6
Compute CSN support at startup
DAreRodz Mar 15, 2023
700f4d6
Add `ignore` directive to Filter blocks from PHP
DAreRodz Mar 15, 2023
341af0a
Check if CSN is enabled before updating filters
DAreRodz Mar 23, 2023
28cdb85
Refactor `changeUrl` to not import the Interactivity API
DAreRodz Mar 24, 2023
dea5d59
Improve comment
DAreRodz Mar 24, 2023
03325dc
Merge branch 'trunk' into try/filters-with-client-side-navigation
DAreRodz Mar 24, 2023
242c3c0
Add __experimental prefix to Interactivity module
DAreRodz Mar 27, 2023
63a2ced
Revert CSN changes in all filters except Active Filters
DAreRodz Mar 27, 2023
d34eb84
Track `popstate` events in Price Filter
DAreRodz Mar 27, 2023
daf3ea1
Remove effect to update Price Filter on popstate
DAreRodz Mar 27, 2023
8b0d600
Add `replace` option for `navigate`
DAreRodz Mar 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion assets/js/blocks/active-filters/active-attribute-filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
isAttributeTermCollection,
isBoolean,
} from '@woocommerce/types';
import { supportsClientSideNavigation } from '@woocommerce/utils';

/**
* Internal dependencies
Expand Down Expand Up @@ -128,7 +129,10 @@ const ActiveAttributeFilters = ( {
} );
}

if ( ! filteringForPhpTemplate ) {
if (
supportsClientSideNavigation ||
! filteringForPhpTemplate
) {
removeAttributeFilterBySlug(
productAttributes,
setProductAttributes,
Expand Down
27 changes: 21 additions & 6 deletions assets/js/blocks/active-filters/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {
isStockStatusQueryCollection,
isStockStatusOptions,
} from '@woocommerce/types';
import { getUrlParameter } from '@woocommerce/utils';
import {
getUrlParameter,
supportsClientSideNavigation,
} from '@woocommerce/utils';
import FilterTitlePlaceholder from '@woocommerce/base-components/filter-placeholder';
import { useIsMounted } from '@woocommerce/base-hooks';

Expand Down Expand Up @@ -111,7 +114,10 @@ const ActiveFiltersBlock = ( {
removeArgsFromFilterUrl( {
filter_stock_status: slug,
} );
if ( ! filteringForPhpTemplate ) {
if (
supportsClientSideNavigation ||
! filteringForPhpTemplate
) {
const newStatuses =
productStockStatus.filter(
( status ) => {
Expand Down Expand Up @@ -149,7 +155,10 @@ const ActiveFiltersBlock = ( {
name: formatPriceRange( minPrice, maxPrice ),
removeCallback: () => {
removeArgsFromFilterUrl( 'max_price', 'min_price' );
if ( ! filteringForPhpTemplate ) {
if (
supportsClientSideNavigation ||
! filteringForPhpTemplate
) {
setMinPrice( undefined );
setMaxPrice( undefined );
}
Expand Down Expand Up @@ -215,7 +224,7 @@ const ActiveFiltersBlock = ( {
* This code should be moved to Rating Filter block once it's implemented.
*/
useEffect( () => {
if ( ! filteringForPhpTemplate ) {
if ( supportsClientSideNavigation || ! filteringForPhpTemplate ) {
return;
}

Expand Down Expand Up @@ -264,7 +273,10 @@ const ActiveFiltersBlock = ( {
removeArgsFromFilterUrl( {
rating_filter: slug,
} );
if ( ! filteringForPhpTemplate ) {
if (
supportsClientSideNavigation ||
! filteringForPhpTemplate
) {
const newRatings = productRatings.filter(
( rating ) => {
return rating !== slug;
Expand Down Expand Up @@ -387,7 +399,10 @@ const ActiveFiltersBlock = ( {
className="wc-block-active-filters__clear-all"
onClick={ () => {
cleanFilterUrl();
if ( ! filteringForPhpTemplate ) {
if (
supportsClientSideNavigation ||
! filteringForPhpTemplate
) {
setMinPrice( undefined );
setMaxPrice( undefined );
setProductAttributes( [] );
Expand Down
57 changes: 57 additions & 0 deletions assets/js/interactivity/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,61 @@ export default () => {
}
}
);

// wp-show
directive(
'show',
( {
directives: {
show: { default: show },
},
element,
evaluate,
context,
} ) => {
const contextValue = useContext( context );
if ( ! evaluate( show, { context: contextValue } ) )
element.props.children = (
<template>{ element.props.children }</template>
);
}
);

// wp-ignore
directive(
'ignore',
( {
element: {
type: Type,
props: { innerHTML, ...rest },
},
} ) => {
// Preserve the initial inner HTML.
const cached = useMemo( () => innerHTML, [] );
return (
<Type
dangerouslySetInnerHTML={ { __html: cached } }
{ ...rest }
/>
);
}
);

// wp-text
directive(
'text',
( {
directives: {
text: { default: text },
},
element,
evaluate,
context,
} ) => {
const contextValue = useContext( context );
element.props.children = evaluate( text, {
context: contextValue,
} );
}
);
};
1 change: 1 addition & 0 deletions assets/js/interactivity/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import registerDirectives from './directives';
import registerComponents from './components';
import { init } from './router';
export { store } from './store';
export { navigate } from './router';

/**
* Initialize the initial vDOM.
Expand Down
8 changes: 6 additions & 2 deletions assets/js/interactivity/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,18 @@ export const prefetch = ( url ) => {
};

// Navigate to a new page.
export const navigate = async ( href ) => {
export const navigate = async ( href, { replace = false } = {} ) => {
const url = cleanUrl( href );
prefetch( url );
const page = await pages.get( url );
if ( page ) {
document.head.replaceChildren( ...page.head );
render( page.body, rootFragment );
window.history.pushState( {}, '', href );
if ( replace ) {
window.history.replaceState( {}, '', href );
} else {
window.history.pushState( {}, '', href );
}
} else {
window.location.assign( href );
}
Expand Down
4 changes: 3 additions & 1 deletion assets/js/interactivity/vdom.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export function toVdom( node ) {

if ( ignore && ! island )
return h( node.localName, {
dangerouslySetInnerHTML: { __html: node.innerHTML },
...props,
innerHTML: node.innerHTML,
directives: { ignore: true },
} );
if ( island ) hydratedIslands.add( node );

Expand Down
19 changes: 18 additions & 1 deletion assets/js/utils/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ const filteringForPhpTemplate = getSettingWithCoercion(
isBoolean
);

export const supportsClientSideNavigation =
document
.querySelector( `meta[itemprop='woo-client-side-navigation']` )
?.getAttribute( 'content' ) === 'active';

/**
* Returns specified parameter from URL
*
Expand All @@ -33,7 +38,19 @@ export function getUrlParameter( name: string ) {
* @param {string} newUrl New URL to be set.
*/
export function changeUrl( newUrl: string ) {
if ( filteringForPhpTemplate ) {
/**
* In order not to enqueue the Interactivity runtime if it is disabled, we
* cannot import `@woocommerce/interactivity` here. That's why we call
* `navigate` from `window.wc.__experimentalInteractivity` directly.
*/
if (
supportsClientSideNavigation &&
window.wc?.__experimentalInteractivity
) {
window.wc.__experimentalInteractivity.navigate( newUrl, {
replace: true,
} );
} else if ( filteringForPhpTemplate ) {
window.location.href = newUrl;
} else {
window.history.replaceState( {}, '', newUrl );
Expand Down
14 changes: 10 additions & 4 deletions bin/webpack-configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,11 +785,17 @@ const getInteractivityAPIConfig = ( options = {} ) => {
const { alias, resolvePlugins = [] } = options;
return {
entry: {
runtime: './assets/js/interactivity',
'wc-interactivity': './assets/js/interactivity',
},
output: {
filename: 'woo-directives-[name].js',
filename: '[name].js',
path: path.resolve( __dirname, '../build/' ),
library: [ 'wc', '__experimentalInteractivity' ],
libraryTarget: 'this',
// This fixes an issue with multiple webpack projects using chunking
// overwriting each other's chunk loader function.
// See https://webpack.js.org/configuration/output/#outputjsonpfunction
jsonpFunction: 'webpackWcBlocksJsonp',
},
resolve: {
alias,
Expand All @@ -806,13 +812,13 @@ const getInteractivityAPIConfig = ( options = {} ) => {
],
optimization: {
runtimeChunk: {
name: 'vendors',
name: 'wc-interactivity-vendors',
},
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
name: 'wc-interactivity-vendors',
minSize: 0,
chunks: 'all',
},
Expand Down
2 changes: 2 additions & 0 deletions bin/webpack-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const wcDepMap = {
'@woocommerce/shared-hocs': [ 'wc', 'wcBlocksSharedHocs' ],
'@woocommerce/price-format': [ 'wc', 'priceFormat' ],
'@woocommerce/blocks-checkout': [ 'wc', 'blocksCheckout' ],
'@woocommerce/interactivity': [ 'wc', '__experimentalInteractivity' ],
};

const wcHandleMap = {
Expand All @@ -28,6 +29,7 @@ const wcHandleMap = {
'@woocommerce/shared-hocs': 'wc-blocks-shared-hocs',
'@woocommerce/price-format': 'wc-price-format',
'@woocommerce/blocks-checkout': 'wc-blocks-checkout',
'@woocommerce/interactivity': 'wc-interactivity',
};

const getAlias = ( options = {} ) => {
Expand Down
2 changes: 1 addition & 1 deletion src/Interactivity/directives/attributes/woo-context.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

function process_woo_context_attribute( $tags, $context ) {
function process_woo_context( $tags, $context ) {
if ( $tags->is_tag_closer() ) {
$context->rewind_context();
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Context data implementation.
*
* @package block-hydration-experiments
* @package block-interactivity-experiments
*/

/**
Expand Down
18 changes: 0 additions & 18 deletions src/Interactivity/directives/tags/woo-context.php

This file was deleted.

Loading