woocommerce/plugins/woocommerce-blocks/packages/checkout/slot/index.js

121 lines
3.5 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import deprecated from '@wordpress/deprecated';
import {
createSlotFill as baseCreateSlotFill,
__experimentalUseSlot,
useSlot as __useSlot,
} from 'wordpress-components';
Move Block Type Settings into Block Type Classes (https://github.com/woocommerce/woocommerce-blocks/pull/4059) * BLOCK SETTINGS: Remove unused constants/settings * AssetDataRegistry: Helpers to check for settings that exist, and registering page ID/permalinks * Move checkout and cart block settings to checkout and cart blocktypes * Move isShippingCalculatorEnabled to cart block * Remove HAS_DARK_EDITOR_STYLE_SUPPORT and IS_SHIPPING_CALCULATOR_ENABLED in favour of getSetting * Move displayCartPricesIncludingTax to blocktypes, and implement getSetting * Move block settings to core settings and blocktypes * Fix namespace usage * Move review settings * move tag settings * Keep productCount in core data * Move min and default height * Improve storePages code * Move attributes to attribute filter block type * Move $word_count_type outside of settings array * Remove unneeded setting in preview data (shippingCostRequiresAddress) * Move min/max settings dependency from GridLayoutControl to Blocks themselves and use getSettings * DEFAULT_COLUMNS and ROWS to settings * Move product columns/rows to block types * Add grid settings to AllProducts block * Correct default rows * correct min rows default * Move hasDarkEditorStyleSupport * Move hideOutOfStockItems to block type settings * Move build settings to inline script dependency * Pass data through asset api and move restApiRoutes * Export all core settings as constants * Remove WORD_COUNT_TYPE from core settings * Move some other core settings to assets * Update constants * Make settings use TypeScript * Update CURRENT_USER_IS_ADMIN usage * WORD_COUNT_TYPE * REST_API_ROUTES * REVIEW_RATINGS_ENABLED and SHOW_AVATARS * Remove REVIEW_RATINGS_ENABLED and SHOW_AVATARS constants * Remove MIN_HEIGHT * Remove DEFAULT_HEIGHT * PLACEHOLDER_IMG_SRC * LIMIT_TAGS * HAS_PRODUCTS * HOME_URL * HAS_TAGS * COUPONS_ENABLED * SHIPPING_ENABLED * TAXES_ENABLED * DISPLAY_ITEMIZED_TAXES * SHIPPING_COST_REQUIRES_ADDRESS * SHIPPING_STATES and SHIPPING_COUNTRIES * STORE_PAGES * ALLOWED_COUNTRIES * ALLOWED_STATES * SHIPPING_METHODS_EXIST * PAYMENT_GATEWAY_SORT_ORDER * CHECKOUT_SHOW_LOGIN_REMINDER * CHECKOUT_ALLOWS_GUEST and CHECKOUT_ALLOWS_SIGNUP * ATTRIBUTES * DISPLAY_CART_PRICES_INCLUDING_TAX * DISPLAY_CART_PRICES_INCLUDING_TAX * update build for TS files * fix build dir * Move blocks build config params * Move placeholderImgSrc to core settings * Move rest api hydration hoc to shared hocs and provide it restApiRoutes directly to avoid asset data registration * Move wordCountType to abstract block * Remove WORD_COUNT_TYPE in favour of getSetting * Move IS_LARGE_CATALOG and PRODUCT_COUNT to abstract block type and use getSetting inline * Add wcBlocksConfig * fix tests * Remove unused $asset_data_registry * remove console.log * Move build settings to abstract block * Trigger build again * Move hydration back to regular hocs for compatibility with trunk (merge conflict) * Removed wcSharedHocsConfig * esc home url * Update search fixture * Update search snap * 40000 timeout * hasProducts -> productCount * Product Count is part of blocks config * update mocks * Use version comparison to determine if batching is enabled * Change isWpVersion * scrollTo button
2021-04-22 11:37:27 +00:00
import { CURRENT_USER_IS_ADMIN } from '@woocommerce/settings';
import { Children, cloneElement } from '@wordpress/element';
/**
* Internal dependencies
*/
import BlockErrorBoundary from '../components/error-boundary';
/**
* This function is used in case __experimentalUseSlot is removed and useSlot is not released, it tries to mock
* the return value of that slot.
*
* @return {Object} The hook mocked return, currently:
* fills, a null array of length 2.
*/
const mockedUseSlot = () => {
/**
* If we're here, it means useSlot was never graduated and __experimentalUseSlot is removed, so we should change our code.
*
*/
deprecated( '__experimentalUseSlot', {
plugin: 'woocommerce-gutenberg-products-block',
} );
// We're going to mock its value
return {
fills: new Array( 2 ),
};
};
/**
* Checks if this slot has any valid fills. A valid fill is one that isn't falsy.
*
* @param {Array} fills The list of fills to check for a valid one in.
* @return {boolean} True if this slot contains any valid fills.
*/
export const hasValidFills = ( fills ) =>
Array.isArray( fills ) && fills.filter( Boolean ).length > 0;
/**
* A hook that is used inside a slotFillProvider to return information on the a slot.
*
* @param {string} slotName The slot name to be hooked into.
* @return {Object} slot data.
*/
let useSlot;
if ( typeof __useSlot === 'function' ) {
useSlot = __useSlot;
} else if ( typeof __experimentalUseSlot === 'function' ) {
useSlot = __experimentalUseSlot;
} else {
useSlot = mockedUseSlot;
}
export { useSlot };
/**
* Abstracts @wordpress/components createSlotFill, wraps Fill in an error boundary and passes down fillProps.
*
* @param {string} slotName The generated slotName, based down to createSlotFill.
* @param {null|function(Element):Element} [onError] Returns an element to display the error if the current use is an admin.
*
* @return {Object} Returns a newly wrapped Fill and Slot.
*/
export const createSlotFill = ( slotName, onError = null ) => {
const { Fill: BaseFill, Slot: BaseSlot } = baseCreateSlotFill( slotName );
/**
* A Fill that will get rendered inside associate slot.
* If the code inside has a error, it would be caught ad removed.
* The error is only visible to admins.
*
* @param {Object} props Items props.
* @param {Array} props.children Children to be rendered.
*/
const Fill = ( { children } ) => (
<BaseFill>
{ ( fillProps ) =>
Children.map( children, ( fill ) => (
<BlockErrorBoundary
/* Returning null would trigger the default error display.
* Returning () => null would render nothing.
*/
renderError={
CURRENT_USER_IS_ADMIN ? onError : () => null
}
>
{ cloneElement( fill, fillProps ) }
</BlockErrorBoundary>
) )
}
</BaseFill>
);
/**
* A Slot that will get rendered inside our tree.
* This forces Slot to use the Portal implementation that allows events to be bubbled to react tree instead of dom tree.
*
* @param {Object} [props] Slot props.
* @param {string} props.className Class name to be used on slot.
* @param {Object} props.fillProps Props to be passed to fills.
* @param {Element|string} props.as Element used to render the slot, defaults to div.
*
*/
const Slot = ( props ) => <BaseSlot { ...props } bubblesVirtually />;
return {
Fill,
Slot,
};
};