{
  "version": 3,
  "sources": ["../../src/tabs/use-tab-list-sync.js"],
  "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { createBlock } from '@wordpress/blocks';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useDispatch } from '@wordpress/data';\nimport { useEffect, useRef } from '@wordpress/element';\n\n/**\n * Keep tabs and tab panels in sync when the lists change due to direct\n * user actions (deletion, paste, duplicate, drag-and-drop).\n *\n * Deletion: when one side shrinks, remove the counterpart at the same index.\n * Insertion: when one side grows without the other, insert the missing\n * counterpart at the matching index.\n *\n * When both lists change simultaneously (e.g. the \"Add Tab\" toolbar button,\n * which inserts both at once), no action is needed and the effect exits early.\n *\n * @param {Object}      props\n * @param {Array}       props.tabs              Raw core/tab block objects.\n * @param {Array}       props.tabPanels         Raw core/tab-panel block objects.\n * @param {string|null} props.tabPanelsClientId Client ID of the core/tab-panels block.\n * @param {string|null} props.tabsListClientId  Client ID of the core/tab-list block.\n */\nexport default function useTabListSync( {\n\ttabPanels,\n\ttabs,\n\ttabPanelsClientId,\n\ttabsListClientId,\n} ) {\n\tconst {\n\t\tremoveBlock,\n\t\tinsertBlocks,\n\t\treplaceInnerBlocks,\n\t\t__unstableMarkNextChangeAsNotPersistent,\n\t} = useDispatch( blockEditorStore );\n\n\tconst prevSyncStateRef = useRef( null );\n\tuseEffect( () => {\n\t\tif ( prevSyncStateRef.current === null ) {\n\t\t\tprevSyncStateRef.current = {\n\t\t\t\ttabPanels: [ ...tabPanels ],\n\t\t\t\ttabs: [ ...tabs ],\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\n\t\tconst { tabPanels: prevTabPanels, tabs: prevTabs } =\n\t\t\tprevSyncStateRef.current;\n\n\t\tconst tabPanelCountChange = tabPanels.length - prevTabPanels.length;\n\t\tconst tabCountChange = tabs.length - prevTabs.length;\n\n\t\tconst tabPanelsInserted = tabPanelCountChange > 0;\n\t\tconst tabsInserted = tabCountChange > 0;\n\n\t\t// Both sides changed by the same amount.\n\t\t// Covers: no-op re-renders, \"Add Tab\" toolbar, and toolbar-remove.\n\t\t// Also handles drag-and-drop reordering of tabs.\n\t\tif ( tabPanelCountChange === tabCountChange ) {\n\t\t\t// When lengths are equal but order changed, the user reordered tabs\n\t\t\t// via drag-and-drop. Reorder the tab panel blocks to match.\n\t\t\tif (\n\t\t\t\ttabPanelCountChange === 0 &&\n\t\t\t\ttabPanelsClientId &&\n\t\t\t\ttabs.some( ( m, i ) => m.clientId !== prevTabs[ i ]?.clientId )\n\t\t\t) {\n\t\t\t\tconst reorderedTabPanels = tabs\n\t\t\t\t\t.map( ( tab ) => {\n\t\t\t\t\t\tconst oldIndex = prevTabs.findIndex(\n\t\t\t\t\t\t\t( pm ) => pm.clientId === tab.clientId\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn oldIndex !== -1 ? tabPanels[ oldIndex ] : null;\n\t\t\t\t\t} )\n\t\t\t\t\t.filter( Boolean );\n\t\t\t\tif ( reorderedTabPanels.length === tabPanels.length ) {\n\t\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\t\treplaceInnerBlocks(\n\t\t\t\t\t\ttabPanelsClientId,\n\t\t\t\t\t\treorderedTabPanels,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tprevSyncStateRef.current = {\n\t\t\t\ttabPanels: [ ...tabPanels ],\n\t\t\t\ttabs: [ ...tabs ],\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\n\t\t// Both sides changed in the same direction but by different amounts.\n\t\t// Bail without making a partial fix.\n\t\tif (\n\t\t\t( tabPanelCountChange > 0 && tabCountChange > 0 ) ||\n\t\t\t( tabPanelCountChange < 0 && tabCountChange < 0 )\n\t\t) {\n\t\t\tprevSyncStateRef.current = {\n\t\t\t\ttabPanels: [ ...tabPanels ],\n\t\t\t\ttabs: [ ...tabs ],\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\n\t\t// If the required container block isn't available yet, bail without\n\t\t// updating the snapshot so the next render re-evaluates the same count change.\n\t\tif ( tabPanelsInserted && ! tabsListClientId ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( tabsInserted && ! tabPanelsClientId ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Update snapshot to the current state.\n\t\tprevSyncStateRef.current = {\n\t\t\ttabPanels: [ ...tabPanels ],\n\t\t\ttabs: [ ...tabs ],\n\t\t};\n\n\t\tconst currentTabPanelIds = new Set(\n\t\t\ttabPanels.map( ( t ) => t.clientId )\n\t\t);\n\t\tconst currentTabIds = new Set( tabs.map( ( m ) => m.clientId ) );\n\n\t\tif ( tabPanelCountChange < 0 ) {\n\t\t\t// Remove the tab at the same position as each deleted tab panel.\n\t\t\tconst removedIndices = prevTabPanels\n\t\t\t\t.map( ( t, i ) =>\n\t\t\t\t\t! currentTabPanelIds.has( t.clientId ) ? i : -1\n\t\t\t\t)\n\t\t\t\t.filter( ( i ) => i !== -1 );\n\t\t\tconst removedSet = new Set( removedIndices );\n\t\t\tremovedIndices.forEach( ( removedIndex ) => {\n\t\t\t\tif ( tabs[ removedIndex ] ) {\n\t\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\t\tremoveBlock( tabs[ removedIndex ].clientId, false );\n\t\t\t\t}\n\t\t\t} );\n\t\t\tprevSyncStateRef.current.tabs =\n\t\t\t\tprevSyncStateRef.current.tabs.filter(\n\t\t\t\t\t( _, i ) => ! removedSet.has( i )\n\t\t\t\t);\n\t\t} else if ( tabCountChange < 0 ) {\n\t\t\t// Remove the tab panel at the same position as each deleted tab.\n\t\t\tconst removedIndices = prevTabs\n\t\t\t\t.map( ( m, i ) =>\n\t\t\t\t\t! currentTabIds.has( m.clientId ) ? i : -1\n\t\t\t\t)\n\t\t\t\t.filter( ( i ) => i !== -1 );\n\t\t\tconst removedSet = new Set( removedIndices );\n\t\t\tremovedIndices.forEach( ( removedIndex ) => {\n\t\t\t\tif ( tabPanels[ removedIndex ] ) {\n\t\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\t\tremoveBlock( tabPanels[ removedIndex ].clientId, false );\n\t\t\t\t}\n\t\t\t} );\n\t\t\tprevSyncStateRef.current.tabPanels =\n\t\t\t\tprevSyncStateRef.current.tabPanels.filter(\n\t\t\t\t\t( _, i ) => ! removedSet.has( i )\n\t\t\t\t);\n\t\t} else if ( tabPanelsInserted ) {\n\t\t\t// A tab panel was pasted or duplicated \u2014 insert a matching tab.\n\t\t\tconst prevTabPanelIds = new Set(\n\t\t\t\tprevTabPanels.map( ( t ) => t.clientId )\n\t\t\t);\n\t\t\tconst newTabs = tabPanels\n\t\t\t\t.map( ( tabPanel, tabPanelIndex ) =>\n\t\t\t\t\t! prevTabPanelIds.has( tabPanel.clientId )\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\ttabPanelIndex,\n\t\t\t\t\t\t\t\tblock: createBlock( 'core/tab', {} ),\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t: null\n\t\t\t\t)\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( newTabs.length > 0 ) {\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\tinsertBlocks(\n\t\t\t\t\tnewTabs.map( ( { block } ) => block ),\n\t\t\t\t\tnewTabs[ 0 ].tabPanelIndex,\n\t\t\t\t\ttabsListClientId,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tnewTabs.forEach( ( { tabPanelIndex, block } ) => {\n\t\t\t\t\tprevSyncStateRef.current.tabs.splice( tabPanelIndex, 0, {\n\t\t\t\t\t\tclientId: block.clientId,\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t\t}\n\t\t} else if ( tabsInserted ) {\n\t\t\t// A tab was pasted or duplicated \u2014 insert a matching tab panels,\n\t\t\t// copying the label from the adjacent tab panel.\n\t\t\tconst prevTabIds = new Set( prevTabs.map( ( m ) => m.clientId ) );\n\t\t\tconst newTabPanels = tabs\n\t\t\t\t.map( ( tab, tabIndex ) => {\n\t\t\t\t\tif ( prevTabIds.has( tab.clientId ) ) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst label =\n\t\t\t\t\t\ttabPanels[ tabIndex - 1 ]?.attributes?.label ??\n\t\t\t\t\t\ttabPanels[ tabIndex ]?.attributes?.label ??\n\t\t\t\t\t\t'';\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\tblock: createBlock( 'core/tab-panel', { label } ),\n\t\t\t\t\t};\n\t\t\t\t} )\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( newTabPanels.length > 0 ) {\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\tinsertBlocks(\n\t\t\t\t\tnewTabPanels.map( ( { block } ) => block ),\n\t\t\t\t\tnewTabPanels[ 0 ].tabIndex,\n\t\t\t\t\ttabPanelsClientId,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tnewTabPanels.forEach( ( { tabIndex, block } ) => {\n\t\t\t\t\tprevSyncStateRef.current.tabPanels.splice( tabIndex, 0, {\n\t\t\t\t\t\tclientId: block.clientId,\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}, [\n\t\ttabPanels,\n\t\ttabs,\n\t\tremoveBlock,\n\t\tinsertBlocks,\n\t\treplaceInnerBlocks,\n\t\t__unstableMarkNextChangeAsNotPersistent,\n\t\ttabsListClientId,\n\t\ttabPanelsClientId,\n\t] );\n}\n"],
  "mappings": "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",
  "names": ["blockEditorStore"]
}
