@wordpress/block-library
Version:
Block library for the WordPress editor.
8 lines (7 loc) • 13.1 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/navigation/edit/overlay-template-part-selector.js"],
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useMemo, useState, useCallback } from '@wordpress/element';\nimport { useEntityRecords, store as coreStore } from '@wordpress/core-data';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport {\n\tSelectControl,\n\tButton,\n\tFlexBlock,\n\tFlexItem,\n\t__experimentalHStack as HStack,\n} from '@wordpress/components';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { decodeEntities } from '@wordpress/html-entities';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { plus } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { createTemplatePartId } from '../../template-part/edit/utils/create-template-part-id';\nimport useCreateOverlayTemplatePart from './use-create-overlay';\nimport DeletedOverlayWarning from './deleted-overlay-warning';\nimport { NAVIGATION_OVERLAY_TEMPLATE_PART_AREA } from '../constants';\n\n/**\n * Overlay Template Part Selector component.\n *\n * @param {Object} props Component props.\n * @param {string} props.overlay Currently selected overlay template part ID.\n * @param {Function} props.setAttributes Function to update block attributes.\n * @param {Function} props.onNavigateToEntityRecord Function to navigate to template part editor.\n * @return {JSX.Element} The overlay template part selector component.\n */\nexport default function OverlayTemplatePartSelector( {\n\toverlay,\n\tsetAttributes,\n\tonNavigateToEntityRecord,\n} ) {\n\tconst {\n\t\trecords: templateParts,\n\t\tisResolving,\n\t\thasResolved,\n\t} = useEntityRecords( 'postType', 'wp_template_part', {\n\t\tper_page: -1,\n\t} );\n\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\n\tconst currentTheme = useSelect(\n\t\t( select ) => select( coreStore ).getCurrentTheme()?.stylesheet,\n\t\t[]\n\t);\n\n\t// Track if we're currently creating a new overlay\n\tconst [ isCreating, setIsCreating ] = useState( false );\n\n\t// Filter template parts by overlay area\n\tconst overlayTemplateParts = useMemo( () => {\n\t\tif ( ! templateParts ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn templateParts.filter(\n\t\t\t( templatePart ) =>\n\t\t\t\ttemplatePart.area === NAVIGATION_OVERLAY_TEMPLATE_PART_AREA\n\t\t);\n\t}, [ templateParts ] );\n\n\t// Hook to create overlay template part\n\tconst createOverlayTemplatePart =\n\t\tuseCreateOverlayTemplatePart( overlayTemplateParts );\n\n\t// Find the selected template part to get its title\n\tconst selectedTemplatePart = useMemo( () => {\n\t\tif ( ! overlay || ! overlayTemplateParts ) {\n\t\t\treturn null;\n\t\t}\n\t\treturn overlayTemplateParts.find(\n\t\t\t( templatePart ) => templatePart.slug === overlay\n\t\t);\n\t}, [ overlay, overlayTemplateParts ] );\n\n\t// Build options for SelectControl\n\tconst options = useMemo( () => {\n\t\tconst baseOptions = [\n\t\t\t{\n\t\t\t\tlabel: __( 'None (default)' ),\n\t\t\t\tvalue: '',\n\t\t\t},\n\t\t];\n\n\t\tif ( ! hasResolved || isResolving ) {\n\t\t\treturn baseOptions;\n\t\t}\n\n\t\tconst templatePartOptions = overlayTemplateParts.map(\n\t\t\t( templatePart ) => {\n\t\t\t\tconst label = templatePart.title?.rendered\n\t\t\t\t\t? decodeEntities( templatePart.title.rendered )\n\t\t\t\t\t: templatePart.slug;\n\n\t\t\t\treturn {\n\t\t\t\t\tlabel,\n\t\t\t\t\tvalue: templatePart.slug,\n\t\t\t\t};\n\t\t\t}\n\t\t);\n\n\t\t// If an overlay is selected but not found in the list, add it as a \"missing\" option\n\t\tif ( overlay && ! selectedTemplatePart ) {\n\t\t\ttemplatePartOptions.unshift( {\n\t\t\t\tlabel: sprintf(\n\t\t\t\t\t/* translators: %s: Overlay slug. */\n\t\t\t\t\t__( '%s (missing)' ),\n\t\t\t\t\toverlay\n\t\t\t\t),\n\t\t\t\tvalue: overlay,\n\t\t\t} );\n\t\t}\n\n\t\treturn [ ...baseOptions, ...templatePartOptions ];\n\t}, [\n\t\toverlayTemplateParts,\n\t\thasResolved,\n\t\tisResolving,\n\t\toverlay,\n\t\tselectedTemplatePart,\n\t] );\n\n\tconst handleSelectChange = ( value ) => {\n\t\tsetAttributes( {\n\t\t\toverlay: value || undefined,\n\t\t} );\n\t};\n\n\tconst handleEditClick = () => {\n\t\tif (\n\t\t\t! overlay ||\n\t\t\t! selectedTemplatePart ||\n\t\t\t! onNavigateToEntityRecord\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Resolve the full template part ID using theme\n\t\t// Default to current theme if not set\n\t\tconst theme = selectedTemplatePart.theme || currentTheme;\n\t\tconst templatePartId = createTemplatePartId( theme, overlay );\n\n\t\tonNavigateToEntityRecord( {\n\t\t\tpostId: templatePartId,\n\t\t\tpostType: 'wp_template_part',\n\t\t} );\n\t};\n\n\tconst handleCreateOverlay = useCallback( async () => {\n\t\ttry {\n\t\t\tsetIsCreating( true );\n\n\t\t\tconst templatePart = await createOverlayTemplatePart();\n\n\t\t\tsetAttributes( {\n\t\t\t\toverlay: templatePart.slug,\n\t\t\t} );\n\n\t\t\t// Navigate to the new overlay for editing\n\t\t\t// Create the full ID using theme and slug\n\t\t\tif ( onNavigateToEntityRecord ) {\n\t\t\t\tconst theme = templatePart.theme || currentTheme;\n\t\t\t\tconst templatePartId = createTemplatePartId(\n\t\t\t\t\ttheme,\n\t\t\t\t\ttemplatePart.slug\n\t\t\t\t);\n\t\t\t\tonNavigateToEntityRecord( {\n\t\t\t\t\tpostId: templatePartId,\n\t\t\t\t\tpostType: 'wp_template_part',\n\t\t\t\t} );\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\t// Error handling pattern matches CreateTemplatePartModalContents.\n\t\t\t// See: packages/fields/src/components/create-template-part-modal/index.tsx\n\t\t\t// The 'unknown_error' code check ensures generic error codes don't show\n\t\t\t// potentially confusing technical messages, instead showing a user-friendly fallback.\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error &&\n\t\t\t\t'code' in error &&\n\t\t\t\terror.message &&\n\t\t\t\terror.code !== 'unknown_error'\n\t\t\t\t\t? error.message\n\t\t\t\t\t: __( 'An error occurred while creating the overlay.' );\n\n\t\t\tcreateErrorNotice( errorMessage, { type: 'snackbar' } );\n\t\t} finally {\n\t\t\tsetIsCreating( false );\n\t\t}\n\t}, [\n\t\tcreateOverlayTemplatePart,\n\t\tsetAttributes,\n\t\tonNavigateToEntityRecord,\n\t\tcreateErrorNotice,\n\t\tcurrentTheme,\n\t] );\n\n\tconst handleClearOverlay = useCallback( () => {\n\t\tsetAttributes( { overlay: undefined } );\n\t}, [ setAttributes ] );\n\n\tconst isCreateButtonDisabled = isResolving || isCreating;\n\n\t// Check if the selected overlay is missing (deleted)\n\tconst isOverlayMissing = useMemo( () => {\n\t\treturn (\n\t\t\toverlay && hasResolved && ! isResolving && ! selectedTemplatePart\n\t\t);\n\t}, [ overlay, hasResolved, isResolving, selectedTemplatePart ] );\n\n\t// Build help text\n\tconst helpText = useMemo( () => {\n\t\tif ( overlayTemplateParts.length === 0 && hasResolved ) {\n\t\t\treturn __( 'No overlays found.' );\n\t\t}\n\t\treturn __( 'Select an overlay for navigation.' );\n\t}, [ overlayTemplateParts.length, hasResolved ] );\n\n\t// Tooltip/aria-label text for the edit button\n\tconst editButtonLabel = useMemo( () => {\n\t\treturn selectedTemplatePart\n\t\t\t? sprintf(\n\t\t\t\t\t/* translators: %s: Overlay title. */\n\t\t\t\t\t__( 'Edit overlay: %s' ),\n\t\t\t\t\tselectedTemplatePart.title?.rendered\n\t\t\t\t\t\t? decodeEntities( selectedTemplatePart.title.rendered )\n\t\t\t\t\t\t: selectedTemplatePart.slug\n\t\t\t )\n\t\t\t: __( 'Edit overlay' );\n\t}, [ selectedTemplatePart ] );\n\n\treturn (\n\t\t<div className=\"wp-block-navigation__overlay-selector\">\n\t\t\t<Button\n\t\t\t\tsize=\"small\"\n\t\t\t\ticon={ plus }\n\t\t\t\tonClick={ handleCreateOverlay }\n\t\t\t\tdisabled={ isCreateButtonDisabled }\n\t\t\t\taccessibleWhenDisabled\n\t\t\t\tisBusy={ isCreating }\n\t\t\t\tlabel={ __( 'Create new overlay template' ) }\n\t\t\t\tshowTooltip\n\t\t\t\tclassName=\"wp-block-navigation__overlay-create-button\"\n\t\t\t/>\n\t\t\t<HStack alignment=\"flex-start\">\n\t\t\t\t<FlexBlock>\n\t\t\t\t\t<SelectControl\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t__nextHasNoMarginBottom\n\t\t\t\t\t\tlabel={ __( 'Overlay template' ) }\n\t\t\t\t\t\tvalue={ overlay || '' }\n\t\t\t\t\t\toptions={ options }\n\t\t\t\t\t\tonChange={ handleSelectChange }\n\t\t\t\t\t\tdisabled={ isResolving }\n\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\thelp={ helpText }\n\t\t\t\t\t/>\n\t\t\t\t</FlexBlock>\n\t\t\t\t{ overlay && hasResolved && selectedTemplatePart && (\n\t\t\t\t\t<FlexItem>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\tonClick={ handleEditClick }\n\t\t\t\t\t\t\tdisabled={ ! onNavigateToEntityRecord }\n\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\tlabel={ editButtonLabel }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tclassName=\"wp-block-navigation__overlay-edit-button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Edit' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</FlexItem>\n\t\t\t\t) }\n\t\t\t</HStack>\n\t\t\t{ isOverlayMissing && (\n\t\t\t\t<DeletedOverlayWarning\n\t\t\t\t\tonClear={ handleClearOverlay }\n\t\t\t\t\tonCreate={ handleCreateOverlay }\n\t\t\t\t\tisCreating={ isCreating }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n"],
"mappings": "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",
"names": []
}