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

Interactivity API: implement the new store() API #11071

Merged
merged 53 commits into from Nov 21, 2023

Conversation

DAreRodz
Copy link
Collaborator

@DAreRodz DAreRodz commented Sep 29, 2023

What

This PR implements the new store() API as specified in the proposal: WordPress/gutenberg#53586

It also updates the current Interactivity API implementation to match the latest features and improvements developed in WordPress/gutenberg.

Will close #11065

Why

To test the new API with actual use cases so we can fine-tune and shape it.

Testing Instructions

Please, go to the following PRs that are built on top of this branch to test these changes:

WooCommerce Visibility

Required:

  • WooCommerce Core
  • Feature plugin
  • Experimental
  • N/A

@github-actions
Copy link
Contributor

We can change this to use deepsignal once this PR is merg...

We can change this to use deepsignal once this PR is merged. github.com/luisherranz/deepsignal/pull/38


// TODO: We can change this to use deepsignal once this PR is merged.
// https://github.com/luisherranz/deepsignal/pull/38
<slotsContext.Provider value={ signal( {} ) }>
{ children }
</slotsContext.Provider>
);
};
export const Slot = ( { name, children } ) => {
const slots = useContext( slotsContext );
return slots.value[ name ] || children;
};

🚀 This comment was generated by the automations bot based on a todo comment in d196254 in #11071. cc @DAreRodz

@github-actions
Copy link
Contributor

github-actions bot commented Sep 29, 2023

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-11071.zip

Script Dependencies Report

There is no changed script dependency between this branch and trunk.

This comment was automatically generated by the ./github/compare-assets action.

TypeScript Errors Report

  • Files with errors: 570
  • Total errors: 2360

⚠️ ⚠️ This PR introduces new TS errors on 4 files:

assets/js/blocks/collection-filters/inner-blocks/attribute-filter/frontend.ts

assets/js/blocks/collection-filters/inner-blocks/price-filter/frontend.ts

assets/js/blocks/collection-filters/inner-blocks/stock-filter/frontend.ts

packages/interactivity-components/dropdown/index.ts

comments-aggregator

@github-actions
Copy link
Contributor

github-actions bot commented Sep 29, 2023

Size Change: +1.62 kB (0%)

Total Size: 1.61 MB

