diff --git a/.github/workflows/mirrors.yml b/.github/workflows/mirrors.yml deleted file mode 100644 index 7cd52722d2f..00000000000 --- a/.github/workflows/mirrors.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Mirrors -on: - push: - branches: ["trunk", "release/**"] - workflow_dispatch: - -permissions: {} - -jobs: - build: - if: github.repository == 'woocommerce/woocommerce' - name: Build WooCommerce zip - runs-on: ubuntu-20.04 - permissions: - contents: read - steps: - - uses: actions/checkout@v3 - - - name: Setup WooCommerce Monorepo - uses: ./.github/actions/setup-woocommerce-monorepo - with: - pull-package-deps: '@woocommerce/plugin-woocommerce' - - - name: Build zip - working-directory: plugins/woocommerce - run: bash bin/build-zip.sh - - - name: Upload the zip file as an artifact - uses: actions/upload-artifact@v3 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - name: woocommerce - path: plugins/woocommerce/woocommerce.zip - retention-days: 7 - - mirror: - if: github.repository == 'woocommerce/woocommerce' - name: Push to Mirror - needs: [build] - runs-on: ubuntu-20.04 - permissions: - contents: read - steps: - - name: Create directories - run: | - mkdir -p monorepo - - - name: Checkout monorepo - uses: actions/checkout@v3 - with: - path: monorepo - - - name: Download WooCommerce ZIP - uses: actions/download-artifact@v3 - with: - name: woocommerce - path: tmp/woocommerce-build - - - name: Extract and replace WooCommerce zip. - working-directory: tmp/woocommerce-build - run: | - mkdir -p woocommerce/woocommerce-production - unzip woocommerce.zip -d woocommerce/woocommerce-production - mv woocommerce/woocommerce-production/woocommerce/* woocommerce/woocommerce-production - rm -rf woocommerce/woocommerce-production/woocommerce - - - name: Copy Composer over to production - run: cp monorepo/plugins/woocommerce/composer.json tmp/woocommerce-build/woocommerce/woocommerce-production - - - name: Set up mirror - working-directory: tmp/woocommerce-build - run: | - touch mirrors.txt - echo "woocommerce/woocommerce-production" >> mirrors.txt - - - name: Push to mirror - uses: Automattic/action-push-to-mirrors@v1 - with: - source-directory: ${{ github.workspace }}/monorepo - token: ${{ secrets.API_TOKEN_GITHUB }} - username: matticbot - working-directory: ${{ github.workspace }}/tmp/woocommerce-build - timeout-minutes: 5 # 2021-01-18: Successful runs seem to take about half a minute. diff --git a/packages/js/customer-effort-score/changelog/52556-fix-52515-ces-feedback-require-dbl-click b/packages/js/customer-effort-score/changelog/52556-fix-52515-ces-feedback-require-dbl-click new file mode 100644 index 00000000000..3963497f38b --- /dev/null +++ b/packages/js/customer-effort-score/changelog/52556-fix-52515-ces-feedback-require-dbl-click @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +A fix a bug where users need to click Give feedback twice. \ No newline at end of file diff --git a/packages/js/customer-effort-score/src/components/customer-effort-score-tracks/index.js b/packages/js/customer-effort-score/src/components/customer-effort-score-tracks/index.js index 103e341e7ed..8676f5f7826 100644 --- a/packages/js/customer-effort-score/src/components/customer-effort-score-tracks/index.js +++ b/packages/js/customer-effort-score/src/components/customer-effort-score-tracks/index.js @@ -8,6 +8,7 @@ import { createElement, useState } from '@wordpress/element'; import { OPTIONS_STORE_NAME } from '@woocommerce/data'; import { __ } from '@wordpress/i18n'; import { recordEvent } from '@woocommerce/tracks'; +import apiFetch from '@wordpress/api-fetch'; /** * Internal dependencies @@ -38,7 +39,6 @@ import { getStoreAgeInWeeks } from '../../utils'; * @param {boolean} props.allowTracking Whether tracking is allowed or not. * @param {boolean} props.resolving Are values still being resolved. * @param {number} props.storeAgeInWeeks The age of the store in weeks. - * @param {Function} props.updateOptions Function to update options. * @param {Function} props.createNotice Function to create a snackbar. */ function _CustomerEffortScoreTracks( { @@ -55,7 +55,6 @@ function _CustomerEffortScoreTracks( { allowTracking, resolving, storeAgeInWeeks, - updateOptions, createNotice, } ) { const [ modalShown, setModalShown ] = useState( false ); @@ -91,12 +90,17 @@ function _CustomerEffortScoreTracks( { ces_location: 'inside', ...trackProps, } ); + if ( ! cesShownForActions || ! cesShownForActions.includes( action ) ) { - updateOptions( { - [ SHOWN_FOR_ACTIONS_OPTION_NAME ]: [ - action, - ...( cesShownForActions || [] ), - ], + apiFetch( { + path: 'wc-admin/options', + method: 'POST', + data: { + [ SHOWN_FOR_ACTIONS_OPTION_NAME ]: [ + action, + ...( cesShownForActions || [] ), + ], + }, } ); } }; @@ -247,11 +251,9 @@ export const CustomerEffortScoreTracks = compose( }; } ), withDispatch( ( dispatch ) => { - const { updateOptions } = dispatch( OPTIONS_STORE_NAME ); const { createNotice } = dispatch( 'core/notices' ); return { - updateOptions, createNotice, }; } ) diff --git a/packages/js/product-editor/changelog/52501-add-settings-sidebar b/packages/js/product-editor/changelog/52501-add-settings-sidebar new file mode 100644 index 00000000000..714550edd2d --- /dev/null +++ b/packages/js/product-editor/changelog/52501-add-settings-sidebar @@ -0,0 +1,4 @@ +Significance: patch +Type: tweak +Comment: Adds layout to Settings, which is unreleased. + diff --git a/packages/js/product-editor/src/index.ts b/packages/js/product-editor/src/index.ts index 6b4862e1408..decce32da21 100644 --- a/packages/js/product-editor/src/index.ts +++ b/packages/js/product-editor/src/index.ts @@ -40,6 +40,10 @@ export { PostTypeContext } from './contexts/post-type-context'; */ export * from './products'; +export { default as SiteHub } from './products-app/site-hub'; +export { default as SidebarContent } from './products-app/sidebar'; +export { unlock } from './lock-unlock'; + // Init the store registerProductEditorUiStore(); diff --git a/packages/js/product-editor/src/lock-unlock.ts b/packages/js/product-editor/src/lock-unlock.ts index 8c585c29833..a43f05fa4f3 100644 --- a/packages/js/product-editor/src/lock-unlock.ts +++ b/packages/js/product-editor/src/lock-unlock.ts @@ -3,8 +3,19 @@ */ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; -export const { lock, unlock } = - __dangerousOptInToUnstableAPIsOnlyForCoreModules( - 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', - '@wordpress/edit-site' - ); +/** + * Internal dependencies + */ +import { getGutenbergVersion } from './utils/get-gutenberg-version'; + +const isGutenbergEnabled = getGutenbergVersion() > 0; +const noop = () => {}; + +const { lock, unlock } = isGutenbergEnabled + ? __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', + '@wordpress/edit-site' + ) + : { lock: noop, unlock: noop }; + +export { lock, unlock }; diff --git a/packages/js/settings-editor/changelog/52501-add-settings-sidebar b/packages/js/settings-editor/changelog/52501-add-settings-sidebar new file mode 100644 index 00000000000..714550edd2d --- /dev/null +++ b/packages/js/settings-editor/changelog/52501-add-settings-sidebar @@ -0,0 +1,4 @@ +Significance: patch +Type: tweak +Comment: Adds layout to Settings, which is unreleased. + diff --git a/packages/js/settings-editor/changelog/add-gutenberg-warning-notice-settings b/packages/js/settings-editor/changelog/add-gutenberg-warning-notice-settings new file mode 100644 index 00000000000..59cc8c7b4c1 --- /dev/null +++ b/packages/js/settings-editor/changelog/add-gutenberg-warning-notice-settings @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Create a warning or notice to add Gutenberg diff --git a/packages/js/settings-editor/package.json b/packages/js/settings-editor/package.json index def85f64fd2..67cdc1c3777 100644 --- a/packages/js/settings-editor/package.json +++ b/packages/js/settings-editor/package.json @@ -39,6 +39,7 @@ "@types/wordpress__blocks": "11.0.7", "@woocommerce/settings": "^1.0.0", "@woocommerce/tracks": "workspace:^", + "@woocommerce/product-editor": "workspace:^", "@wordpress/api-fetch": "wp-6.0", "@wordpress/components": "wp-6.0", "@wordpress/compose": "wp-6.0", @@ -244,6 +245,10 @@ "node_modules/@woocommerce/eslint-plugin/configs", "node_modules/@woocommerce/eslint-plugin/rules", "node_modules/@woocommerce/eslint-plugin/index.js", + "node_modules/@woocommerce/product-editor/build", + "node_modules/@woocommerce/product-editor/build-module", + "node_modules/@woocommerce/product-editor/build-style", + "node_modules/@woocommerce/product-editor/build-types", "node_modules/@woocommerce/tracks/build", "node_modules/@woocommerce/tracks/build-module", "node_modules/@woocommerce/tracks/build-types", diff --git a/packages/js/settings-editor/src/index.tsx b/packages/js/settings-editor/src/index.tsx index 86aa6bb63e8..b12ac7dc2d7 100644 --- a/packages/js/settings-editor/src/index.tsx +++ b/packages/js/settings-editor/src/index.tsx @@ -2,7 +2,38 @@ * External dependencies */ import { createElement } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { isGutenbergVersionAtLeast } from './utils'; +import { Layout } from './layout'; + +const Sidebar =
Sidebar content goes here
; export const SettingsEditor = () => { - return
Settings Editor
; + const isRequiredGutenbergVersion = isGutenbergVersionAtLeast( 19.0 ); + + if ( ! isRequiredGutenbergVersion ) { + return ( + // Temporary during development. +
+ { __( + 'Please enable Gutenberg version 19.0 or higher for this feature', + 'woocommerce' + ) } +
+ ); + } + + return ( + + ); }; diff --git a/packages/js/settings-editor/src/layout.tsx b/packages/js/settings-editor/src/layout.tsx new file mode 100644 index 00000000000..1e83202cab5 --- /dev/null +++ b/packages/js/settings-editor/src/layout.tsx @@ -0,0 +1,127 @@ +/** + * External dependencies + */ +import { createElement, Fragment, useRef } from '@wordpress/element'; +import { unlock, SiteHub, SidebarContent } from '@woocommerce/product-editor'; +import { + useViewportMatch, + useResizeObserver, + useReducedMotion, +} from '@wordpress/compose'; +import { __ } from '@wordpress/i18n'; +import { + // @ts-expect-error missing type. + EditorSnackbars, + // @ts-expect-error missing type. + privateApis as editorPrivateApis, +} from '@wordpress/editor'; +// eslint-disable-next-line @woocommerce/dependency-group +import { + // @ts-expect-error missing type. + __unstableMotion as motion, + // @ts-expect-error missing type. + __unstableAnimatePresence as AnimatePresence, +} from '@wordpress/components'; + +type Route = { + key: string; + areas: { + sidebar: React.JSX.Element | React.FunctionComponent; + content?: React.JSX.Element | React.FunctionComponent; + edit?: React.JSX.Element | React.FunctionComponent; + mobile?: React.JSX.Element | React.FunctionComponent | boolean; + preview?: boolean; + }; + widths?: { + content?: number; + edit?: number; + sidebar?: number; + }; +}; + +const { NavigableRegion } = unlock( editorPrivateApis ); + +const ANIMATION_DURATION = 0.3; + +type LayoutProps = { + route: Route; +}; + +export function Layout( { route }: LayoutProps ) { + const [ fullResizer ] = useResizeObserver(); + const toggleRef = useRef< HTMLAnchorElement >( null ); + const isMobileViewport = useViewportMatch( 'medium', '<' ); + const disableMotion = useReducedMotion(); + + const { key: routeKey, areas, widths } = route; + + return ( + <> + { fullResizer } +
+
+ { /* + The NavigableRegion must always be rendered and not use + `inert` otherwise `useNavigateRegions` will fail. + */ } + { ( ! isMobileViewport || ! areas.mobile ) && ( + + + + + + { areas.sidebar } + + + + + ) } + + + + { ! isMobileViewport && areas.content && ( +
+ { areas.content } +
+ ) } + + { ! isMobileViewport && areas.edit && ( +
+ { areas.edit } +
+ ) } +
+
+ + ); +} diff --git a/packages/js/settings-editor/src/utils/index.ts b/packages/js/settings-editor/src/utils/index.ts new file mode 100644 index 00000000000..b16b71c2a5e --- /dev/null +++ b/packages/js/settings-editor/src/utils/index.ts @@ -0,0 +1,12 @@ +/** + * External dependencies + */ +import { getSetting } from '@woocommerce/settings'; + +export function isGutenbergVersionAtLeast( version: number ) { + const adminSettings: { gutenberg_version?: string } = getSetting( 'admin' ); + if ( adminSettings.gutenberg_version ) { + return parseFloat( adminSettings?.gutenberg_version ) >= version; + } + return false; +} diff --git a/packages/js/settings-editor/typings/index.d.ts b/packages/js/settings-editor/typings/index.d.ts new file mode 100644 index 00000000000..4d11d9a97aa --- /dev/null +++ b/packages/js/settings-editor/typings/index.d.ts @@ -0,0 +1,13 @@ +declare module '@woocommerce/settings' { + export declare function getAdminLink( path: string ): string; + export declare function getSetting< T >( + name: string, + fallback?: unknown, + filter = ( val: unknown, fb: unknown ) => + typeof val !== 'undefined' ? val : fb + ): T; + export declare function isWpVersion( + version: string, + operator: '>' | '>=' | '=' | '<' | '<=' + ): boolean; +} diff --git a/plugins/woocommerce-beta-tester/api/options/rest-api.php b/plugins/woocommerce-beta-tester/api/options/rest-api.php index cc5ee9f481a..7ec0439548a 100644 --- a/plugins/woocommerce-beta-tester/api/options/rest-api.php +++ b/plugins/woocommerce-beta-tester/api/options/rest-api.php @@ -44,6 +44,37 @@ register_woocommerce_admin_test_helper_rest_route( ) ); +register_woocommerce_admin_test_helper_rest_route( + '/options', + 'wca_test_helper_update_option', + array( + 'methods' => 'POST', + 'args' => array( + 'options' => array( + 'description' => 'Array of options to update.', + 'type' => 'array', + 'required' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'option_name' => array( + 'description' => 'The name of the option to update.', + 'type' => 'string', + 'required' => true, + 'sanitize_callback' => 'sanitize_text_field', + ), + 'option_value' => array( + 'description' => 'The new value for the option.', + 'required' => true, + ), + ), + ), + ), + ), + ) +); + + /** * A helper to delete options. * @@ -99,3 +130,26 @@ function wca_test_helper_get_options( $request ) { return new WP_REST_Response( $options, 200 ); } +/** + * Update WordPress options. Supports single or batch updates. + * + * @param WP_REST_Request $request The full request data. + * @return WP_REST_Response + */ +function wca_test_helper_update_option( $request ) { + $data = $request->get_json_params(); + $response = array(); + + foreach ( $data['options'] as $option ) { + if ( ! isset( $option['option_name'] ) || ! isset( $option['option_value'] ) ) { + continue; + } + update_option( $option['option_name'], $option['option_value'] ); + $response[] = array( + 'option_name' => $option['option_name'], + 'option_value' => $option['option_value'], + ); + } + + return new WP_REST_Response( $response, 200 ); +} diff --git a/plugins/woocommerce-beta-tester/changelog/update-reset-onboarding-wizard b/plugins/woocommerce-beta-tester/changelog/update-reset-onboarding-wizard new file mode 100644 index 00000000000..6a043310761 --- /dev/null +++ b/plugins/woocommerce-beta-tester/changelog/update-reset-onboarding-wizard @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +Update WC Admin Test Helper's Reset Onboarding Wizard tool diff --git a/plugins/woocommerce-beta-tester/src/tools/data/actions.js b/plugins/woocommerce-beta-tester/src/tools/data/actions.js index e988cc653f5..8a92c7da17e 100644 --- a/plugins/woocommerce-beta-tester/src/tools/data/actions.js +++ b/plugins/woocommerce-beta-tester/src/tools/data/actions.js @@ -101,14 +101,43 @@ export function* triggerWcaInstall() { export function* resetOnboardingWizard() { yield runCommand( 'Reset Onboarding Wizard', function* () { const optionsToDelete = [ - 'woocommerce_task_list_tracked_completed_tasks', 'woocommerce_onboarding_profile', - '_transient_wc_onboarding_themes', + 'woocommerce_task_list_tracked_completed_tasks', + 'woocommerce_private_link', + 'woocommerce_share_key', + 'woocommerce_store_pages_only', ]; + + const defaultOptions = { + woocommerce_allow_tracking: 'no', + woocommerce_default_country: 'US:CA', + woocommerce_currency: 'USD', + woocommerce_currency_pos: 'left', + woocommerce_price_thousand_sep: ',', + woocommerce_price_decimal_sep: '.', + woocommerce_price_num_decimals: '2', + woocommerce_coming_soon: 'no', + }; + + // Delete existing options yield apiFetch( { method: 'DELETE', path: `${ API_NAMESPACE }/options/${ optionsToDelete.join( ',' ) }`, } ); + + // Execute batch update of options + yield apiFetch( { + method: 'POST', + path: `${ API_NAMESPACE }/options`, + data: { + options: Object.entries( defaultOptions ).map( + ( [ option_name, option_value ] ) => ( { + option_name, + option_value, + } ) + ), + }, + } ); } ); } diff --git a/plugins/woocommerce-blocks/.eslintrc.js b/plugins/woocommerce-blocks/.eslintrc.js index 827ec476499..a65aae69504 100644 --- a/plugins/woocommerce-blocks/.eslintrc.js +++ b/plugins/woocommerce-blocks/.eslintrc.js @@ -121,6 +121,40 @@ const restrictedImports = [ }, ]; +const coreModules = [ + '@woocommerce/block-data', + '@woocommerce/blocks-checkout', + '@woocommerce/blocks-components', + '@woocommerce/price-format', + '@woocommerce/settings', + '@woocommerce/shared-context', + '@woocommerce/shared-hocs', + '@woocommerce/tracks', + '@woocommerce/data', + '@wordpress/a11y', + '@wordpress/api-fetch', + '@wordpress/block-editor', + '@wordpress/compose', + '@wordpress/data', + '@wordpress/core-data', + '@wordpress/editor', + '@wordpress/escape-html', + '@wordpress/hooks', + '@wordpress/keycodes', + '@wordpress/url', + '@woocommerce/blocks-test-utils', + '@woocommerce/e2e-utils', + 'babel-jest', + 'dotenv', + 'jest-environment-puppeteer', + 'lodash/kebabCase', + 'lodash', + 'prop-types', + 'react', + 'requireindex', + 'react-transition-group', +]; + module.exports = { env: { browser: true, @@ -151,39 +185,7 @@ module.exports = { // List of modules that are externals in our webpack config. // This helps the `import/no-extraneous-dependencies` and //`import/no-unresolved` rules account for them. - 'import/core-modules': [ - '@woocommerce/block-data', - '@woocommerce/blocks-checkout', - '@woocommerce/blocks-components', - '@woocommerce/price-format', - '@woocommerce/settings', - '@woocommerce/shared-context', - '@woocommerce/shared-hocs', - '@woocommerce/tracks', - '@woocommerce/data', - '@wordpress/a11y', - '@wordpress/api-fetch', - '@wordpress/block-editor', - '@wordpress/compose', - '@wordpress/data', - '@wordpress/core-data', - '@wordpress/editor', - '@wordpress/escape-html', - '@wordpress/hooks', - '@wordpress/keycodes', - '@wordpress/url', - '@woocommerce/blocks-test-utils', - '@woocommerce/e2e-utils', - 'babel-jest', - 'dotenv', - 'jest-environment-puppeteer', - 'lodash/kebabCase', - 'lodash', - 'prop-types', - 'react', - 'requireindex', - 'react-transition-group', - ], + 'import/core-modules': coreModules, 'import/resolver': { node: {}, webpack: {}, @@ -301,6 +303,7 @@ module.exports = { typescript: {}, // this loads /tsconfig.json to eslint }, 'import/core-modules': [ + ...coreModules, // We should lint these modules imports, but the types are way out of date. // To support us not inadvertently introducing new import errors this lint exists, but to avoid // having to fix hundreds of import errors for @wordpress packages we ignore them. diff --git a/plugins/woocommerce-blocks/.wp-env.json b/plugins/woocommerce-blocks/.wp-env.json index 12cfcee5453..f3ee36fcba3 100644 --- a/plugins/woocommerce-blocks/.wp-env.json +++ b/plugins/woocommerce-blocks/.wp-env.json @@ -5,6 +5,7 @@ "https://github.com/WP-API/Basic-Auth/archive/master.zip", "https://downloads.wordpress.org/plugin/wordpress-importer.0.8.zip", "./tests/mocks/woo-test-helper", + "../woocommerce/tests/e2e-pw/bin/test-helper-apis.php", "../woocommerce" ], "env": { diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/index.js b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/index.js index 468acb2b0c9..01d65485825 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/index.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/index.js @@ -8,11 +8,9 @@ export { default as ProductDetails } from './product-details'; export { default as ProductImage } from './product-image'; export { default as ProductLowStockBadge } from './product-low-stock-badge'; export { default as ProductSummary } from './product-summary'; -export { default as PickupLocation } from './pickup-location'; export { default as ProductMetadata } from './product-metadata'; export { default as ProductSaleBadge } from './product-sale-badge'; export { default as ReturnToCartButton } from './return-to-cart-button'; -export { default as ShippingLocation } from './shipping-location'; export { default as ShippingRatesControl } from './shipping-rates-control'; export { default as ShippingRatesControlPackage } from './shipping-rates-control-package'; export { default as PaymentMethodIcons } from './payment-method-icons'; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/index.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/index.tsx index 25bc4f8c7a0..0d9fa083c03 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/index.tsx @@ -13,10 +13,12 @@ import './style.scss'; interface OrderSummaryProps { cartItems: CartItem[]; + disableProductDescriptions: boolean; } const OrderSummary = ( { cartItems = [], + disableProductDescriptions = false, }: OrderSummaryProps ): null | JSX.Element => { const { isLarge, hasContainerWidth } = useContainerWidthContext(); @@ -34,6 +36,9 @@ const OrderSummary = ( { { cartItems.map( ( cartItem ) => { return ( diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/order-summary-item.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/order-summary-item.tsx index 3d2be02e888..e12e45dc432 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/order-summary-item.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/order-summary/order-summary-item.tsx @@ -30,9 +30,13 @@ import ProductMetadata from '../product-metadata'; interface OrderSummaryProps { cartItem: CartItem; + disableProductDescriptions: boolean; } -const OrderSummaryItem = ( { cartItem }: OrderSummaryProps ): JSX.Element => { +const OrderSummaryItem = ( { + cartItem, + disableProductDescriptions, +}: OrderSummaryProps ): JSX.Element => { const { images, low_stock_remaining: lowStockRemaining, @@ -122,6 +126,18 @@ const OrderSummaryItem = ( { cartItem }: OrderSummaryProps ): JSX.Element => { arg, } ); + const productMetaProps = disableProductDescriptions + ? { + itemData, + variation, + } + : { + itemData, + variation, + shortDescription, + fullDescription, + }; + return (
{ /> ) ) } - +
{ sprintf( diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx deleted file mode 100644 index 74b71aa5789..00000000000 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/** - * External dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; -import { isObject, objectHasProp } from '@woocommerce/types'; -import { isPackageRateCollectable } from '@woocommerce/base-utils'; - -/** - * Shows a formatted pickup location. - */ -const PickupLocation = (): JSX.Element | null => { - const { pickupAddress } = useSelect( ( select ) => { - const cartShippingRates = select( 'wc/store/cart' ).getShippingRates(); - - const flattenedRates = cartShippingRates.flatMap( - ( cartShippingRate ) => cartShippingRate.shipping_rates - ); - const selectedCollectableRate = flattenedRates.find( - ( rate ) => rate.selected && isPackageRateCollectable( rate ) - ); - - // If the rate has an address specified in its metadata. - if ( - isObject( selectedCollectableRate ) && - objectHasProp( selectedCollectableRate, 'meta_data' ) - ) { - const selectedRateMetaData = selectedCollectableRate.meta_data.find( - ( meta ) => meta.key === 'pickup_address' - ); - if ( - isObject( selectedRateMetaData ) && - objectHasProp( selectedRateMetaData, 'value' ) && - selectedRateMetaData.value - ) { - const selectedRatePickupAddress = selectedRateMetaData.value; - return { - pickupAddress: selectedRatePickupAddress, - }; - } - } - - if ( isObject( selectedCollectableRate ) ) { - return { - pickupAddress: undefined, - }; - } - return { - pickupAddress: undefined, - }; - } ); - - // If the method does not contain an address, or the method supporting collection was not found, return early. - if ( typeof pickupAddress === 'undefined' ) { - return null; - } - - // Show the pickup method's name if we don't have an address to show. - return ( - - { sprintf( - /* translators: %s: shipping method name, e.g. "Amazon Locker" */ - __( 'Collection from %s', 'woocommerce' ), - pickupAddress - ) + ' ' } - - ); -}; - -export default PickupLocation; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx deleted file mode 100644 index 31f81fa80ac..00000000000 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/** - * External dependencies - */ -import { render, screen } from '@testing-library/react'; -import { CART_STORE_KEY, CHECKOUT_STORE_KEY } from '@woocommerce/block-data'; -import { dispatch } from '@wordpress/data'; -import { previewCart } from '@woocommerce/resource-previews'; -import PickupLocation from '@woocommerce/base-components/cart-checkout/pickup-location'; - -jest.mock( '@woocommerce/settings', () => { - const originalModule = jest.requireActual( '@woocommerce/settings' ); - - return { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore We know @woocommerce/settings is an object. - ...originalModule, - getSetting: ( setting: string, ...rest: unknown[] ) => { - if ( setting === 'localPickupEnabled' ) { - return true; - } - if ( setting === 'collectableMethodIds' ) { - return [ 'pickup_location' ]; - } - return originalModule.getSetting( setting, ...rest ); - }, - }; -} ); -describe( 'PickupLocation', () => { - it( `renders an address if one is set in the methods metadata`, async () => { - dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); - - // Deselect the default selected rate and select pickup_location:1 rate. - const currentlySelectedIndex = - previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( - ( rate ) => rate.selected - ); - previewCart.shipping_rates[ 0 ].shipping_rates[ - currentlySelectedIndex - ].selected = false; - const pickupRateIndex = - previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( - ( rate ) => rate.method_id === 'pickup_location' - ); - previewCart.shipping_rates[ 0 ].shipping_rates[ - pickupRateIndex - ].selected = true; - - dispatch( CART_STORE_KEY ).receiveCart( previewCart ); - - render( ); - expect( - screen.getByText( - /Collection from 123 Easy Street, New York, 12345/ - ) - ).toBeInTheDocument(); - } ); - it( 'renders no address if one is not set in the methods metadata', async () => { - dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); - - // Deselect the default selected rate and select pickup_location:1 rate. - const currentlySelectedIndex = - previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( - ( rate ) => rate.selected - ); - previewCart.shipping_rates[ 0 ].shipping_rates[ - currentlySelectedIndex - ].selected = false; - const pickupRateIndex = - previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( - ( rate ) => rate.rate_id === 'pickup_location:2' - ); - previewCart.shipping_rates[ 0 ].shipping_rates[ - pickupRateIndex - ].selected = true; - - // Set the pickup_location metadata value to an empty string in the selected pickup rate. - const addressKeyIndex = previewCart.shipping_rates[ 0 ].shipping_rates[ - pickupRateIndex - ].meta_data.findIndex( - ( metaData ) => metaData.key === 'pickup_address' - ); - previewCart.shipping_rates[ 0 ].shipping_rates[ - pickupRateIndex - ].meta_data[ addressKeyIndex ].value = ''; - - dispatch( CART_STORE_KEY ).receiveCart( previewCart ); - - render( ); - expect( - screen.queryByText( /Collection from / ) - ).not.toBeInTheDocument(); - } ); -} ); diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/shipping-calculator/shipping-calculator-button.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/shipping-calculator/shipping-calculator-button.tsx index 9d48d98e9bd..bd55b2de8c9 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/shipping-calculator/shipping-calculator-button.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/shipping-calculator/shipping-calculator-button.tsx @@ -31,7 +31,6 @@ export const ShippingCalculatorButton = ( { + + ); +}; + +export default ConfigurePlaceholder; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/checkout/configure-placeholder/style.scss similarity index 70% rename from plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/style.scss rename to plugins/woocommerce-blocks/assets/js/blocks/checkout/configure-placeholder/style.scss index a5e23fedd40..deed836df3c 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/style.scss +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/configure-placeholder/style.scss @@ -1,4 +1,4 @@ -.components-placeholder.wc-block-checkout__no-shipping-placeholder { +.components-placeholder.wc-block-checkout__configure-placeholder { margin-bottom: $gap; * { @@ -13,7 +13,7 @@ color: $white; } - .wc-block-checkout__no-shipping-placeholder-description { + .wc-block-checkout__configure-placeholder-description { display: block; margin: 0.25em 0 1em 0; } diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.json b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.json index 0e01ec44c03..b524ebde66a 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.json +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.json @@ -16,6 +16,10 @@ "type": "string", "default": "" }, + "disableProductDescriptions": { + "type": "boolean", + "default": false + }, "lock": { "type": "object", "default": { @@ -24,10 +28,8 @@ } } }, - "parent": [ - "woocommerce/checkout-order-summary-block" - ], + "parent": [ "woocommerce/checkout-order-summary-block" ], "textdomain": "woocommerce", "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3 -} \ No newline at end of file +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.tsx index 2c3ccab913f..c2b41f0ee2a 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/block.tsx @@ -5,12 +5,23 @@ import { OrderSummary } from '@woocommerce/base-components/cart-checkout'; import { useStoreCart } from '@woocommerce/base-context/hooks'; import { TotalsWrapper } from '@woocommerce/blocks-components'; -const Block = ( { className = '' }: { className?: string } ): JSX.Element => { +/** + * Internal dependencies + */ +import { BlockAttributes } from './edit'; + +const Block = ( { + className = '', + disableProductDescriptions = false, +}: BlockAttributes ): JSX.Element => { const { cartItems } = useStoreCart(); return ( - + ); }; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/edit.tsx index 5b589f4f095..d5372dc04bd 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-cart-items/edit.tsx @@ -1,26 +1,61 @@ /** * External dependencies */ -import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; +import { useBlockProps, InspectorControls } from '@wordpress/block-editor'; +import { PanelBody, ToggleControl } from '@wordpress/components'; +import { isExperimentalBlocksEnabled } from '@woocommerce/block-settings'; /** * Internal dependencies */ import Block from './block'; +export type BlockAttributes = { + className: string; + disableProductDescriptions: boolean; +}; + export const Edit = ( { attributes, + setAttributes, }: { - attributes: { - className: string; - }; + attributes: BlockAttributes; setAttributes: ( attributes: Record< string, unknown > ) => void; } ): JSX.Element => { - const { className } = attributes; + const { className, disableProductDescriptions } = attributes; const blockProps = useBlockProps(); + return (
- + { /* For now this setting can only be enabled if you have experimental features enabled. */ } + { isExperimentalBlocksEnabled() && ( + + + + setAttributes( { + disableProductDescriptions: + ! disableProductDescriptions, + } ) + } + /> + + + ) } +
); }; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-shipping/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-shipping/block.tsx index 7ca7678c2b1..e8fbeed254b 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-shipping/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-shipping/block.tsx @@ -1,32 +1,68 @@ /** * External dependencies */ +import { __ } from '@wordpress/i18n'; import { TotalsShipping } from '@woocommerce/base-components/cart-checkout'; -import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; -import { useStoreCart } from '@woocommerce/base-context/hooks'; +import { useStoreCart } from '@woocommerce/base-context'; import { TotalsWrapper } from '@woocommerce/blocks-checkout'; +import { useSelect } from '@wordpress/data'; +import { CHECKOUT_STORE_KEY } from '@woocommerce/block-data'; +import { + filterShippingRatesByPrefersCollection, + isAddressComplete, + selectedRatesAreCollectable, +} from '@woocommerce/base-utils'; const Block = ( { className = '', }: { className?: string; } ): JSX.Element | null => { - const { cartTotals, cartNeedsShipping } = useStoreCart(); + const { cartNeedsShipping, shippingRates, shippingAddress } = + useStoreCart(); + const prefersCollection = useSelect( ( select ) => + select( CHECKOUT_STORE_KEY ).prefersCollection() + ); if ( ! cartNeedsShipping ) { return null; } - const totalsCurrency = getCurrencyFromPriceResponse( cartTotals ); + const hasSelectedCollectionOnly = selectedRatesAreCollectable( + filterShippingRatesByPrefersCollection( + shippingRates, + prefersCollection ?? false + ) + ); + + const hasCompleteAddress = isAddressComplete( shippingAddress, [ + 'state', + 'country', + 'postcode', + 'city', + ] ); return ( + { hasCompleteAddress + ? __( + 'No available delivery option', + 'woocommerce' + ) + : __( + 'Enter address to calculate', + 'woocommerce' + ) } +
+ } /> ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/block.tsx index c204a044262..e68704bc635 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/block.tsx @@ -3,8 +3,12 @@ */ import { PaymentMethods } from '../../../cart-checkout-shared/payment-methods'; -const Block = (): JSX.Element | null => { - return ; +const Block = ( { + noPaymentMethods, +}: { + noPaymentMethods?: JSX.Element | undefined; +} ): JSX.Element | null => { + return ; }; export default Block; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/edit.tsx index 820c7b5ed5e..9c9d4b408e9 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-payment-block/edit.tsx @@ -5,6 +5,7 @@ import clsx from 'clsx'; import { __ } from '@wordpress/i18n'; import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; import { PanelBody, ExternalLink } from '@wordpress/components'; +import { payment } from '@wordpress/icons'; import { ADMIN_URL, getSetting } from '@woocommerce/settings'; import ExternalLinkCard from '@woocommerce/editor-components/external-link-card'; import { innerBlockAreas } from '@woocommerce/blocks-checkout'; @@ -24,6 +25,7 @@ import { AdditionalFieldsContent, } from '../../form-step'; import Block from './block'; +import ConfigurePlaceholder from '../../configure-placeholder'; export const Edit = ( { attributes, @@ -119,7 +121,23 @@ export const Edit = ( { ) } - + + } + /> diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/block.tsx index 13633478b0c..608e23732a9 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/block.tsx @@ -60,7 +60,26 @@ const renderShippingRatesControlOption = ( }; }; -const Block = ( { noShippingPlaceholder = null } ): ReactElement | null => { +const NoShippingAddressMessage = () => { + return ( +

+ { __( + 'Enter a shipping address to view shipping options.', + 'woocommerce' + ) } +

+ ); +}; + +const Block = ( { + noShippingPlaceholder = null, +}: { + noShippingPlaceholder?: ReactElement | null; +} ) => { const { isEditor } = useEditorContext(); const { @@ -95,14 +114,7 @@ const Block = ( { noShippingPlaceholder = null } ): ReactElement | null => { getShippingRatesPackageCount( shippingRates ); if ( ! hasCalculatedShipping && ! shippingRatesPackageCount ) { - return ( -

- { __( - 'Shipping options will be displayed here after entering your full shipping address.', - 'woocommerce' - ) } -

- ); + return ; } const addressComplete = isAddressComplete( shippingAddress ); @@ -124,15 +136,12 @@ const Block = ( { noShippingPlaceholder = null } ): ReactElement | null => { status="warning" > { __( - 'There are no shipping options available. Please check your shipping address.', + 'No shipping options are available for this address. Please verify the address is correct or try a different address.', 'woocommerce' ) } ) : ( - __( - 'Add a shipping address to view shipping options.', - 'woocommerce' - ) + ) } } diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/edit.tsx index 6845bfe7e78..c690f6d1a31 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/edit.tsx @@ -5,6 +5,7 @@ import clsx from 'clsx'; import { __ } from '@wordpress/i18n'; import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; import { PanelBody, ExternalLink } from '@wordpress/components'; +import { shipping } from '@wordpress/icons'; import { ADMIN_URL, getSetting } from '@woocommerce/settings'; import ExternalLinkCard from '@woocommerce/editor-components/external-link-card'; import { innerBlockAreas } from '@woocommerce/blocks-checkout'; @@ -19,7 +20,7 @@ import { AdditionalFields, AdditionalFieldsContent, } from '../../form-step'; -import NoShippingPlaceholder from './no-shipping-placeholder'; +import ConfigurePlaceholder from '../../configure-placeholder'; import Block from './block'; import './editor.scss'; @@ -126,7 +127,23 @@ export const Edit = ( { ) } - } /> + + } + /> diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/index.js b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/index.js deleted file mode 100644 index 501a8eddc73..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/no-shipping-placeholder/index.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { Placeholder, Button } from '@wordpress/components'; -import { Icon, shipping } from '@wordpress/icons'; -import { ADMIN_URL } from '@woocommerce/settings'; - -/** - * Internal dependencies - */ -import './style.scss'; - -const NoShippingPlaceholder = () => { - return ( - } - label={ __( 'Shipping options', 'woocommerce' ) } - className="wc-block-checkout__no-shipping-placeholder" - > - - { __( - 'Your store does not have any Shipping Options configured. Once you have added your Shipping Options they will appear here.', - 'woocommerce' - ) } - - - - ); -}; - -export default NoShippingPlaceholder; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/style.scss index bb950600655..72379d3530b 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/style.scss +++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/style.scss @@ -11,4 +11,11 @@ .wc-block-components-shipping-rates-control__no-results-notice { margin: em($gap-small) 0; } + + .wc-block-components-shipping-rates-control__no-shipping-address-message { + background-color: $gray-200; + color: $gray-700; + padding: em($gap-large); + text-align: center; + } } diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/block.tsx index d947a80bdc0..4d93aea271f 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/block.tsx @@ -12,8 +12,12 @@ import { PanelBody, ToggleControl, Placeholder, + + // @ts-expect-error - no types. // eslint-disable-next-line @wordpress/no-unsafe-wp-apis __experimentalToggleGroupControl as ToggleGroupControl, + + // @ts-expect-error - no types. // eslint-disable-next-line @wordpress/no-unsafe-wp-apis __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; @@ -72,6 +76,7 @@ const ProductCategoriesBlock = ( { > setAttributes( { diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/edit.tsx index eaf56523e24..f661957ce3a 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/edit.tsx @@ -10,7 +10,9 @@ import Block from './block'; import './editor.scss'; import type { ProductCategoriesBlockProps } from './types'; -export const Edit = ( props: ProductCategoriesBlockProps ): JSX.Element => { +export default function ProductCategoriesEdit( + props: ProductCategoriesBlockProps +): JSX.Element { const blockProps = useBlockProps(); return ( @@ -18,4 +20,4 @@ export const Edit = ( props: ProductCategoriesBlockProps ): JSX.Element => { ); -}; +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/index.tsx index f3f076d69cb..ae9ccf2ffbe 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-categories/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-categories/index.tsx @@ -7,11 +7,11 @@ import { Icon, listView } from '@wordpress/icons'; /** * Internal dependencies */ -import './editor.scss'; import metadata from './block.json'; -import './style.scss'; -import { Edit } from './edit'; +import Edit from './edit'; import type { ProductCategoriesIndexProps } from './types'; +import './editor.scss'; +import './style.scss'; registerBlockType( metadata, { icon: { diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-elements/add-to-cart-form/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-elements/add-to-cart-form/edit.tsx index 211aea918b4..0bc2c4765db 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-elements/add-to-cart-form/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-elements/add-to-cart-form/edit.tsx @@ -9,6 +9,8 @@ import { BlockEditProps } from '@wordpress/blocks'; import { Disabled, Tooltip } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { isSiteEditorPage } from '@woocommerce/utils'; +import { getSettingWithCoercion } from '@woocommerce/settings'; +import { isBoolean } from '@woocommerce/types'; /** * Internal dependencies @@ -26,8 +28,15 @@ export interface Attributes { const Edit = ( props: BlockEditProps< Attributes > ) => { const { setAttributes } = props; + const isStepperLayoutFeatureEnabled = getSettingWithCoercion( + 'isStepperLayoutFeatureEnabled', + false, + isBoolean + ); + const quantitySelectorStyleClass = - props.attributes.quantitySelectorStyle === QuantitySelectorStyle.Input + props.attributes.quantitySelectorStyle === + QuantitySelectorStyle.Input || ! isStepperLayoutFeatureEnabled ? 'wc-block-add-to-cart-form--input' : 'wc-block-add-to-cart-form--stepper'; @@ -52,10 +61,14 @@ const Edit = ( props: BlockEditProps< Attributes > ) => { return ( <> - + { isStepperLayoutFeatureEnabled && ( + + ) }
) => {
- { props.attributes.quantitySelectorStyle === - QuantitySelectorStyle.Input && ( + { ( props.attributes.quantitySelectorStyle === + QuantitySelectorStyle.Input || + ! isStepperLayoutFeatureEnabled ) && ( <>
) => { ) } { props.attributes.quantitySelectorStyle === - QuantitySelectorStyle.Stepper && ( - <> -
- + + +
+ - - -
- - - ) } + + ) }
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block-variations.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block-variations.tsx deleted file mode 100644 index 4e4287b26a9..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block-variations.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { BlockVariation } from '@wordpress/blocks'; -import { Icon, button } from '@wordpress/icons'; - -const variations: BlockVariation[] = [ - { - name: 'product-filters-overlay-navigation-open-trigger', - title: __( 'Overlay Navigation (Experimental)', 'woocommerce' ), - attributes: { - triggerType: 'open-overlay', - }, - isDefault: false, - icon: , - isActive: [ 'triggerType' ], - }, -]; - -export const blockVariations = variations; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block.json b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block.json deleted file mode 100644 index 829afc09465..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/block.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "woocommerce/product-filters-overlay-navigation", - "title": "Overlay Navigation (Experimental)", - "description": "Display overlay navigation controls.", - "category": "woocommerce", - "keywords": [ "WooCommerce" ], - "textdomain": "woocommerce", - "ancestor": [ "woocommerce/product-filters-overlay", "woocommerce/product-filters" ], - "attributes": { - "align": { - "type": "string", - "default": "right" - }, - "navigationStyle": { - "type": "string", - "default": "label-and-icon" - }, - "buttonStyle": { - "type": "string", - "default": "link" - }, - "iconSize": { - "type": "number" - }, - "overlayMode": { - "type": "string", - "default": "never" - }, - "overlayIcon": { - "type": "string", - "default": "filter-icon-1" - }, - "style": { - "type": "object", - "default": { - "spacing": { - "blockGap": "1rem" - } - } - }, - "triggerType": { - "type": "string", - "default": "close-overlay" - } - }, - "supports": { - "interactivity": true, - "align": [ "left", "right", "center"], - "inserter": true, - "color": { - "__experimentalDefaultControls": { - "text": false, - "background": false - } - }, - "position": { - "sticky": true - }, - "typography": { - "fontSize": true, - "lineHeight": true, - "__experimentalFontWeight": true, - "__experimentalFontFamily": true, - "__experimentalFontStyle": true, - "__experimentalTextTransform": true, - "__experimentalTextDecoration": true, - "__experimentalLetterSpacing": true, - "__experimentalDefaultControls": { - "fontSize": false - } - }, - "layout": { - "default": { - "type": "flex", - "orientation": "horizontal", - "flexWrap": "nowrap" - }, - "allowEditing": false - }, - "spacing": { - "margin": true, - "padding": true, - "blockGap": true, - "__experimentalDefaultControls": { - "margin": false, - "padding": false, - "blockGap": false - } - }, - "__experimentalBorder": { - "color": true, - "radius": true, - "style": true, - "width": true, - "__experimentalDefaultControls": { - "color": false, - "radius": false, - "style": false, - "width": false - } - } - }, - "usesContext": [ "woocommerce/product-filters/overlay"], - "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 3 -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/edit.tsx deleted file mode 100644 index 85845cdff45..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/edit.tsx +++ /dev/null @@ -1,211 +0,0 @@ -/** - * External dependencies - */ -import { useSelect } from '@wordpress/data'; -import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; -import { BlockEditProps, store as blocksStore } from '@wordpress/blocks'; -import { __ } from '@wordpress/i18n'; -import clsx from 'clsx'; -import { Icon, close, menu, settings } from '@wordpress/icons'; -import { filter, filterThreeLines } from '@woocommerce/icons'; - -/** - * Internal dependencies - */ -import type { BlockAttributes, BlockVariationTriggerType } from './types'; -import './editor.scss'; -import { Inspector } from './inspector-controls'; - -const OverlayNavigationLabel = ( { - variation, -}: { - variation: BlockVariationTriggerType; -} ) => { - let label = __( 'Close', 'woocommerce' ); - if ( variation === 'open-overlay' ) { - label = __( 'Filters', 'woocommerce' ); - } - - return { label }; -}; - -const OverlayNavigationIcon = ( { - variation, - iconSize, - overlayIcon, - style, -}: { - variation: BlockVariationTriggerType; - iconSize: number | undefined; - overlayIcon: string; - style: BlockAttributes[ 'style' ]; -} ) => { - let icon = close; - - if ( variation === 'open-overlay' ) { - switch ( overlayIcon ) { - case 'filter-icon-4': - icon = settings; - break; - case 'filter-icon-3': - icon = menu; - break; - case 'filter-icon-2': - icon = filterThreeLines; - break; - case 'filter-icon-1': - icon = filter; - break; - default: - icon = filter; - } - } - - return ( - - ); -}; - -const OverlayNavigationContent = ( { - variation, - iconSize, - style, - overlayIcon, - navigationStyle, -}: { - variation: BlockVariationTriggerType; - iconSize: BlockAttributes[ 'iconSize' ]; - style: BlockAttributes[ 'style' ]; - overlayIcon: BlockAttributes[ 'overlayIcon' ]; - navigationStyle: BlockAttributes[ 'navigationStyle' ]; -} ) => { - const overlayNavigationLabel = ( - - ); - const overlayNavigationIcon = ( - - ); - - if ( navigationStyle === 'label-and-icon' ) { - if ( variation === 'open-overlay' ) { - return ( - <> - { overlayNavigationIcon } - { overlayNavigationLabel } - - ); - } else if ( variation === 'close-overlay' ) { - return ( - <> - { overlayNavigationLabel } - { overlayNavigationIcon } - - ); - } - } else if ( navigationStyle === 'label-only' ) { - return overlayNavigationLabel; - } else if ( navigationStyle === 'icon-only' ) { - return overlayNavigationIcon; - } - - return null; -}; - -type BlockProps = BlockEditProps< BlockAttributes >; - -export const Edit = ( { attributes, setAttributes }: BlockProps ) => { - const { - navigationStyle, - buttonStyle, - iconSize, - overlayIcon, - style, - triggerType, - } = attributes; - - const blockProps = useBlockProps( { - className: clsx( 'wc-block-product-filters-overlay-navigation', { - 'wp-block-button__link wp-element-button': buttonStyle !== 'link', - } ), - } ); - - const shouldHideBlock = () => { - if ( triggerType === 'open-overlay' ) { - return false; - } - - return true; - }; - // We need useInnerBlocksProps because Gutenberg only applies layout classes - // to parent block. We don't have any inner blocks but we want to use the - // layout controls. - const innerBlocksProps = useInnerBlocksProps( blockProps ); - - const buttonBlockStyles = useSelect( - ( select ) => select( blocksStore ).getBlockStyles( 'core/button' ), - [] - ); - - const buttonStyles = [ - { value: 'link', label: __( 'Link', 'woocommerce' ) }, - ]; - - buttonBlockStyles.forEach( - ( buttonBlockStyle: { name: string; label: string } ) => { - if ( buttonBlockStyle.name === 'link' ) return; - buttonStyles.push( { - value: buttonBlockStyle.name, - label: buttonBlockStyle.label, - } ); - } - ); - - if ( shouldHideBlock() ) { - return ( - - ); - } - - return ( - - ); -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/editor.scss b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/editor.scss deleted file mode 100644 index dff648439fa..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/editor.scss +++ /dev/null @@ -1,33 +0,0 @@ -.wc-block-product-filters-overlay-navigation__icon-size-control { - - .components-range-control__wrapper { - order: 1; - } - - .components-range-control__number { - order: 0; - margin-left: 0 !important; - margin-right: 20px; - - .components-input-control__input::-webkit-outer-spin-button, - .components-input-control__input::-webkit-inner-spin-button { - appearance: none; - margin: 0; - } - - /* Remove stepper arrows in Firefox */ - .components-input-control__input { - appearance: textfield; - width: 40px !important; - } - - .components-input-control__container::after { - content: "px"; - position: absolute; - top: 6px; - right: 7px; - font-size: 12px; - color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); - } - } -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/frontend.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/frontend.tsx deleted file mode 100644 index 77411ae98ea..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/frontend.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { store } from '@woocommerce/interactivity'; - -export interface ProductFiltersContext { - isDialogOpen: boolean; -} - -const productFiltersOverlayNavigation = { - state: {}, - actions: {}, - callbacks: {}, -}; - -store( 'woocommerce/product-filters', productFiltersOverlayNavigation ); - -export type ProductFiltersOverlayNavigation = - typeof productFiltersOverlayNavigation; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/index.tsx deleted file mode 100644 index 000ea4807fe..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/** - * External dependencies - */ -import { registerBlockType } from '@wordpress/blocks'; -import { closeSquareShadow } from '@woocommerce/icons'; -import { Icon } from '@wordpress/icons'; -import { isExperimentalBlocksEnabled } from '@woocommerce/block-settings'; - -/** - * Internal dependencies - */ -import metadata from './block.json'; -import { Edit } from './edit'; -import { Save } from './save'; -import { blockVariations } from './block-variations'; -import './style.scss'; - -if ( isExperimentalBlocksEnabled() ) { - registerBlockType( metadata, { - edit: Edit, - save: Save, - icon: , - variations: blockVariations, - } ); -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/inspector-controls.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/inspector-controls.tsx deleted file mode 100644 index 847d7369082..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/inspector-controls.tsx +++ /dev/null @@ -1,176 +0,0 @@ -/** - * External dependencies - */ -import { InspectorControls } from '@wordpress/block-editor'; -import { BlockEditProps } from '@wordpress/blocks'; -import { __ } from '@wordpress/i18n'; -import { filter, filterThreeLines } from '@woocommerce/icons'; -import { Icon, menu, settings } from '@wordpress/icons'; -import { - PanelBody, - RadioControl, - SelectControl, - RangeControl, - __experimentalToggleGroupControl as ToggleGroupControl, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, -} from '@wordpress/components'; - -/** - * Internal dependencies - */ -import type { BlockAttributes } from './types'; - -interface ButtonStyle { - value: string; - label: string; -} - -interface InspectorProps { - attributes: BlockEditProps< BlockAttributes >[ 'attributes' ]; - setAttributes: BlockEditProps< BlockAttributes >[ 'setAttributes' ]; - buttonStyles: ButtonStyle[]; -} - -export const Inspector = ( { - attributes, - setAttributes, - buttonStyles, -}: InspectorProps ) => { - const { navigationStyle, buttonStyle, iconSize, overlayIcon, triggerType } = - attributes; - return ( - - - - setAttributes( { - navigationStyle: value, - } ) - } - /> - - { buttonStyles.length <= 3 && ( - - setAttributes( { - buttonStyle: value, - } ) - } - > - { buttonStyles.map( ( option ) => ( - - ) ) } - - ) } - { buttonStyles.length > 3 && ( - - setAttributes( { - buttonStyle: value, - } ) - } - /> - ) } - - { triggerType === 'open-overlay' && - navigationStyle !== 'label-only' && ( - { - setAttributes( { - overlayIcon: value, - } ); - } } - > - } - /> - - } - /> - } - /> - } - /> - - ) } - - { navigationStyle !== 'label-only' && ( - { - setAttributes( { iconSize: newSize } ); - } } - min={ 0 } - max={ 300 } - /> - ) } - - - ); -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/save.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/save.tsx deleted file mode 100644 index d6fb9643a7e..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/save.tsx +++ /dev/null @@ -1,12 +0,0 @@ -/** - * External dependencies - */ -import { useBlockProps } from '@wordpress/block-editor'; -import clsx from 'clsx'; - -export const Save = (): JSX.Element => { - const blockProps = useBlockProps.save( { - className: clsx( 'wc-block-product-filters-overlay-navigation' ), - } ); - return
; -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/style.scss deleted file mode 100644 index da985d86584..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/style.scss +++ /dev/null @@ -1,25 +0,0 @@ -.wc-block-product-filters-overlay-navigation__wrapper { - display: flex; -} - -.wc-block-product-filters-overlay-navigation { - display: flex; - flex-direction: row; - cursor: pointer; - - &.alignright { - justify-content: right; - } - - &.alignleft { - justify-content: unset; - } - - &.aligncenter { - justify-content: center; - } - - &.hidden { - display: none; - } -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/types.ts b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/types.ts deleted file mode 100644 index 74db6bb5f21..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay-navigation/types.ts +++ /dev/null @@ -1,54 +0,0 @@ -type BorderRadius = { - bottomLeft: string; - bottomRight: string; - topLeft: string; - topRight: string; -}; -type BorderSide = { - color: string; - width: string; -}; - -export type BlockVariationTriggerType = 'open-overlay' | 'close-overlay'; - -export type BlockAttributes = { - navigationStyle: 'label-and-icon' | 'label-only' | 'icon-only'; - buttonStyle: string; - iconSize?: number; - triggerType: BlockVariationTriggerType; - overlayIcon: string; - style: { - border?: { - radius?: string | BorderRadius; - width?: string; - top?: BorderSide; - bottom?: BorderSide; - left?: BorderSide; - right?: BorderSide; - }; - spacing?: { - blockGap?: string; - margin?: { - top?: string; - right?: string; - bottom?: string; - left?: string; - }; - padding?: { - top?: string; - right?: string; - bottom?: string; - left?: string; - }; - }; - typography?: { - fontSize?: string; - lineHeight?: number; - fontStyle?: string; - fontWeight?: string; - letterSpacing?: string; - textDecoration?: string; - textTransform?: string; - }; - }; -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/block.json b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/block.json deleted file mode 100644 index 6278e472b09..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/block.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 3, - "name": "woocommerce/product-filters-overlay", - "version": "1.0.0", - "title": "Product Filters Overlay (Experimental)", - "description": "Display product filters in an overlay on top of a page.", - "category": "woocommerce", - "keywords": [ - "WooCommerce" - ], - "supports": { - "align": true, - "multiple": false, - "inserter": false, - "layout": { - "allowCustomContentAndWideSize": true - }, - "color": {}, - "typography": {}, - "dimensions": {}, - "spacing": { - "padding": true, - "blockGap": true - } - }, - "textdomain": "woocommerce", - "providesContext": {}, - "attributes": { - "overlayStyle": { - "type": "string", - "default": "drawer" - }, - "overlayPosition": { - "type": "string", - "default": "left" - }, - "style": { - "type": "object", - "default": { - "spacing": { - "padding": { - "top": "1rem", - "right": "1rem", - "bottom": "1rem", - "left": "1rem" - } - } - } - } - }, - "example": {} -} \ No newline at end of file diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/edit.tsx deleted file mode 100644 index ed16b732af2..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/edit.tsx +++ /dev/null @@ -1,124 +0,0 @@ -/* eslint-disable @wordpress/no-unsafe-wp-apis */ -/** - * External dependencies - */ -import { - InnerBlocks, - useBlockProps, - useInnerBlocksProps, - InspectorControls, -} from '@wordpress/block-editor'; -import { BlockEditProps, InnerBlockTemplate } from '@wordpress/blocks'; -import { - PanelBody, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, - __experimentalToggleGroupControl as ToggleGroupControl, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { WC_BLOCKS_IMAGE_URL } from '@woocommerce/block-settings'; - -/** - * Internal dependencies - */ -import type { ProductFiltersOverlayBlockAttributes } from './types'; - -const TEMPLATE: InnerBlockTemplate[] = [ [ 'woocommerce/product-filters' ] ]; - -export const Edit = ( { - setAttributes, - attributes, -}: BlockEditProps< ProductFiltersOverlayBlockAttributes > ) => { - const blockProps = useBlockProps(); - - return ( -
- - - { - setAttributes( { - overlayStyle: value, - } ); - } } - help={ - attributes.overlayStyle === 'fullscreen' - ? __( - 'The overlay will fill up the whole screen.', - 'woocommerce' - ) - : __( - 'The overlay will show on the left or right side of the screen (only on desktop).', - 'woocommerce' - ) - } - > - - - - { attributes.overlayStyle === 'drawer' && ( - { - setAttributes( { - overlayPosition: value, - } ); - } } - > - - - - ) } - - { attributes.overlayStyle === 'drawer' ? ( - { - ) : ( - { - ) } - - - -
- ); -}; - -export const Save = () => { - const blockProps = useBlockProps.save(); - const innerBlocksProps = useInnerBlocksProps.save( blockProps ); - return
; -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/icon.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/icon.tsx deleted file mode 100644 index 89255bbc35a..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/icon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -/** - * External dependencies - */ -import { Icon, pages } from '@wordpress/icons'; - -const icon = () => ; - -export default icon; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/index.tsx deleted file mode 100644 index 74486af38cd..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -/** - * External dependencies - */ -import { registerBlockType } from '@wordpress/blocks'; -import { isExperimentalBlocksEnabled } from '@woocommerce/block-settings'; - -/** - * Internal dependencies - */ -import metadata from './block.json'; -import { ProductFiltersOverlayBlockSettings } from './settings'; - -if ( isExperimentalBlocksEnabled() ) { - registerBlockType( metadata, ProductFiltersOverlayBlockSettings ); -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/save.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/save.tsx deleted file mode 100644 index 228294212c0..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/save.tsx +++ /dev/null @@ -1,17 +0,0 @@ -/** - * External dependencies - */ -import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; -import clsx from 'clsx'; - -/** - * Internal dependencies - */ - -export const Save = (): JSX.Element => { - const blockProps = useBlockProps.save( { - className: clsx( 'wc-block-product-filters-overlay' ), - } ); - const innerBlocksProps = useInnerBlocksProps.save( blockProps ); - return
; -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/settings.ts b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/settings.ts deleted file mode 100644 index f2123044d41..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/settings.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Internal dependencies - */ -import { Edit } from './edit'; -import { Save } from './save'; -import icon from './icon'; - -export const ProductFiltersOverlayBlockSettings = { - icon, - edit: Edit, - save: Save, -}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/types.ts b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/types.ts deleted file mode 100644 index e59dcbf0a7e..00000000000 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/overlay/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ProductFiltersOverlayBlockAttributes { - overlayStyle: string; - overlayPosition: string; - setAttributes: ( attributes: ProductFiltersOverlayBlockAttributes ) => void; -} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/edit.tsx index ffe4a31c78c..084ca3fbe6c 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/edit.tsx @@ -32,6 +32,7 @@ import { EXCLUDED_BLOCKS } from '../../constants'; import { Notice } from '../../components/notice'; import type { Attributes } from './types'; import './style.scss'; +import { InitialDisabled } from '../../components/initial-disabled'; const RatingFilterEdit = ( props: BlockEditProps< Attributes > ) => { const { attributes, setAttributes } = props; @@ -189,30 +190,32 @@ const RatingFilterEdit = ( props: BlockEditProps< Attributes > ) => { />
- { showNoProductsNotice && ( - - { __( - "Your store doesn't have any products with ratings yet. This filter option will display when a product receives a review.", - 'woocommerce' - ) } - - ) } -
- + { showNoProductsNotice && ( + + { __( + "Your store doesn't have any products with ratings yet. This filter option will display when a product receives a review.", + 'woocommerce' + ) } + + ) } +
- { children } - -
+ + { children } + +
+
); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/style.scss index 05109040dcd..ff6a707758e 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/style.scss +++ b/plugins/woocommerce-blocks/assets/js/blocks/product-filters/inner-blocks/rating-filter/style.scss @@ -1,6 +1,4 @@ .wp-block-woocommerce-product-filter-rating { - display: grid; - .wc-block-components-product-rating { margin-bottom: 0; display: flex; diff --git a/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/editor.scss b/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/editor.scss deleted file mode 100644 index a6224675b76..00000000000 --- a/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/editor.scss +++ /dev/null @@ -1,7 +0,0 @@ -.wc-blocks-no-payment-methods-notice { - margin: 0; - - .components-notice__content { - margin: 4px 0; - } -} diff --git a/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/index.tsx b/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/index.tsx deleted file mode 100644 index 5b08a4826af..00000000000 --- a/plugins/woocommerce-blocks/assets/js/editor-components/no-payment-methods-notice/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { Notice, ExternalLink } from '@wordpress/components'; -import { ADMIN_URL } from '@woocommerce/settings'; - -/** - * Internal dependencies - */ -import './editor.scss'; - -export function NoPaymentMethodsNotice() { - const noticeContent = __( - 'Your store does not have any payment methods that support the Checkout block. Once you have configured a compatible payment method it will be displayed here.', - 'woocommerce' - ); - - return ( - -
- { noticeContent }{ ' ' } - - { __( 'Configure Payment Methods', 'woocommerce' ) } - -
-
- ); -} diff --git a/plugins/woocommerce-blocks/bin/webpack-entries.js b/plugins/woocommerce-blocks/bin/webpack-entries.js index 20577a59cd3..d040dcefcf6 100644 --- a/plugins/woocommerce-blocks/bin/webpack-entries.js +++ b/plugins/woocommerce-blocks/bin/webpack-entries.js @@ -91,14 +91,6 @@ const blocks = { 'product-filters': { isExperimental: true, }, - 'product-filters-overlay': { - isExperimental: true, - customDir: 'product-filters/inner-blocks/overlay', - }, - 'product-filters-overlay-navigation': { - isExperimental: true, - customDir: 'product-filters/inner-blocks/overlay-navigation', - }, 'product-filter-status': { isExperimental: true, customDir: 'product-filters/inner-blocks/status-filter', diff --git a/plugins/woocommerce-blocks/tests/e2e/plugins/enable-experimental-features.php b/plugins/woocommerce-blocks/tests/e2e/plugins/enable-experimental-features.php deleted file mode 100644 index 0b03452dd33..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/plugins/enable-experimental-features.php +++ /dev/null @@ -1,21 +0,0 @@ - { ).toBeVisible(); } ); - test( 'has the stepper option visible', async ( { - admin, - editor, - blockUtils, - } ) => { - await admin.createNewPost(); - await editor.insertBlock( { name: 'woocommerce/single-product' } ); + test.describe( 'Stepper Layout', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.setFeatureFlag( + 'add-to-cart-with-options-stepper-layout', + true + ); + } ); + test( 'has the stepper option visible', async ( { + admin, + editor, + blockUtils, + } ) => { + await admin.createNewPost(); + await editor.insertBlock( { name: 'woocommerce/single-product' } ); - await blockUtils.configureSingleProductBlock(); + await blockUtils.configureSingleProductBlock(); - await blockUtils.enableStepperMode(); + await blockUtils.enableStepperMode(); - const minusButton = editor.canvas.locator( - blockData.selectors.editor.stepperMinusButton - ); - const plusButton = editor.canvas.locator( - blockData.selectors.editor.stepperPlusButton - ); + const minusButton = editor.canvas.locator( + blockData.selectors.editor.stepperMinusButton + ); + const plusButton = editor.canvas.locator( + blockData.selectors.editor.stepperPlusButton + ); - await expect( minusButton ).toBeVisible(); - await expect( plusButton ).toBeVisible(); - } ); - - test( 'has the stepper mode working on the frontend', async ( { - admin, - editor, - blockUtils, - page, - } ) => { - await admin.createNewPost(); - await editor.insertBlock( { name: 'woocommerce/single-product' } ); - - const productName = 'Hoodie with Logo'; - - await blockUtils.configureSingleProductBlock( productName ); - - await blockUtils.enableStepperMode(); - - await editor.publishAndVisitPost(); - - const minusButton = page.getByLabel( `Reduce quantity` ); - const plusButton = page.getByLabel( `Increase quantity` ); - - await expect( minusButton ).toBeVisible(); - await expect( plusButton ).toBeVisible(); - - const input = page.getByLabel( 'Product quantity' ); - - await expect( input ).toHaveValue( '1' ); - await plusButton.click(); - await expect( input ).toHaveValue( '2' ); - await minusButton.click(); - await expect( input ).toHaveValue( '1' ); - // Ensure the quantity doesn't go below 1. - await minusButton.click(); - await expect( input ).toHaveValue( '1' ); - } ); - - test( "doesn't render stepper when the product is sold individually", async ( { - admin, - editor, - blockUtils, - page, - } ) => { - await blockUtils.createSoldIndividuallyProduct(); - await admin.createNewPost(); - await editor.insertBlock( { name: 'woocommerce/single-product' } ); - - const productName = 'Sold Individually'; - - await blockUtils.configureSingleProductBlock( productName ); - await blockUtils.enableStepperMode(); - - await editor.publishAndVisitPost(); - - const minusButton = page.getByLabel( `Reduce quantity` ); - const plusButton = page.getByLabel( `Increase quantity ` ); - - await expect( minusButton ).toBeHidden(); - await expect( plusButton ).toBeHidden(); - } ); - - test( 'has the stepper mode working on the frontend with min, max, and step attributes', async ( { - admin, - editor, - blockUtils, - page, - } ) => { - await admin.createNewPost(); - await editor.insertBlock( { name: 'woocommerce/single-product' } ); - - const productName = 'Hoodie with Logo'; - - await blockUtils.configureSingleProductBlock( productName ); - - await blockUtils.enableStepperMode(); - await editor.publishAndVisitPost(); - - await blockUtils.setMinMaxAndStep( { - min: 2, - max: 10, - step: 2, + await expect( minusButton ).toBeVisible(); + await expect( plusButton ).toBeVisible(); } ); - const minusButton = page.getByLabel( `Reduce quantity` ); - const plusButton = page.getByLabel( `Increase quantity` ); + test( 'has the stepper mode working on the frontend', async ( { + admin, + editor, + blockUtils, + page, + } ) => { + await admin.createNewPost(); + await editor.insertBlock( { name: 'woocommerce/single-product' } ); - await expect( minusButton ).toBeVisible(); - await expect( plusButton ).toBeVisible(); + const productName = 'Hoodie with Logo'; - const input = page.getByLabel( 'Product quantity' ); + await blockUtils.configureSingleProductBlock( productName ); - await expect( input ).toHaveValue( '2' ); - await minusButton.click(); - await expect( input ).toHaveValue( '2' ); - await plusButton.click(); - await expect( input ).toHaveValue( '4' ); - await plusButton.click(); - await expect( input ).toHaveValue( '6' ); - await plusButton.click(); - await expect( input ).toHaveValue( '8' ); - await plusButton.click(); - await expect( input ).toHaveValue( '10' ); - await plusButton.click(); - await expect( input ).toHaveValue( '10' ); + await blockUtils.enableStepperMode(); + + await editor.publishAndVisitPost(); + + const minusButton = page.getByLabel( `Reduce quantity` ); + const plusButton = page.getByLabel( `Increase quantity` ); + + await expect( minusButton ).toBeVisible(); + await expect( plusButton ).toBeVisible(); + + const input = page.getByLabel( 'Product quantity' ); + + await expect( input ).toHaveValue( '1' ); + await plusButton.click(); + await expect( input ).toHaveValue( '2' ); + await minusButton.click(); + await expect( input ).toHaveValue( '1' ); + // Ensure the quantity doesn't go below 1. + await minusButton.click(); + await expect( input ).toHaveValue( '1' ); + } ); + + test( "doesn't render stepper when the product is sold individually", async ( { + admin, + editor, + blockUtils, + page, + } ) => { + await blockUtils.createSoldIndividuallyProduct(); + await admin.createNewPost(); + await editor.insertBlock( { name: 'woocommerce/single-product' } ); + + const productName = 'Sold Individually'; + + await blockUtils.configureSingleProductBlock( productName ); + await blockUtils.enableStepperMode(); + + await editor.publishAndVisitPost(); + + const minusButton = page.getByLabel( `Reduce quantity` ); + const plusButton = page.getByLabel( `Increase quantity ` ); + + await expect( minusButton ).toBeHidden(); + await expect( plusButton ).toBeHidden(); + } ); + + test( 'has the stepper mode working on the frontend with min, max, and step attributes', async ( { + admin, + editor, + blockUtils, + page, + } ) => { + await admin.createNewPost(); + await editor.insertBlock( { name: 'woocommerce/single-product' } ); + + const productName = 'Hoodie with Logo'; + + await blockUtils.configureSingleProductBlock( productName ); + + await blockUtils.enableStepperMode(); + await editor.publishAndVisitPost(); + + await blockUtils.setMinMaxAndStep( { + min: 2, + max: 10, + step: 2, + } ); + + const minusButton = page.getByLabel( `Reduce quantity` ); + const plusButton = page.getByLabel( `Increase quantity` ); + + await expect( minusButton ).toBeVisible(); + await expect( plusButton ).toBeVisible(); + + const input = page.getByLabel( 'Product quantity' ); + + await expect( input ).toHaveValue( '2' ); + await minusButton.click(); + await expect( input ).toHaveValue( '2' ); + await plusButton.click(); + await expect( input ).toHaveValue( '4' ); + await plusButton.click(); + await expect( input ).toHaveValue( '6' ); + await plusButton.click(); + await expect( input ).toHaveValue( '8' ); + await plusButton.click(); + await expect( input ).toHaveValue( '10' ); + await plusButton.click(); + await expect( input ).toHaveValue( '10' ); + } ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts index 750eb786bed..91e9589dcdb 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts @@ -78,7 +78,7 @@ test.describe( 'Shopper → Shipping', () => { await expect( userPage.getByText( - 'Shipping options will be displayed here after entering your full shipping address' + 'Enter a shipping address to view shipping options.' ) ).toBeVisible(); @@ -86,7 +86,7 @@ test.describe( 'Shopper → Shipping', () => { await expect( userPage.getByText( - 'Shipping options will be displayed here after entering your full shipping address' + 'Enter a shipping address to view shipping options.' ) ).toBeHidden(); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts index 135e9363eee..7e03961550a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts @@ -155,9 +155,7 @@ test.describe( 'Shopper (guest) → Order Confirmation → Create Account', () = test.use( { storageState: guestFile } ); test.beforeEach( async ( { frontendUtils, pageObject, requestUtils } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await frontendUtils.goToShop(); await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME ); await frontendUtils.goToCheckout(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters-overlay/product-filters-overlay-navigation.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters-overlay/product-filters-overlay-navigation.block_theme.spec.ts index 143f51c9cd8..e4d19de67d4 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters-overlay/product-filters-overlay-navigation.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters-overlay/product-filters-overlay-navigation.block_theme.spec.ts @@ -18,9 +18,7 @@ const blockData = { test.describe( `Filters Overlay Navigation`, () => { test.beforeEach( async ( { admin, requestUtils } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.templateSlug }`, postType: blockData.templateType, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/active-filter-frontend.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/active-filter-frontend.block_theme.spec.ts index 0fbd25e7f4d..23fbc01560d 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/active-filter-frontend.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/active-filter-frontend.block_theme.spec.ts @@ -14,9 +14,7 @@ const test = base.extend< { templateCompiler: TemplateCompiler } >( { test.describe( 'woocommerce/product-filter-active - Frontend', () => { test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); } ); test( 'Without any filters selected, active block should not be rendered', async ( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-editor.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-editor.block_theme.spec.ts index 77f9b13f090..6fbdee01e21 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-editor.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-editor.block_theme.spec.ts @@ -32,9 +32,7 @@ const test = base.extend< { pageObject: ProductFiltersPage } >( { test.describe( `${ blockData.name }`, () => { test.beforeEach( async ( { admin, requestUtils } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-frontend.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-frontend.block_theme.spec.ts index 8f79924b291..18ae6b3b80c 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-frontend.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/attribute-filter-frontend.block_theme.spec.ts @@ -24,9 +24,7 @@ const test = base.extend< { templateCompiler: TemplateCompiler } >( { test.describe( 'woocommerce/product-filter-attribute - Frontend', () => { test.describe( 'With default display style', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile( { attributes: { attributeId: 1, @@ -139,9 +137,7 @@ test.describe( 'woocommerce/product-filter-attribute - Frontend', () => { test.describe( 'With show counts enabled', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile( { attributes: { attributeId: 1, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/price-filter-frontend.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/price-filter-frontend.block_theme.spec.ts index 191c16f53f4..80c1f650a8e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/price-filter-frontend.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/price-filter-frontend.block_theme.spec.ts @@ -15,9 +15,7 @@ const test = base.extend< { templateCompiler: TemplateCompiler } >( { test.describe.skip( 'Product Filter: Price Filter Block', () => { test.describe( 'frontend', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile(); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts index 900ad03f6ca..0945e129b5a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts @@ -47,9 +47,7 @@ const test = base.extend< { pageObject: ProductFiltersPage } >( { test.describe( `${ blockData.name }`, () => { test.beforeEach( async ( { admin, requestUtils } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/rating-filter-frontend.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/rating-filter-frontend.block_theme.spec.ts index 272aeb4966f..e4f2ea8b680 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/rating-filter-frontend.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/rating-filter-frontend.block_theme.spec.ts @@ -15,9 +15,7 @@ const test = base.extend< { templateCompiler: TemplateCompiler } >( { test.describe.skip( 'Product Filter: Rating Filter Block', () => { test.describe( 'frontend', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile( { attributes: { attributeId: 1, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/stock-status-frontend.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/stock-status-frontend.block_theme.spec.ts index 4012ea324af..46ee9d7c09f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/stock-status-frontend.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/stock-status-frontend.block_theme.spec.ts @@ -15,9 +15,7 @@ const test = base.extend< { templateCompiler: TemplateCompiler } >( { test.describe.skip( 'Product Filter: Stock Status Block', () => { test.describe( 'With default display style', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile(); } ); @@ -109,9 +107,7 @@ test.describe.skip( 'Product Filter: Stock Status Block', () => { test.describe( 'With dropdown display style', () => { test.beforeEach( async ( { requestUtils, templateCompiler } ) => { - await requestUtils.activatePlugin( - 'woocommerce-blocks-test-enable-experimental-features' - ); + await requestUtils.setFeatureFlag( 'experimental-blocks', true ); await templateCompiler.compile( { attributes: { displayStyle: 'dropdown', diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/feature-flag.ts b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/feature-flag.ts new file mode 100644 index 00000000000..ec45c36a010 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/feature-flag.ts @@ -0,0 +1,25 @@ +/** + * Internal dependencies + */ +import type { RequestUtils } from './index'; + +export async function setFeatureFlag( + this: RequestUtils, + flag: string, + value: boolean +) { + return this.rest( { + method: 'POST', + path: '/e2e-feature-flags/update', + data: { [ flag ]: value }, + failOnStatusCode: true, + } ); +} + +export async function resetFeatureFlag( this: RequestUtils ) { + return this.rest( { + method: 'GET', + path: '/e2e-feature-flags/reset', + failOnStatusCode: true, + } ); +} diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts index e6129f1ab1f..b3b473eeb56 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts @@ -13,6 +13,7 @@ import { createTemplateFromFile, TemplateCompiler, } from './templates'; +import { resetFeatureFlag, setFeatureFlag } from './feature-flag'; export class RequestUtils extends CoreRequestUtils { /** @borrows getTemplates as this.getTemplates */ @@ -25,6 +26,10 @@ export class RequestUtils extends CoreRequestUtils { /** @borrows createTemplateFromFile as this.createTemplateFromFile */ createTemplateFromFile: typeof createTemplateFromFile = createTemplateFromFile.bind( this ); + /** @borrows setFeatureFlag as this.setFeatureFlag */ + setFeatureFlag: typeof setFeatureFlag = setFeatureFlag.bind( this ); + /** @borrows resetFeatureFlag as this.resetFeatureFlag */ + resetFeatureFlag: typeof resetFeatureFlag = resetFeatureFlag.bind( this ); } export { TemplateCompiler, PostCompiler }; diff --git a/plugins/woocommerce/changelog/51950-update-21774-promotions-async-twicedaily b/plugins/woocommerce/changelog/51950-update-21774-promotions-async-twicedaily new file mode 100644 index 00000000000..a6a5aa11bba --- /dev/null +++ b/plugins/woocommerce/changelog/51950-update-21774-promotions-async-twicedaily @@ -0,0 +1,4 @@ +Significance: patch +Type: tweak +Comment: Increases frequency of cron job from daily to twice daily. + diff --git a/plugins/woocommerce/changelog/52427-dev-introducing-order-status-legacy-constants b/plugins/woocommerce/changelog/52427-dev-introducing-order-status-legacy-constants new file mode 100644 index 00000000000..f29ca10c0f6 --- /dev/null +++ b/plugins/woocommerce/changelog/52427-dev-introducing-order-status-legacy-constants @@ -0,0 +1,4 @@ +Significance: minor +Type: dev + +Adds constants for all legacy order statuses to centralize them, reduce typos, improve code strictness, ease status lookups, and enhance documentation. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52475-update-34731-remove-coupon-note b/plugins/woocommerce/changelog/52475-update-34731-remove-coupon-note new file mode 100644 index 00000000000..0d0b33e62b0 --- /dev/null +++ b/plugins/woocommerce/changelog/52475-update-34731-remove-coupon-note @@ -0,0 +1,4 @@ +Significance: patch +Type: enhancement + +Removed CouponPageMoved class. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52476-52012-unicode-control-characters-not-correctly-filtered b/plugins/woocommerce/changelog/52476-52012-unicode-control-characters-not-correctly-filtered new file mode 100644 index 00000000000..dda06a9ed75 --- /dev/null +++ b/plugins/woocommerce/changelog/52476-52012-unicode-control-characters-not-correctly-filtered @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Prevented phone numbers containing Unicode control characters from failing validation during Checkout. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52501-add-settings-sidebar b/plugins/woocommerce/changelog/52501-add-settings-sidebar new file mode 100644 index 00000000000..714550edd2d --- /dev/null +++ b/plugins/woocommerce/changelog/52501-add-settings-sidebar @@ -0,0 +1,4 @@ +Significance: patch +Type: tweak +Comment: Adds layout to Settings, which is unreleased. + diff --git a/plugins/woocommerce/changelog/52503-dev-experimental-disable-product-descriptions b/plugins/woocommerce/changelog/52503-dev-experimental-disable-product-descriptions new file mode 100644 index 00000000000..457b638494a --- /dev/null +++ b/plugins/woocommerce/changelog/52503-dev-experimental-disable-product-descriptions @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +[Experimental] Allow disabling product descriptions in the product summary. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52523-dev-improve-import-sample-products-test b/plugins/woocommerce/changelog/52523-dev-improve-import-sample-products-test new file mode 100644 index 00000000000..1a4da4ce1f0 --- /dev/null +++ b/plugins/woocommerce/changelog/52523-dev-improve-import-sample-products-test @@ -0,0 +1,4 @@ +Significance: patch +Type: performance + +Optimize `test_import_sample_products` unit test performance \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52573-fix-hide-stepper-layout-feature-flag b/plugins/woocommerce/changelog/52573-fix-hide-stepper-layout-feature-flag new file mode 100644 index 00000000000..3d9b4d0d350 --- /dev/null +++ b/plugins/woocommerce/changelog/52573-fix-hide-stepper-layout-feature-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: dev + +Add To Cart With Options - Stepper layout: implement feature under feature flag \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52578-show-payment-method-in-text b/plugins/woocommerce/changelog/52578-show-payment-method-in-text new file mode 100644 index 00000000000..e1434331d7e --- /dev/null +++ b/plugins/woocommerce/changelog/52578-show-payment-method-in-text @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Show the payment method as text if there's no brand or last4 digits are present. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/52603-dev-shipping-methods-50558 b/plugins/woocommerce/changelog/52603-dev-shipping-methods-50558 new file mode 100644 index 00000000000..05ccc4539ef --- /dev/null +++ b/plugins/woocommerce/changelog/52603-dev-shipping-methods-50558 @@ -0,0 +1,4 @@ +Significance: minor +Type: tweak + +Checkout: Adjust styling and wording of "No delivery address" and "No shipping option" messages. \ No newline at end of file diff --git a/plugins/woocommerce/changelog/add-tracks-role-prop b/plugins/woocommerce/changelog/add-tracks-role-prop new file mode 100644 index 00000000000..52376790c98 --- /dev/null +++ b/plugins/woocommerce/changelog/add-tracks-role-prop @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Add global prop to Tracks events for user role diff --git a/plugins/woocommerce/changelog/chore-remove-filter-overlay-blocks b/plugins/woocommerce/changelog/chore-remove-filter-overlay-blocks new file mode 100644 index 00000000000..46f988eb89f --- /dev/null +++ b/plugins/woocommerce/changelog/chore-remove-filter-overlay-blocks @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: Experimental: Remove filter overlay blocks. + + diff --git a/plugins/woocommerce/changelog/e2e-fix-font-weight-combobox-locator-wp6.7 b/plugins/woocommerce/changelog/e2e-fix-font-weight-combobox-locator-wp6.7 new file mode 100644 index 00000000000..e2647026302 --- /dev/null +++ b/plugins/woocommerce/changelog/e2e-fix-font-weight-combobox-locator-wp6.7 @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +E2E tests: updated locator to work with WP6.7 diff --git a/plugins/woocommerce/changelog/e2e-remove-http-response-check-on-editor-navigation b/plugins/woocommerce/changelog/e2e-remove-http-response-check-on-editor-navigation new file mode 100644 index 00000000000..1e94f739038 --- /dev/null +++ b/plugins/woocommerce/changelog/e2e-remove-http-response-check-on-editor-navigation @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +E2E tests: update utils to not wait for http reponse when navigating to editor page diff --git a/plugins/woocommerce/changelog/fix-42090-payment-shipping-empty-states b/plugins/woocommerce/changelog/fix-42090-payment-shipping-empty-states new file mode 100644 index 00000000000..904d2d8aaec --- /dev/null +++ b/plugins/woocommerce/changelog/fix-42090-payment-shipping-empty-states @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Added placeholder in the checkout block editor when payment methods are not configured diff --git a/plugins/woocommerce/changelog/fix-52308-payment-info-in-email b/plugins/woocommerce/changelog/fix-52308-payment-info-in-email new file mode 100644 index 00000000000..e58046833d9 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-52308-payment-info-in-email @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Include the last 4 digits of a payment card in the order details shown to customers when the info is available diff --git a/plugins/woocommerce/changelog/fix-52617-stop-using-__experimentalGetTemplateForLink b/plugins/woocommerce/changelog/fix-52617-stop-using-__experimentalGetTemplateForLink new file mode 100644 index 00000000000..eb84d2874a9 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-52617-stop-using-__experimentalGetTemplateForLink @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +Fix CYS error with latest Gutenberg nightly builds diff --git a/plugins/woocommerce/changelog/fix-pattern-images b/plugins/woocommerce/changelog/fix-pattern-images new file mode 100644 index 00000000000..8c2788e6d28 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-pattern-images @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Patterns: Remove broken Product Hero 2 Column 2 Row pattern diff --git a/plugins/woocommerce/changelog/fix-rating-filter-minor-issues b/plugins/woocommerce/changelog/fix-rating-filter-minor-issues new file mode 100644 index 00000000000..a5afe34ba16 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-rating-filter-minor-issues @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Experimental: Rating filter: fix block focus and visibility + + diff --git a/plugins/woocommerce/changelog/refactor-checkout-shipping-total-components b/plugins/woocommerce/changelog/refactor-checkout-shipping-total-components new file mode 100644 index 00000000000..ce81a3f6509 --- /dev/null +++ b/plugins/woocommerce/changelog/refactor-checkout-shipping-total-components @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Updated cart and checkout shipping totals to show more clearly delivery vs collection, and updates calculator button behaviour diff --git a/plugins/woocommerce/changelog/update-cys-edit-site-classnames b/plugins/woocommerce/changelog/update-cys-edit-site-classnames new file mode 100644 index 00000000000..00df32860b1 --- /dev/null +++ b/plugins/woocommerce/changelog/update-cys-edit-site-classnames @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +Update CYS class names to avoid conflicts with future updates of Gutenberg or WordPress diff --git a/plugins/woocommerce/changelog/update-fix-product-categories-list-settings-sidebar-layout b/plugins/woocommerce/changelog/update-fix-product-categories-list-settings-sidebar-layout new file mode 100644 index 00000000000..a193bfe673c --- /dev/null +++ b/plugins/woocommerce/changelog/update-fix-product-categories-list-settings-sidebar-layout @@ -0,0 +1,4 @@ +Significance: patch +Type: tweak + +Fix visual issue in the Display Style of the Product Categories List block diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/block-editor-container.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/block-editor-container.tsx index 9bc29e8745b..f6b406810e6 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/block-editor-container.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/block-editor-container.tsx @@ -38,14 +38,10 @@ import { useIsActiveNewNeutralVariation } from './hooks/use-is-active-new-neutra export const BlockEditorContainer = () => { const settings = useSiteEditorSettings(); - const currentTemplate: - | { - id: string; - } - | undefined = useSelect( + const currentTemplateId: string | undefined = useSelect( ( select ) => // @ts-expect-error No types for this exist yet. - select( coreStore ).__experimentalGetTemplateForLink( '/' ), + select( coreStore ).getDefaultTemplateId( { slug: 'home' } ), [] ); @@ -61,7 +57,7 @@ export const BlockEditorContainer = () => { const [ blocks, , onChange ] = useEditorBlocks( templateType, - currentTemplate?.id ?? '' + currentTemplateId || '' ); const urlParams = useQuery(); diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/editor.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/editor.tsx index 93920c3f71f..9e29294f8ba 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/editor.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/editor.tsx @@ -77,7 +77,7 @@ export const Editor = ( { isLoading }: { isLoading: boolean } ) => { enableRegionNavigation={ false } className={ clsx( 'woocommerce-customize-store__edit-site-editor', - 'edit-site-editor__interface-skeleton', + 'woocommerce-edit-site-editor__interface-skeleton', { 'show-icon-labels': false, 'is-loading': isLoading, diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_breakpoints.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_breakpoints.scss new file mode 100644 index 00000000000..a68a1b9f0ac --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_breakpoints.scss @@ -0,0 +1 @@ +$break-medium: 782px; diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_mixins.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_mixins.scss new file mode 100644 index 00000000000..db0a80b0773 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_mixins.scss @@ -0,0 +1,31 @@ +@import "_breakpoints.scss"; + +@mixin break-medium() { + @media (min-width: #{ ($break-medium) }) { + @content; + } +} + +/** + * Allows users to opt-out of animations via OS-level preferences. + */ +@mixin reduce-motion($property: "") { + @if $property =="transition" { + @media (prefers-reduced-motion: reduce) { + transition-duration: 0s; + transition-delay: 0s; + } + } @else if $property =="animation" { + @media (prefers-reduced-motion: reduce) { + animation-duration: 1ms; + animation-delay: 0s; + } + } @else { + @media (prefers-reduced-motion: reduce) { + transition-duration: 0s; + transition-delay: 0s; + animation-duration: 1ms; + animation-delay: 0s; + } + } +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_variables.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_variables.scss new file mode 100644 index 00000000000..9877ddf7e39 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/_variables.scss @@ -0,0 +1,24 @@ +$font-line-height-x-large: 32px; + +$grid-unit: 8px; +$grid-unit-05: 0.5 * $grid-unit; // 4px +$grid-unit-10: 1 * $grid-unit; // 8px +$grid-unit-15: 1.5 * $grid-unit; // 12px +$grid-unit-20: 2 * $grid-unit; // 16px +$grid-unit-40: 4 * $grid-unit; // 32px +$grid-unit-60: 6 * $grid-unit; // 48px +$grid-unit-70: 7 * $grid-unit; // 56px +$grid-unit-80: 8 * $grid-unit; // 64px + +$radius-medium: 4px; +$radius-large: 8px; + +$elevation-x-small: 0 1px 1px rgba($black, 0.03), 0 1px 2px rgba($black, 0.02), 0 3px 3px rgba($black, 0.02), 0 4px 4px rgba($black, 0.01); +$elevation-large: 0 5px 15px rgba($black, 0.08), 0 15px 27px rgba($black, 0.07), 0 30px 36px rgba($black, 0.04), 0 50px 43px rgba($black, 0.02); +$nav-sidebar-width: 300px; +$header-height: 60px; +$canvas-padding: $grid-unit-20; + +$sidebar-width: 280px; + +$border-width: 1px; diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/layout.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/layout.scss new file mode 100644 index 00000000000..7b7a2526543 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/layout.scss @@ -0,0 +1,272 @@ +// This is a copy of the Gutenberg styles with the selectors modified. +// Also, some z-index properties have been removed for simplicity. +// https://github.com/WordPress/gutenberg/blob/8aa998526984a3e9d547cd638840f8314bad9d81/packages/edit-site/src/components/layout/style.scss +// See https://github.com/woocommerce/woocommerce/issues/48377 +@import "_variables.scss"; +@import "_mixins.scss"; + +.woocommerce-edit-site-layout { + height: 100%; + background: $gray-900; + color: $gray-400; + display: flex; + flex-direction: column; + + // Show a dark background in "frame" mode to avoid edge artifacts. + &:not(.is-full-canvas) .editor-visual-editor { + background: $gray-900; + } +} + +.woocommerce-edit-site-layout__content { + height: 100%; + flex-grow: 1; + display: flex; +} + +.woocommerce-edit-site-layout__sidebar-region { + width: 100vw; + flex-shrink: 0; + + @include break-medium { + width: $nav-sidebar-width; + } + + // This is only necessary for the exit animation + .woocommerce-edit-site-layout.is-full-canvas & { + position: fixed !important; + height: 100vh; + left: 0; + top: 0; + } + + .woocommerce-edit-site-layout__sidebar { + display: flex; + flex-direction: column; + height: 100%; + } + + .resizable-editor__drag-handle { + right: 0; + } +} + +.woocommerce-edit-site-layout__main { + flex-grow: 1; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.woocommerce-edit-site-layout__mobile { + position: relative; + width: 100%; + + /* + * The SiteHubMobile component is displayed + * for pages that do not have a sidebar, + * yet it needs the Sidebar component for the React context. + * + * This removes the padding in this scenario. + * See https://github.com/WordPress/gutenberg/pull/63118 + */ + .woocommerce-edit-site-sidebar__screen-wrapper { + padding: 0; + } +} + +.woocommerce-edit-site-layout__canvas-container { + position: relative; + flex-grow: 1; + // When animating the frame size can exceed its container size. + overflow: visible; + + &.is-resizing::after { + // This covers the whole content which ensures mouse up triggers + // even if the content is "inert". + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ""; + } +} + +.woocommerce-edit-site-layout__canvas { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + + &.is-right-aligned { + justify-content: flex-end; + } + + .woocommerce-edit-site-resizable-frame__inner { + color: $gray-900; + } + + @include break-medium { + top: $canvas-padding; + bottom: $canvas-padding; + width: calc(100% - #{$canvas-padding}); + + .woocommerce-edit-site-resizable-frame__inner-content { + box-shadow: $elevation-x-small; + transition: border-radius, box-shadow 0.4s; + // This ensure the radius work properly. + overflow: hidden; + + .woocommerce-edit-site-layout:not(.is-full-canvas) & { + border-radius: $radius-large; + } + + &:hover { + box-shadow: $elevation-large; + } + } + } + + .woocommerce-edit-site-layout.is-full-canvas & { + top: 0; + bottom: 0; + width: 100%; + } +} + +// This shouldn't be necessary (we should have a way to say that a skeletton is relative +.woocommerce-edit-site-layout__mobile .interface-interface-skeleton, +.woocommerce-edit-site-layout__canvas .interface-interface-skeleton, +.woocommerce-edit-site-template-pages-preview .interface-interface-skeleton { + position: relative !important; + min-height: 100% !important; +} + +.woocommerce-edit-site-template-pages-preview { + height: 100%; +} + +/* stylelint-disable -- Disable reason: View Transitions not supported properly by stylelint. */ +html.canvas-mode-edit-transition::view-transition-group(toggle) { + animation-delay: 255ms; +} + +@media (prefers-reduced-motion) { + + ::view-transition-group(*), + ::view-transition-old(*), + ::view-transition-new(*) { + animation: none !important; + } +} + +/* stylelint-enable */ + +.woocommerce-edit-site-layout.is-full-canvas .woocommerce-edit-site-layout__sidebar-region .woocommerce-edit-site-layout__view-mode-toggle { + display: none; +} + +.woocommerce-edit-site-layout__view-mode-toggle.components-button { + /* stylelint-disable -- Disable reason: View Transitions not supported properly by stylelint. */ + view-transition-name: toggle; + /* stylelint-enable */ + position: relative; + color: $white; + height: $header-height; + width: $header-height; + overflow: hidden; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background: $gray-900; + border-radius: 0; + + &:hover, + &:active { + color: $white; + } + + &:focus-visible, + &:focus { + box-shadow: 0 0 0 3px #1e1e1e, 0 0 0 6px var(--wp-admin-theme-color); + outline: 4px solid #0000; + outline-offset: 4px; + } + + &::before { + transition: box-shadow 0.1s ease; + @include reduce-motion("transition"); + content: ""; + display: block; + position: absolute; + top: 9px; + right: 9px; + bottom: 9px; + left: 9px; + border-radius: $radius-medium; + box-shadow: none; + } + + .woocommerce-edit-site-layout__view-mode-toggle-icon { + display: flex; + height: $header-height; + width: $header-height; + justify-content: center; + align-items: center; + } +} + +.woocommerce-edit-site-layout__actions { + position: fixed !important; // Need to override the default relative positioning + top: -9999em; + bottom: auto; + left: auto; + right: 0; + width: $sidebar-width; + color: $gray-900; + background: $white; + + &:focus, + &:focus-within { + top: auto; + bottom: 0; + } + + &.is-entity-save-view-open { + + &:focus, + &:focus-within { + top: 0; + } + } + + @include break-medium { + border-left: $border-width solid $gray-300; + } +} + +.woocommerce-edit-site-layout__area { + flex-grow: 1; + margin: 0; + overflow: hidden; + box-shadow: $elevation-x-small; + + @include break-medium() { + border-radius: 8px; + margin: $canvas-padding $canvas-padding $canvas-padding 0; + } +} + +.woocommerce-edit-site .components-editor-notices__snackbar { + position: fixed; + right: 0; + bottom: 16px; + padding-left: 16px; + padding-right: 16px; +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/resizable-frame.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/resizable-frame.scss new file mode 100644 index 00000000000..73bdd8195de --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/resizable-frame.scss @@ -0,0 +1,76 @@ +// This is a copy of the Gutenberg styles with the selectors modified. +// https://github.com/WordPress/gutenberg/blob/8aa998526984a3e9d547cd638840f8314bad9d81/packages/edit-site/src/components/resizable-frame/style.scss +// See https://github.com/woocommerce/woocommerce/issues/48377 +@import "_variables.scss"; + +.woocommerce-edit-site-resizable-frame__inner { + position: relative; + + &.is-resizing { + @at-root { + body:has(&) { + cursor: col-resize; + user-select: none; + -webkit-user-select: none; + } + } + + &::before { + // This covers the whole content which ensures mouse up triggers + // even if the content is "inert". + position: absolute; + z-index: 1; + inset: 0; + content: ""; + } + } +} + +.woocommerce-edit-site-resizable-frame__inner-content { + position: absolute; + z-index: 0; + inset: 0; +} + +.woocommerce-edit-site-resizable-frame__handle { + align-items: center; + background-color: rgba($gray-700, 0.4); + border: 0; + border-radius: $grid-unit-05; + cursor: col-resize; + display: flex; + height: $grid-unit-80; + justify-content: flex-end; + padding: 0; + position: absolute; + top: calc(50% - #{$grid-unit-40}); + width: $grid-unit-05; + z-index: 100; + + &::before { + content: ""; + height: 100%; + left: 100%; + position: absolute; + width: $grid-unit-40; + } + + &::after { + content: ""; + height: 100%; + position: absolute; + right: 100%; + width: $grid-unit-40; + } + + &:focus-visible { + // Works with Windows high contrast mode while also hiding weird outline in Safari. + outline: 2px solid transparent; + } + + &:hover, + &:focus, + &.is-resizing { + background-color: var(--wp-admin-theme-color); + } +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/save-hub.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/save-hub.scss new file mode 100644 index 00000000000..fb546bb2246 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/save-hub.scss @@ -0,0 +1,34 @@ +// This is a copy of the Gutenberg styles with the selectors modified. +// https://github.com/WordPress/gutenberg/blob/8aa998526984a3e9d547cd638840f8314bad9d81/packages/edit-site/src/components/save-hub/style.scss +// See https://github.com/woocommerce/woocommerce/issues/48377 +@import "_variables.scss"; + +.woocommerce-edit-site-save-hub { + color: $gray-600; + border-top: 1px solid $gray-800; + flex-shrink: 0; + margin: 0; + padding: $grid-unit-20 $canvas-padding; +} + +.woocommerce-edit-site-save-hub__button { + color: inherit; + width: 100%; + justify-content: center; + + &[aria-disabled="true"] { + opacity: 1; + } + + &[aria-disabled="true"]:hover { + color: inherit; + } + + &:not(.is-primary) { + + &.is-busy, + &.is-busy[aria-disabled="true"]:hover { + color: $gray-900; + } + } +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/sidebar-navigation-screen.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/sidebar-navigation-screen.scss new file mode 100644 index 00000000000..eb24cea6b80 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/sidebar-navigation-screen.scss @@ -0,0 +1,170 @@ +// This is a copy of the Gutenberg styles with the selectors modified. +// https://github.com/WordPress/gutenberg/blob/8aa998526984a3e9d547cd638840f8314bad9d81/packages/edit-site/src/components/sidebar-navigation-screen/style.scss +// See https://github.com/woocommerce/woocommerce/issues/48377 +@import "_variables.scss"; + +.woocommerce-edit-site-sidebar-navigation-screen { + display: flex; + flex-direction: column; + overflow-x: unset !important; + position: relative; +} + +.woocommerce-edit-site-sidebar-navigation-screen__main { + // Ensure the sidebar is always at least as tall as the viewport. + // This allows the footer section to be sticky at the bottom of the viewport. + flex-grow: 1; + margin-bottom: $grid-unit-20; + + &.has-footer { + margin-bottom: 0; + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__content { + padding: 0 $grid-unit-20; + + .components-item-group { + margin-left: -$grid-unit-20; + margin-right: -$grid-unit-20; + } + + .components-text { + color: $gray-400; + } + + .components-heading { + margin-bottom: $grid-unit-10; + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__meta { + margin: 0 0 $grid-unit-20 $grid-unit-20; + color: $gray-400; + + .components-text { + color: $gray-400; + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__page-link { + color: $gray-600; + display: inline-block; + word-break: break-word; + + &:hover, + &:focus { + color: $white; + } + + .components-external-link__icon { + margin-left: $grid-unit-05; + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__title-icon { + position: sticky; + top: 0; + background: $gray-900; + padding-top: $grid-unit-60; + margin-bottom: $grid-unit-10; + padding-bottom: $grid-unit-10; +} + +.woocommerce-edit-site-sidebar-navigation-screen__title { + flex-grow: 1; + overflow-wrap: break-word; + + &#{&}, + &#{&} .woocommerce-edit-site-sidebar-navigation-screen__title { + line-height: $font-line-height-x-large; + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__actions { + display: flex; + flex-shrink: 0; +} + +.woocommerce-edit-site-sidebar-navigation-screen__content .woocommerce-edit-site-global-styles-variation-container { + @include break-medium() { + // Safari does not currently support `scrollbar-gutter: stable`, so at + // particular viewport sizes it's possible for previews to render prior to a + // scrollbar appearing. This then causes a scrollbar to appear, which reduces + // the width of the container and can cause the preview's width to change. + // As a result, the preview can go into an endless loop of resizing, causing + // the preview elements to appear to "dance". A workaround is to provide a + // max-width for the container, which prevents the introduction of the scrollbar + // from causing the preview's width to change. + // See: https://github.com/WordPress/gutenberg/issues/55112 + max-width: 292px; + } +} + +.woocommerce-edit-site-global-styles-variation-title { + color: $gray-300; + font-size: 11px; + text-transform: uppercase; + font-weight: 500; +} + +.woocommerce-edit-site-sidebar-navigation-screen__content .woocommerce-edit-site-global-styles-variations_item { + + // Use a white outline to provide contrast with the dark background. + .woocommerce-edit-site-global-styles-variations_item-preview { + outline-color: rgba($white, 0.05); + } + + &:not(.is-active):hover .woocommerce-edit-site-global-styles-variations_item-preview { + outline-color: rgba($white, 0.15); + } + + &.is-active .woocommerce-edit-site-global-styles-variations_item-preview { + outline-color: $white; + } + + &:focus-visible .woocommerce-edit-site-global-styles-variations_item-preview { + outline-color: var(--wp-admin-theme-color); + } +} + +.woocommerce-edit-site-sidebar-navigation-screen__footer { + position: sticky; + bottom: 0; + background-color: $gray-900; + gap: 0; + padding: $grid-unit-20 0; + margin: $grid-unit-20 0 0; + border-top: 1px solid $gray-800; +} + +/* In general style overrides are discouraged. + * This is a temporary solution to override the InputControl component's styles. + * The `Theme` component will potentially be the more appropriate approach + * once that component is stabilized. + * See: packages/components/src/theme + */ +.woocommerce-edit-site-sidebar-navigation-screen__input-control { + width: 100%; + + .components-input-control__container { + background: $gray-800; + + .components-button { + color: $gray-200 !important; + } + } + + .components-input-control__input { + color: $gray-200 !important; + background: $gray-800 !important; + } + + .components-input-control__backdrop { + border: 4px !important; + } + + .components-base-control__help { + color: $gray-600; + } +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/site-hub.scss b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/site-hub.scss new file mode 100644 index 00000000000..ff29f4a9f7a --- /dev/null +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/gutenberg-styles/site-hub.scss @@ -0,0 +1,93 @@ +// This is a copy of the Gutenberg styles with the selectors modified. +// https://github.com/WordPress/gutenberg/blob/8aa998526984a3e9d547cd638840f8314bad9d81/packages/edit-site/src/components/site-hub/style.scss +// See https://github.com/woocommerce/woocommerce/issues/48377 +@import "_variables.scss"; + +.woocommerce-edit-site-site-hub { + display: flex; + align-items: center; + justify-content: space-between; + gap: $grid-unit-10; + margin-right: $grid-unit-15; + height: $grid-unit-70; +} + +.woocommerce-edit-site-site-hub__actions { + flex-shrink: 0; +} + +.woocommerce-edit-site-site-hub__view-mode-toggle-container { + height: $header-height; + width: $header-height; + flex-shrink: 0; + + &.has-transparent-background .woocommerce-edit-site-layout__view-mode-toggle-icon { + background: transparent; + } +} + +.woocommerce-edit-site-site-hub__title .components-button { + color: $gray-200; + display: block; + flex-grow: 1; + font-size: 15px; + font-weight: 500; + overflow: hidden; + // Add space for the ↗ to render. + padding-right: $grid-unit-20; + + // Create 12px gap between site icon and site title + margin-left: - $grid-unit-05; + position: relative; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + + &:hover, + &:focus, + &:active { + color: $gray-200; + } + + &:focus { + // Defer to :focus-visible below. + box-shadow: none; + outline: none; + } + + &:focus-visible { + // Push the shadow away from the title. + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $gray-900, 0 0 0 calc(2 * var(--wp-admin-border-width-focus)) var(--wp-admin-theme-color); + + // Windows High Contrast mode will show this outline, but not the box-shadow. + outline: 2px solid transparent; + outline-offset: 2px; + } + + &::after { + content: "\2197"; + font-weight: 400; + opacity: 0; + position: absolute; + right: 0; + transition: opacity 0.1s linear; + @include reduce-motion("transition"); + } + + &:hover::after, + &:focus::after, + &:active::after { + opacity: 1; + } +} + +.woocommerce-edit-site-site-hub_toggle-command-center { + color: $gray-200; + + &:hover, + &:active { + svg { + fill: $gray-100; + } + } +} diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-insert-pattern.ts b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-insert-pattern.ts index b8b231836fd..f25f4341108 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-insert-pattern.ts +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-insert-pattern.ts @@ -27,16 +27,16 @@ import { trackEvent } from '../../tracking'; export const useInsertPattern = () => { const isActiveNewNeutralVariation = useIsActiveNewNeutralVariation(); - const currentTemplate = useSelect( + const currentTemplateId: string | undefined = useSelect( ( sel ) => // @ts-expect-error No types for this exist yet. - sel( coreStore ).__experimentalGetTemplateForLink( '/' ), + sel( coreStore ).getDefaultTemplateId( { slug: 'home' } ), [] ); const [ blocks ] = useEditorBlocks( 'wp_template', - currentTemplate?.id ?? '' + currentTemplateId || '' ); const insertedPatternRef = useRef< string | null >( null ); diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-selected-pattern.ts b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-selected-pattern.ts index 5fdf08d46f6..7d95f128dfb 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-selected-pattern.ts +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/hooks/use-selected-pattern.ts @@ -9,7 +9,7 @@ import { useEffect, useState } from '@wordpress/element'; import { PatternWithBlocks } from '~/customize-store/types/pattern'; export const useSelectedPattern = ( - patternSelector = '.edit-site-sidebar-navigation-screen__content .block-editor-block-patterns-list__item' + patternSelector = '.woocommerce-edit-site-sidebar-navigation-screen__content .block-editor-block-patterns-list__item' ) => { const [ selectedPattern, setSelectedPattern ] = useState< PatternWithBlocks >(); diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/layout.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/layout.tsx index 489329614f5..b1a1c6e54ad 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/layout.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/layout.tsx @@ -54,6 +54,7 @@ import { isOfflineAIFlow } from '../guards'; import { isWooExpress } from '~/utils/is-woo-express'; import { trackEvent } from '../tracking'; import { SidebarNavigationExtraScreen } from './sidebar/navigation-extra-screen/sidebar-navigation-extra-screen'; +import './gutenberg-styles/layout.scss'; const { useGlobalStyle } = unlock( blockEditorPrivateApis ); @@ -157,9 +158,11 @@ export const Layout = () => { type={ templateType } id={ templateId } > -
+
{ view: { x: 0 }, } } isTransparent={ false } - className="edit-site-layout__hub" + className="woocommerce-edit-site-layout__hub" /> -
-
+
+
{ : ANIMATION_DURATION, ease: 'easeOut', } } - className="edit-site-layout__sidebar" + className="woocommerce-edit-site-layout__sidebar" > @@ -201,14 +204,14 @@ export const Layout = () => {
{ ! isMobileViewport && ( -
+
{ canvasResizer } { !! canvasSize.width && ( diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx index 2e9ad3f603c..090498a39ba 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx @@ -198,7 +198,7 @@ export const OnboardingTour = ( { steps: [ { referenceElements: { - desktop: `.edit-site-layout__canvas-container`, + desktop: `.woocommerce-edit-site-layout__canvas-container`, }, meta: { name: 'view-changes-real-time', @@ -216,7 +216,7 @@ export const OnboardingTour = ( { }, { referenceElements: { - desktop: `.edit-site-layout__sidebar-region`, + desktop: `.woocommerce-edit-site-layout__sidebar-region`, }, meta: { name: 'make-your-store-your-own', diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/resizable-frame.jsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/resizable-frame.jsx index e2b5f2bde26..7b8c957d26b 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/resizable-frame.jsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/resizable-frame.jsx @@ -15,6 +15,11 @@ import { import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import './gutenberg-styles/resizable-frame.scss'; + // Removes the inline styles in the drag handles. const HANDLE_STYLES_OVERRIDE = { position: undefined, @@ -90,7 +95,7 @@ function ResizableFrame( { const frameRef = useRef( null ); const resizableHandleHelpId = useInstanceId( ResizableFrame, - 'edit-site-resizable-frame-handle-help' + 'woocommerce-edit-site-resizable-frame-handle-help' ); const defaultAspectRatio = defaultSize.width / defaultSize.height; @@ -204,7 +209,7 @@ function ResizableFrame( { key="handle" role="separator" aria-orientation="vertical" - className={ clsx( 'edit-site-resizable-frame__handle', { + className={ clsx( 'woocommerce-edit-site-resizable-frame__handle', { 'is-resizing': isResizing, } ) } variants={ resizeHandleVariants } @@ -297,7 +302,7 @@ function ResizableFrame( { onResizeStart={ handleResizeStart } onResize={ handleResize } onResizeStop={ handleResizeStop } - className={ clsx( 'edit-site-resizable-frame__inner', { + className={ clsx( 'woocommerce-edit-site-resizable-frame__inner', { 'is-resizing': isResizing, } ) } > diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/pattern-screen/sidebar-pattern-screen.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/pattern-screen/sidebar-pattern-screen.tsx index 13a8b0862dc..7783832b2ad 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/pattern-screen/sidebar-pattern-screen.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/pattern-screen/sidebar-pattern-screen.tsx @@ -108,16 +108,16 @@ export const SidebarPatternScreen = ( { category }: { category: string } ) => { const refElement = useRef< HTMLDivElement >( null ); - const currentTemplate = useSelect( + const currentTemplateId: string | undefined = useSelect( ( sel ) => // @ts-expect-error No types for this exist yet. - sel( coreStore ).__experimentalGetTemplateForLink( '/' ), + sel( coreStore ).getDefaultTemplateId( { slug: 'home' } ), [] ); const [ blocks ] = useEditorBlocks( 'wp_template', - currentTemplate?.id ?? '' + currentTemplateId || '' ); const isEditorLoading = useIsSiteEditorLoading(); diff --git a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx index 1b5ef141c39..04a43a7f5af 100644 --- a/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx +++ b/plugins/woocommerce/client/admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx @@ -38,6 +38,7 @@ import { CustomizeStoreContext } from '../'; import { trackEvent } from '~/customize-store/tracking'; import { useEditorBlocks } from '../hooks/use-editor-blocks'; import { useIsNoBlocksPlaceholderPresent } from '../hooks/block-placeholder/use-is-no-blocks-placeholder-present'; +import '../gutenberg-styles/save-hub.scss'; const PUBLISH_ON_SAVE_ENTITIES = [ { @@ -52,20 +53,16 @@ export const SaveHub = () => { const { sendEvent } = useContext( CustomizeStoreContext ); const [ isResolving, setIsResolving ] = useState< boolean >( false ); - const currentTemplate: - | { - id: string; - } - | undefined = useSelect( + const currentTemplateId: string | undefined = useSelect( ( select ) => // @ts-expect-error No types for this exist yet. - select( coreStore ).__experimentalGetTemplateForLink( '/' ), + select( coreStore ).getDefaultTemplateId( { slug: 'home' } ), [] ); const [ blocks ] = useEditorBlocks( 'wp_template', - currentTemplate?.id ?? '' + currentTemplateId || '' ); const isNoBlocksPlaceholderPresent = @@ -173,14 +170,14 @@ export const SaveHub = () => { if ( isMainScreen ) { return (