Filename Size Change
build/product-button-interactivity-frontend.js 8.29 kB -190 B (-2%)
build/product-gallery-frontend.js 778 B -94 B (-11%) 👏
build/product-gallery-large-image-frontend.js 604 B -44 B (-7%)
build/wc-interactivity.js 12.7 kB +1.95 kB (+18%) ⚠️
ℹ️ View Unchanged
Filename Size
build/3810-frontend.js 18.3 kB
build/4124-frontend.js 23.9 kB
build/8280-frontend.js 8.47 kB
build/active-filters-frontend.js 6.71 kB
build/active-filters-rtl.css 1.68 kB
build/active-filters-wrapper-frontend.js 6.91 kB
build/active-filters-wrapper-rtl.css 1.53 kB
build/active-filters-wrapper.css 1.53 kB
build/active-filters.css 1.68 kB
build/active-filters.js 6.06 kB
build/add-to-cart-form-rtl.css 444 B
build/add-to-cart-form.css 444 B
build/all-products-frontend.js 9.67 kB
build/all-products-rtl.css 4.54 kB
build/all-products.css 4.54 kB
build/all-products.js 39.7 kB
build/all-reviews-rtl.css 1.75 kB
build/all-reviews.css 1.75 kB
build/all-reviews.js 7.8 kB
build/attribute-filter-frontend.js 19.9 kB
build/attribute-filter-rtl.css 4.03 kB
build/attribute-filter-wrapper-frontend.js 21.1 kB
build/attribute-filter-wrapper-rtl.css 3.89 kB
build/attribute-filter-wrapper.css 3.88 kB
build/attribute-filter.css 4.01 kB
build/attribute-filter.js 11.3 kB
build/blocks-checkout.js 33.9 kB
build/blocks-components.js 32.4 kB
build/breadcrumbs-rtl.css 234 B
build/breadcrumbs.css 234 B
build/breadcrumbs.js 2.13 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.4 kB
build/cart-blocks/cart-accepted-payment-methods-style.js 153 B
build/cart-blocks/cart-cross-sells-frontend.js 267 B
build/cart-blocks/cart-cross-sells-products-frontend.js 5.56 kB
build/cart-blocks/cart-cross-sells-products-style.js 153 B
build/cart-blocks/cart-cross-sells-style.js 269 B
build/cart-blocks/cart-express-payment-frontend.js 5.38 kB
build/cart-blocks/cart-express-payment-style.js 155 B
build/cart-blocks/cart-items-frontend.js 281 B
build/cart-blocks/cart-items-style.js 240 B
build/cart-blocks/cart-line-items-frontend.js 9.24 kB
build/cart-blocks/cart-line-items-style.js 153 B
build/cart-blocks/cart-order-summary-frontend.js 20.6 kB
build/cart-blocks/cart-order-summary-style.js 339 B
build/cart-blocks/cart-totals-frontend.js 296 B
build/cart-blocks/cart-totals-style.js 253 B
build/cart-blocks/empty-cart-frontend.js 376 B
build/cart-blocks/empty-cart-style.js 375 B
build/cart-blocks/filled-cart-frontend.js 614 B
build/cart-blocks/filled-cart-style.js 332 B
build/cart-blocks/order-summary-coupon-form-frontend.js 21 kB
build/cart-blocks/order-summary-coupon-form-style.js 155 B
build/cart-blocks/order-summary-discount-frontend.js 21 kB
build/cart-blocks/order-summary-discount-style.js 155 B
build/cart-blocks/order-summary-fee-frontend.js 288 B
build/cart-blocks/order-summary-fee-style.js 153 B
build/cart-blocks/order-summary-heading-frontend.js 347 B
build/cart-blocks/order-summary-heading-style.js 351 B
build/cart-blocks/order-summary-shipping-frontend.js 20.6 kB
build/cart-blocks/order-summary-shipping-style.js 154 B
build/cart-blocks/order-summary-subtotal-frontend.js 291 B
build/cart-blocks/order-summary-subtotal-style.js 154 B
build/cart-blocks/order-summary-taxes-frontend.js 454 B
build/cart-blocks/order-summary-taxes-style.js 202 B
build/cart-blocks/proceed-to-checkout-frontend.js 7.64 kB
build/cart-blocks/proceed-to-checkout-style.js 1.09 kB
build/cart-frontend.js 29 kB
build/cart-rtl.css 9.27 kB
build/cart.css 9.25 kB
build/cart.js 39.7 kB
build/catalog-sorting-rtl.css 259 B
build/catalog-sorting.css 259 B
build/catalog-sorting.js 1.7 kB
build/checkout-blocks/actions-frontend.js 8.14 kB
build/checkout-blocks/actions-style.js 1.02 kB
build/checkout-blocks/billing-address-frontend.js 9.86 kB
build/checkout-blocks/billing-address-style.js 574 B
build/checkout-blocks/contact-information-frontend.js 1.67 kB
build/checkout-blocks/contact-information-style.js 653 B
build/checkout-blocks/express-payment-frontend.js 5.81 kB
build/checkout-blocks/fields-frontend.js 375 B
build/checkout-blocks/fields-style.js 342 B
build/checkout-blocks/order-note-frontend.js 681 B
build/checkout-blocks/order-summary-cart-items-frontend.js 6.49 kB
build/checkout-blocks/order-summary-cart-items-style.js 153 B
build/checkout-blocks/order-summary-coupon-form-frontend.js 21 kB
build/checkout-blocks/order-summary-coupon-form-style.js 155 B
build/checkout-blocks/order-summary-discount-frontend.js 21.1 kB
build/checkout-blocks/order-summary-discount-style.js 154 B
build/checkout-blocks/order-summary-fee-frontend.js 291 B
build/checkout-blocks/order-summary-fee-style.js 155 B
build/checkout-blocks/order-summary-frontend.js 20.6 kB
build/checkout-blocks/order-summary-shipping-frontend.js 20.6 kB
build/checkout-blocks/order-summary-shipping-style.js 154 B
build/checkout-blocks/order-summary-style.js 341 B
build/checkout-blocks/order-summary-subtotal-frontend.js 289 B
build/checkout-blocks/order-summary-subtotal-style.js 155 B
build/checkout-blocks/order-summary-taxes-frontend.js 455 B
build/checkout-blocks/order-summary-taxes-style.js 201 B
build/checkout-blocks/payment-frontend.js 14.5 kB
build/checkout-blocks/payment-style.js 500 B
build/checkout-blocks/pickup-options-frontend.js 11.2 kB
build/checkout-blocks/pickup-options-style.js 481 B
build/checkout-blocks/shipping-address-frontend.js 9.79 kB
build/checkout-blocks/shipping-address-style.js 517 B
build/checkout-blocks/shipping-method-frontend.js 1.97 kB
build/checkout-blocks/shipping-method-style.js 1.44 kB
build/checkout-blocks/shipping-methods-frontend.js 19 kB
build/checkout-blocks/shipping-methods-style.js 456 B
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout-blocks/terms-style.js 1.03 kB
build/checkout-blocks/totals-frontend.js 338 B
build/checkout-blocks/totals-style.js 301 B
build/checkout-frontend.js 30.7 kB
build/checkout-rtl.css 8.39 kB
build/checkout.css 8.37 kB
build/checkout.js 42.5 kB
build/classic-shortcode-rtl.css 242 B
build/classic-shortcode.css 241 B
build/classic-shortcode.js 4.66 kB
build/collection-attribute-filter-frontend.js 496 B
build/collection-attribute-filter-rtl.css 2.68 kB
build/collection-attribute-filter.css 2.67 kB
build/collection-attribute-filter.js 7.14 kB
build/collection-filters.js 3.02 kB
build/collection-price-filter-frontend.js 600 B
build/collection-price-filter-rtl.css 1.07 kB
build/collection-price-filter.css 1.07 kB
build/collection-price-filter.js 2.15 kB
build/collection-stock-filter-frontend.js 396 B
build/collection-stock-filter-rtl.css 4.03 kB
build/collection-stock-filter.css 4.03 kB
build/collection-stock-filter.js 4.18 kB
build/customer-account-rtl.css 410 B
build/customer-account.css 409 B
build/customer-account.js 3.19 kB
build/featured-category-rtl.css 974 B
build/featured-category.css 973 B
build/featured-category.js 13.6 kB
build/featured-product-rtl.css 1.02 kB
build/featured-product.css 1.02 kB
build/featured-product.js 13.9 kB
build/filter-wrapper-frontend.js 14.6 kB
build/filter-wrapper-rtl.css 378 B
build/filter-wrapper.css 378 B
build/filter-wrapper.js 2.38 kB
build/handpicked-products.js 7.34 kB
build/legacy-template-rtl.css 240 B
build/legacy-template.css 240 B
build/legacy-template.js 7.85 kB
build/mini-cart-component-frontend.js 30.8 kB
build/mini-cart-contents-block/cart-button-frontend.js 1.86 kB
build/mini-cart-contents-block/cart-button-style.js 1.23 kB
build/mini-cart-contents-block/checkout-button-frontend.js 1.95 kB
build/mini-cart-contents-block/checkout-button-style.js 1.44 kB
build/mini-cart-contents-block/empty-cart-frontend.js 383 B
build/mini-cart-contents-block/empty-cart-style.js 387 B
build/mini-cart-contents-block/filled-cart-frontend.js 284 B
build/mini-cart-contents-block/filled-cart-style.js 287 B
build/mini-cart-contents-block/footer-frontend.js 3.87 kB
build/mini-cart-contents-block/footer-style.js 1.96 kB
build/mini-cart-contents-block/items-frontend.js 246 B
build/mini-cart-contents-block/items-style.js 250 B
build/mini-cart-contents-block/products-table-frontend.js 8.59 kB
build/mini-cart-contents-block/shopping-button-frontend.js 501 B
build/mini-cart-contents-block/shopping-button-style.js 361 B
build/mini-cart-contents-block/title-frontend.js 2.04 kB
build/mini-cart-contents-block/title-items-counter-frontend.js 1.74 kB
build/mini-cart-contents-block/title-items-counter-style.js 1.2 kB
build/mini-cart-contents-block/title-label-frontend.js 1.68 kB
build/mini-cart-contents-block/title-label-style.js 1.14 kB
build/mini-cart-contents-block/title-style.js 1.38 kB
build/mini-cart-contents-rtl.css 3.23 kB
build/mini-cart-contents.css 3.22 kB
build/mini-cart-contents.js 16 kB
build/mini-cart-frontend.js 2.35 kB
build/mini-cart-rtl.css 2.44 kB
build/mini-cart.css 2.44 kB
build/mini-cart.js 6.09 kB
build/order-confirmation-additional-information-rtl.css 367 B
build/order-confirmation-additional-information.css 367 B
build/order-confirmation-additional-information.js 1.58 kB
build/order-confirmation-billing-address-rtl.css 398 B
build/order-confirmation-billing-address.css 397 B
build/order-confirmation-billing-address.js 1.56 kB
build/order-confirmation-billing-wrapper.js 1.51 kB
build/order-confirmation-downloads-rtl.css 477 B
build/order-confirmation-downloads-wrapper.js 1.58 kB
build/order-confirmation-downloads.css 478 B
build/order-confirmation-downloads.js 1.91 kB
build/order-confirmation-shipping-address-rtl.css 399 B
build/order-confirmation-shipping-address.css 398 B
build/order-confirmation-shipping-address.js 1.56 kB
build/order-confirmation-shipping-wrapper.js 1.52 kB
build/order-confirmation-status-rtl.css 280 B
build/order-confirmation-status.css 280 B
build/order-confirmation-status.js 1.55 kB
build/order-confirmation-summary-rtl.css 460 B
build/order-confirmation-summary.css 460 B
build/order-confirmation-summary.js 1.76 kB
build/order-confirmation-totals-rtl.css 594 B
build/order-confirmation-totals-wrapper.js 1.8 kB
build/order-confirmation-totals.css 593 B
build/order-confirmation-totals.js 2.18 kB
build/packages-style-rtl.css 5.19 kB
build/packages-style.css 5.19 kB
build/page-content-wrapper.js 1.96 kB
build/price-filter-frontend.js 7.94 kB
build/price-filter-rtl.css 2.68 kB
build/price-filter-wrapper-frontend.js 8.11 kB
build/price-filter-wrapper-rtl.css 2.53 kB
build/price-filter-wrapper.css 2.53 kB
build/price-filter.css 2.67 kB
build/price-filter.js 7.53 kB
build/price-format.js 913 B
build/product-add-to-cart-frontend.js 8.12 kB
build/product-add-to-cart-rtl.css 1.37 kB
build/product-add-to-cart.css 1.38 kB
build/product-add-to-cart.js 8.36 kB
build/product-average-rating-frontend.js 1.88 kB
build/product-average-rating.js 1.4 kB
build/product-best-sellers.js 7.08 kB
build/product-button-frontend.js 4.94 kB
build/product-button-rtl.css 1.14 kB
build/product-button.css 1.14 kB
build/product-button.js 4.66 kB
build/product-categories-rtl.css 654 B
build/product-categories.css 654 B
build/product-categories.js 2.6 kB
build/product-category.js 8.01 kB
build/product-collection-no-results.js 1.66 kB
build/product-collection.js 13.9 kB
build/product-details-rtl.css 397 B
build/product-details.css 394 B
build/product-gallery-large-image-next-previous.js 4.27 kB
build/product-gallery-large-image.js 2.47 kB
build/product-gallery-pager.js 3.48 kB
build/product-gallery-rtl.css 1.26 kB
build/product-gallery-thumbnails.js 3.94 kB
build/product-gallery.css 1.26 kB
build/product-gallery.js 9.6 kB
build/product-image-frontend.js 2.89 kB
build/product-image-gallery-rtl.css 307 B
build/product-image-gallery.css 306 B
build/product-image-rtl.css 996 B
build/product-image.css 994 B
build/product-image.js 2.57 kB
build/product-new.js 7.95 kB
build/product-on-sale.js 7.33 kB
build/product-price-frontend.js 2.82 kB
build/product-price-rtl.css 644 B
build/product-price.css 643 B
build/product-price.js 2.34 kB
build/product-query-rtl.css 350 B
build/product-query.css 349 B
build/product-query.js 11.7 kB
build/product-rating-counter-frontend.js 2.19 kB
build/product-rating-counter.js 1.7 kB
build/product-rating-frontend.js 2.53 kB
build/product-rating-rtl.css 247 B
build/product-rating-stars-frontend.js 2.43 kB
build/product-rating-stars-rtl.css 899 B
build/product-rating-stars.css 900 B
build/product-rating-stars.js 1.95 kB
build/product-rating.css 246 B
build/product-rating.js 2.04 kB
build/product-results-count-rtl.css 230 B
build/product-results-count.css 230 B
build/product-results-count.js 1.66 kB
build/product-reviews-rtl.css 458 B
build/product-reviews.css 458 B
build/product-sale-badge-frontend.js 2.01 kB
build/product-sale-badge-rtl.css 437 B
build/product-sale-badge.css 437 B
build/product-sale-badge.js 1.52 kB
build/product-search-rtl.css 419 B
build/product-search.css 417 B
build/product-search.js 2.62 kB
build/product-sku-frontend.js 2.02 kB
build/product-sku-rtl.css 240 B
build/product-sku.css 239 B
build/product-sku.js 1.53 kB
build/product-stock-indicator-frontend.js 2.2 kB
build/product-stock-indicator-rtl.css 232 B
build/product-stock-indicator.css 232 B
build/product-stock-indicator.js 1.71 kB
build/product-summary-frontend.js 2.36 kB
build/product-summary-rtl.css 549 B
build/product-summary.css 549 B
build/product-summary.js 1.88 kB
build/product-tag.js 7.53 kB
build/product-template-rtl.css 536 B
build/product-template.css 535 B
build/product-template.js 2.81 kB
build/product-title-frontend.js 2.31 kB
build/product-title-rtl.css 693 B
build/product-title.css 694 B
build/product-title.js 2.05 kB
build/product-top-rated.js 7.61 kB
build/products-by-attribute.js 8.05 kB
build/rating-filter-frontend.js 18.8 kB
build/rating-filter-rtl.css 4.09 kB
build/rating-filter-wrapper-frontend.js 19.7 kB
build/rating-filter-wrapper-rtl.css 3.95 kB
build/rating-filter-wrapper.css 3.95 kB
build/rating-filter.css 4.08 kB
build/rating-filter.js 5.8 kB
build/reviews-by-category-rtl.css 1.75 kB
build/reviews-by-category.css 1.75 kB
build/reviews-by-category.js 11.4 kB
build/reviews-by-product-rtl.css 1.75 kB
build/reviews-by-product.css 1.75 kB
build/reviews-by-product.js 12.7 kB
build/reviews-frontend.js 6.44 kB
build/single-product-rtl.css 378 B
build/single-product.css 378 B
build/single-product.js 11.1 kB
build/stock-filter-frontend.js 19 kB
build/stock-filter-rtl.css 3.88 kB
build/stock-filter-wrapper-frontend.js 20 kB
build/stock-filter-wrapper-rtl.css 3.75 kB
build/stock-filter-wrapper.css 3.74 kB
build/stock-filter.css 3.87 kB
build/stock-filter.js 6.44 kB
build/store-notices.js 1.68 kB
build/wc-blocks-classic-template-revert-button-style-rtl.css 240 B
build/wc-blocks-classic-template-revert-button-style.css 239 B
build/wc-blocks-classic-template-revert-button.js 1.19 kB
build/wc-blocks-data.js 19.7 kB
build/wc-blocks-editor-style-rtl.css 7.06 kB
build/wc-blocks-editor-style.css 7.06 kB
build/wc-blocks-google-analytics.js 1.13 kB
build/wc-blocks-jetpack-woocommerce-analytics.js 750 B
build/wc-blocks-middleware.js 735 B
build/wc-blocks-registry.js 2.75 kB
build/wc-blocks-rtl.css 2.48 kB
build/wc-blocks-shared-context.js 860 B
build/wc-blocks-shared-hocs.js 1.41 kB
build/wc-blocks-vendors.js 61.8 kB
build/wc-blocks.css 2.48 kB
build/wc-blocks.js 9.15 kB
build/wc-interactivity-dropdown.js 453 B
build/wc-payment-method-bacs.js 405 B
build/wc-payment-method-cheque.js 402 B
build/wc-payment-method-cod.js 508 B
build/wc-payment-method-paypal.js 439 B
build/wc-settings.js 2.42 kB
build/wc-shipping-method-pickup-location.js 29.4 kB

compressed-size-action

@luisherranz
Copy link
Collaborator

I've extracted the getters so different instances of them run "in the scope of each component". It's a bit like hooks, but automatic 😄

I've also refactored the scope a little bit. Now it makes more sense. You also need to pull interactivity-api-refactor-product-button-with-new-store-api.

I'll keep thinking if scope needs to be a stack, because now it needs to be set up inside the computeds, because they can run "outside" of the compontent scope when any of their dependencies is invalidated. At this point, I don't think it needs to be a stack because our directives don't stack, but if we don't make it a stack, there's no way to reset it properly either. So it'd be more a stack that consists of the same scope over and over to know when is the last and be able to properly reset it 😄

Copy link
Collaborator

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a small review of your last commit and left some notes, but this is quite exciting 🙂👏

Amazing work!!

assets/js/interactivity/store.ts Outdated Show resolved Hide resolved

const actionHandlers = {
get: ( target, key, receiver ) => {
const result = Reflect.get( target, key, receiver );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const result = Reflect.get( target, key, receiver );

Note: This could also be a getter if for some reason this runs outside of a scope. I can't think of any case where a getter might run outside of a scope and still need access to the default namespace, but maybe we find it in the future.

So there's nothing to do, this is just a note in case we find that case in the future.

if ( getter ) {
const scope = getScope();
if ( scope ) {
scope.getters = scope.getters || new Map();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should move this to an external Map as well: scope -> getters, to avoid adding non-user-facing stuff to the scope.

Copy link
Collaborator Author

@DAreRodz DAreRodz Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the scope is not publicly accessible. Developers use getElement and getContext, which return only a subset of the current scope. But we can move getters outside and use a WeakMap to link them to the scope related. I think it makes sense, anyway, so I'll make this change. 👍

} )
);
}
return scope.getters.get( getter ).value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: We are going to need a way to access the computed when we optimize wp-text and wp-bind to pass signals down. It doesn't have to be a nice API, so maybe something as simple as getComputed(obj, "prop");

assets/js/interactivity/hooks.tsx Outdated Show resolved Hide resolved
assets/js/interactivity/store.ts Outdated Show resolved Hide resolved
assets/js/interactivity/store.ts Outdated Show resolved Hide resolved
assets/js/interactivity/store.ts Outdated Show resolved Hide resolved
}

// Check if the property is an object.
if ( isObject( result ) ) return proxify( result, ns );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This is reusing the isObject from deepMerge which excludes arrays, although arrays could potentially contain functions/generators. For now, I don't think we need to support that as I can't think of any case where someone would like to have actions inside an array.

So there's nothing to do, this is just a note in case we find that case in the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's the reason I opted to use isObject. If we find we need to support actions inside arrays, we can change it in the future. 🙂

@DAreRodz
Copy link
Collaborator Author

Another thing I've found is that we are using forward slashes in namespaces, e.g.

'namespace' => 'woocommerce/product-button',

But we didn't allow that character in namespaces for directives defining it explicitly, so the following didn't work:

<div data-wp-watch="woocommerce/product-button::callbacks.start animation"></div>

Fixed in 5d91a56.

@DAreRodz DAreRodz added the type: enhancement The issue is a request for an enhancement. label Nov 15, 2023
@DAreRodz DAreRodz marked this pull request as ready for review November 15, 2023 13:22
Copy link
Contributor

@Aljullu Aljullu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reviewed the code and tested this PR via #11558 and couldn't spot anything off. However, as I mentioned in #11558 (review), I still feel I'm missing a lot of context around how things work with the Interactivity API, so I don't think I'm entitled to approve or reject this PR. I will let the others take a look.

Nevertheless, I left a couple of comments in the code. They are both minor suggestions/questions, so feel free to disregard them.

useEffect( () => {
// Prefetch the page if it is in the directive options.
if ( link?.prefetch ) {
prefetch( href );
// prefetch( href );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this commented out? Is it intended to leave it like this?

Copy link
Collaborator Author

@DAreRodz DAreRodz Nov 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, funny. 😄 That's actually the code we have in Gutenberg right now:

https://github.com/WordPress/gutenberg/blob/05432dd7c26f4c282b8750141a86a4b154704972/packages/interactivity/src/directives.js#L292-L294

I'd leave it as it is for now, although that should change eventually.

Comment on lines +14 to +15
const isObject = ( item: unknown ): boolean =>
!! item && typeof item === 'object' && ! Array.isArray( item );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if you can have @woocommerce dependencies in this file. But in case you can, we have an isObject function in @woocommerce/types which might be useful.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not to depend on other files not part of the Interactivity API runtime. 🤔

luisherranz and others added 2 commits November 16, 2023 23:45
…`store()` API (#11558)

* Refactor Product Button with new store() API

* Use `wc_initial_state` in Product Button

* Fix namespace

* Remove unnecessary state

* Test namespaces in directive paths

* Add test context with namespace

* Simplify woo-test context

* Move addToCart and animations to a file

* Do not pass `rawStore` to `afterLoad` callbacks

* Move callbacks and actions back to the main file

Because the animation was broken.

* Remove selectors in favor of state

* Use default ns in `getContext` for state and actions

* Remove `afterLoad` callback

* Remove unnecessary ns

* Fix getContext in add-to-cart

* Replace namespace and delete unnecessary store

* Pass context types only once

* Use an alternative for requestIdleCallback

* Add previous react code for notices

* Add namespace to Product Collection block

* Replace getTextButton with getButtonText

* Add block name to the ProductCollection namespace

* fix style HTML code

* Remove circular deps error on the Interactivity API

* Product Gallery block: Migrate to new Interactivity API store (#11721)

* Migrate Product Gallery block to new Interactivity API store

* Fix some references

* Add missing data-wc-interactive

* Fix an additional namespace

* Remove unnecessary click handler

* Dialog working

* Refactor action names

* Reindex PHP array

There was some missing indexes, which turned the array into an object in JS.

* Remove unused event handlers

* Move next/previous logic to external function

* Move StorePart util to the types folder

* Rename namespace to `woocommerce/product-gallery`

* Undo product collection namespace renaming

* Remove unnecessary namespace

* Don't hide the large image on page load

* Minor refactorings

* Fix eslint error

* Fix php cs errors with spacing and double arrows alignment

* Disable no-use-before-define rule for eslint

* Disable @typescript-eslint/ban-types rule for eslint

* Fix parsed context error in e2e tests

* Fix context parser for Thumbnail image

* Move store to the top of the frontend file

* Add interactivity api utils to the @woocommerce/utils alias

* Replace deprecated event attribute

---------

Co-authored-by: Luis Herranz <luisherranz@gmail.com>
Co-authored-by: David Arenas <david.arenas@automattic.com>
Co-authored-by: roykho <roykho77@gmail.com>

---------

Co-authored-by: David Arenas <david.arenas@automattic.com>
Co-authored-by: Luigi Teschio <gigitux@gmail.com>
Co-authored-by: Alexandre Lara <allexandrelara@gmail.com>
Co-authored-by: roykho <roykho77@gmail.com>
Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in 6413756 in #11071. cc @DAreRodz

Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in b67b264 in #11071. cc @DAreRodz

Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in f665a38 in #11071. cc @DAreRodz

Copy link
Collaborator

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gigitux can you apply the changes that you did in #11858 also here please?

Are the e2e tests already fixed in trunk? Who's taking care of that? I'd like to merge this PR to continue the migration.


As there are conflicts with #11858, I'm going to anticipately approve this PR, but the fix in that PR needs to be applied here as well before merging.

cc: @DAreRodz @sunyatasattva

Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in 09821c9 in #11071. cc @DAreRodz

@gigitux
Copy link
Contributor

gigitux commented Nov 21, 2023

@gigitux can you apply the changes that you did in #11858 also here please?

Done!

Currently the E2E tests pass on trunk. So, if something doesn't pass, maybe it could be worth investigating it!

Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in fa5932c in #11071. cc @DAreRodz

@luisherranz luisherranz force-pushed the interactivity-api-new-store-api branch from fa5932c to 09821c9 Compare November 21, 2023 10:20
Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in 09821c9 in #11071. cc @DAreRodz

@luisherranz
Copy link
Collaborator

luisherranz commented Nov 21, 2023

@gigitux merging trunk with this branch didn't apply the fix of #11858, it deleted wc_initial_state: 09821c9

Screenshot 2023-11-21 at 11 24 09

Copy link
Contributor

Replace with an interactive block that calls `actions.sel...

Replace with an interactive block that calls `actions.selectImage`.


// TODO: Replace with an interactive block that calls `actions.selectImage`.
const observer = new MutationObserver( function ( mutations ) {
for ( const mutation of mutations ) {
const mutationTarget = mutation.target as HTMLElement;
const currentImageAttribute =
mutationTarget.getAttribute( 'current-image' );
if (
mutation.type === 'attributes' &&
currentImageAttribute &&
context.visibleImagesIds.includes(
currentImageAttribute
)

🚀 This comment was generated by the automations bot based on a todo comment in 8f675cd in #11071. cc @DAreRodz

@DAreRodz DAreRodz merged commit 68c1d92 into trunk Nov 21, 2023
32 checks passed
@DAreRodz DAreRodz deleted the interactivity-api-new-store-api branch November 21, 2023 10:46
@Aljullu Aljullu added this to the 11.7.0 milestone Dec 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Interactivity API: implement the new store() API
5 participants