Repository: element-plus/element-plus
File: packages/components/cascader-panel/src/index.vue (Vue)

Code before:
    (reserveExpandingState && oldExpandingNode) || newNodes[0]

  if (newExpandingNode) {
    newExpandingNode.pathNodes.forEach((node) => expandNode(node, true))
  } else {
    expandingNode.value = undefined
  }

  oldNodes.forEach((node) => node.doCheck(false))
  reactive(newNodes).forEach((node) => node.doCheck(true))
  checkedNodes.value = newNodes
  nextTick(scrollToExpandingNode)
}

const scrollToExpandingNode = () => {
  if (!isClient) return

  menuList.value.forEach((menu) => {
    const menuElement = menu?.$el
    if (menuElement) {
      const container = menuElement.querySelector(
        `.${ns.namespace.value}-scrollbar__wrap`
      )
      const activeNode =
        menuElement.querySelector(`.${ns.b('node')}.in-active-path`) ||
        menuElement.querySelector(`.${ns.b('node')}.${ns.is('active')}`)
      scrollIntoView(container, activeNode)
    }
  })
}

const handleKeyDown = (e: KeyboardEvent) => {
  const target = e.target as HTMLElement
  const code = getEventCode(e)

  switch (code) {
    case EVENT_CODE.up:
    case EVENT_CODE.down: {
      e.preventDefault()
      const distance = code === EVENT_CODE.up ? -1 : 1
      focusNode(
        getSibling(
          target,
          distance,
          `.${ns.b('node')}[tabindex="-1"]`
        ) as HTMLElement
      )
      break
    }
    case EVENT_CODE.left: {
      e.preventDefault()

Review comment (suggestion):
I’m not sure why `in-active-path` has a lower priority than `active`, but intuitively, prioritizing `in-active-path` seems more reasonable. 
For example, in this case, the first panel scrolls to the last active node, while the second panel is actually still the one in the `in-active-path`. [play](https://element-plus.run/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cCBsYW5nPVwidHNcIj5cbmltcG9ydCB7IEVsZW1lbnRQbHVzIH0gZnJvbSAnQGVsZW1lbnQtcGx1cy9pY29ucy12dWUnXG5pbXBvcnQgeyB2ZXJzaW9uIGFzIGVwVmVyc2lvbiB9IGZyb20gJ2VsZW1lbnQtcGx1cydcbmltcG9ydCB7IG11bHRpcGx5IH0gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IHsgcmVmLCB2ZXJzaW9uIGFzIHZ1ZVZlcnNpb24gfSBmcm9tICd2dWUnXG5cbi8vIDEuIGNsaWNrIFwiMlwiIG5vZGVcbi8vIDIuIGNsb3NlIGRyb3Bkb3duXG4vLyAzLiBvcGVuIGRyb3Bkb3duXG5cbmNvbnN0IHNlbGVjdGVkID0gcmVmKFsnMTAtMScsJzEwLTInXSlcbmNvbnN0IHByb3BzID0ge1xuICBjaGVja1N0cmljdGx5OmZhbHNlLFxuICBlbWl0UGF0aDpmYWxzZSxcbiAgbXVsdGlwbGU6dHJ1ZSxcbn1cbmNvbnN0IG9wdGlvbnMgPSBbXG57XG4gIGxhYmVsOicxJyxcbiAgdmFsdWU6JzEnLFxuICBjaGlsZHJlbjpbXG4gICAge1xuICAgICAgbGFiZWw6JzEtMScsXG4gICAgICB2YWx1ZTonMS0xJyxcbiAgICB9LFxuICBdXG59LFxue1xuICBsYWJlbDonMicsXG4gIHZhbHVlOicyJyxcbiAgY2hpbGRyZW46W1xuICAgIHtcbiAgICAgIGxhYmVsOicyLTEnLFxuICAgICAgdmFsdWU6JzItMScsXG4gICAgfSxcbiAgXVxufSxcbntcbiAgbGFiZWw6JzMnLFxuICB2YWx1ZTonMycsXG4gIGNoaWxkcmVuOltcbiAgICB7XG4gICAgICBsYWJlbDonMy0xJyxcbiAgICAgIHZhbHVlOiczLTEnLFxuICAgIH1cbiAgXVxufSxcbntcbiAgbGFiZWw6JzQnLFxuICB2YWx1ZTonNCcsXG4gIGNoaWxkcmVuOltcbiAgICB7XG4gICAgICBsYWJlbDonNC0xJyxcbiAgICAgIHZhbHVlOic0LTEnLFxuICAgIH0sXG4gIF1cbn0sXG57XG4gIGxhYmVsOic1JyxcbiAgdmFsdWU6JzUnLFxuICBjaGlsZHJlbjpbXG4gICAge1xuICAgICAgbGFiZWw6JzUtMScsXG4gICAgICB2YWx1ZTonNS0xJyxcbiAgICB9XG4gIF1cbn0sXG57XG4gIGxhYmVsOic2JyxcbiAgdmFsdWU6JzYnLFxuICBjaGlsZHJlbjpbXG4gICAge1xuICAgICAgbGFiZWw6JzYtMScsXG4gICAgICB2YWx1ZTonNi0xJyxcbiAgICB9LFxuICBdXG59LFxue1xuICBsYWJlbDonNycsXG4gIHZhbHVlOic3JyxcbiAgY2hpbGRyZW46W1xuICAgIHtcbiAgICAgIGxhYmVsOic3LTEnLFxuICAgICAgdmFsdWU6JzctMScsXG4gICAgfSxcbiAgICB7XG4gICAgICBsYWJlbDonNy0yJyxcbiAgICAgIHZhbHVlOic3LTInLFxuICAgIH1cbiAgXVxufSxcbntcbiAgbGFiZWw6JzgnLFxuICB2YWx1ZTonOCcsXG4gIGNoaWxkcmVuOltcbiAgICB7XG4gICAgICBsYWJlbDonOC0xJyxcbiAgICAgIHZhbHVlOic4LTEnLFxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6JzgtMicsXG4gICAgICB2YWx1ZTonOC0yJyxcbiAgICB9XG4gIF1cbn0sXG57XG4gIGxhYmVsOic5JyxcbiAgdmFsdWU6JzknLFxuICBjaGlsZHJlbjpbXG4gICAge1xuICAgICAgbGFiZWw6JzktMScsXG4gICAgICB2YWx1ZTonOS0xJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGxhYmVsOic5LTInLFxuICAgICAgdmFsdWU6JzktMicsXG4gICAgfVxuICBdXG59LFxue1xuICBsYWJlbDonMTAnLFxuICB2YWx1ZTonMTAnLFxuICBjaGlsZHJlbjpbXG4gICAge1xuICAgICAgbGFiZWw6JzEwLTEnLFxuICAgICAgdmFsdWU6JzEwLTEnLFxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6JzEwLTInLFxuICAgICAgdmFsdWU6JzEwLTInLFxuICAgIH1cbiAgXVxufSxcblxuXVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPGVsLWNhc2NhZGVyIHYtbW9kZWw9XCJzZWxlY3RlZFwiIDpvcHRpb25zPVwib3B0aW9uc1wiIDpwcm9wcz1cInByb3BzXCIgY29sbGFwc2UtdGFncyBmaWx0ZXJhYmxlPjwvZWwtY2FzY2FkZXI+XG48L3RlbXBsYXRlPlxuIiwiZWxlbWVudC1wbHVzLmpzIjoiaW1wb3J0IEVsZW1lbnRQbHVzIGZyb20gJ2VsZW1lbnQtcGx1cydcbmltcG9ydCB7IGdldEN1cnJlbnRJbnN0YW5jZSB9IGZyb20gJ3Z1ZSdcblxubGV0IGluc3RhbGxlZCA9IGZhbHNlXG5hd2FpdCBsb2FkU3R5bGUoKVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBFbGVtZW50UGx1cygpIHtcbiAgaWYgKGluc3RhbGxlZCkgcmV0dXJuXG4gIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKClcbiAgaW5zdGFuY2UuYXBwQ29udGV4dC5hcHAudXNlKEVsZW1lbnRQbHVzKVxuICBpbnN0YWxsZWQgPSB0cnVlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkU3R5bGUoKSB7XG4gIGNvbnN0IHN0eWxlcyA9IFsnaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9lbGVtZW50LXBsdXNAbGF0ZXN0L2Rpc3QvaW5kZXguY3NzJywgJ2h0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWxlbWVudC1wbHVzQGxhdGVzdC90aGVtZS1jaGFsay9kYXJrL2Nzcy12YXJzLmNzcyddLm1hcCgoc3R5bGUpID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKVxuICAgICAgbGluay5yZWwgPSAnc3R5bGVzaGVldCdcbiAgICAgIGxpbmsuaHJlZiA9IHN0eWxlXG4gICAgICBsaW5rLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCByZXNvbHZlKVxuICAgICAgbGluay5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIHJlamVjdClcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKGxpbmspXG4gICAgfSlcbiAgfSlcbiAgcmV0dXJuIFByb21pc2UuYWxsU2V0dGxlZChzdHlsZXMpXG59XG4iLCJ0c2NvbmZpZy5qc29uIjoie1xuICBcImNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAgXCJ0YXJnZXRcIjogXCJFU05leHRcIixcbiAgICBcImpzeFwiOiBcInByZXNlcnZlXCIsXG4gICAgXCJtb2R1bGVcIjogXCJFU05leHRcIixcbiAgICBcIm1vZHVsZVJlc29sdXRpb25cIjogXCJCdW5kbGVyXCIsXG4gICAgXCJ0eXBlc1wiOiBbXCJlbGVtZW50LXBsdXMvZ2xvYmFsLmQudHNcIl0sXG4gICAgXCJhbGxvd0ltcG9ydGluZ1RzRXh0ZW5zaW9uc1wiOiB0cnVlLFxuICAgIFwiYWxsb3dKc1wiOiB0cnVlLFxuICAgIFwiY2hlY2tKc1wiOiB0cnVlXG4gIH0sXG4gIFwidnVlQ29tcGlsZXJPcHRpb25zXCI6IHtcbiAgICBcInRhcmdldFwiOiAzLjNcbiAgfVxufVxuIiwiUGxheWdyb3VuZE1haW4udnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCBBcHAgZnJvbSAnLi9BcHAudnVlJ1xuaW1wb3J0IHsgc2V0dXBFbGVtZW50UGx1cyB9IGZyb20gJy4vZWxlbWVudC1wbHVzLmpzJ1xuc2V0dXBFbGVtZW50UGx1cygpXG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8QXBwIC8+XG48L3RlbXBsYXRlPlxuIiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9AdnVlL3J1bnRpbWUtZG9tQGxhdGVzdC9kaXN0L3J1bnRpbWUtZG9tLmVzbS1icm93c2VyLmpzXCIsXG4gICAgXCJAdnVlL3NoYXJlZFwiOiBcImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQHZ1ZS9zaGFyZWRAbGF0ZXN0L2Rpc3Qvc2hhcmVkLmVzbS1idW5kbGVyLmpzXCIsXG4gICAgXCJlbGVtZW50LXBsdXNcIjogXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2VsZW1lbnQtcGx1c0BsYXRlc3QvZGlzdC9pbmRleC5mdWxsLm1pbi5tanNcIixcbiAgICBcImVsZW1lbnQtcGx1cy9cIjogXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2VsZW1lbnQtcGx1c0BsYXRlc3QvXCIsXG4gICAgXCJAZWxlbWVudC1wbHVzL2ljb25zLXZ1ZVwiOiBcImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQGVsZW1lbnQtcGx1cy9pY29ucy12dWVAMi9kaXN0L2luZGV4Lm1pbi5qc1wiXG4gIH0sXG4gIFwic2NvcGVzXCI6IHt9XG59IiwiX28iOnt9fQ==)

related #20877

Code after:
    (reserveExpandingState && oldExpandingNode) || newNodes[0]

  if (newExpandingNode) {
    newExpandingNode.pathNodes.forEach((node) => expandNode(node, true))
  } else {
    expandingNode.value = undefined
  }

  oldNodes.forEach((node) => node.doCheck(false))
  reactive(newNodes).forEach((node) => node.doCheck(true))
  checkedNodes.value = newNodes
  nextTick(scrollToExpandingNode)
}

const scrollToExpandingNode = () => {
  if (!isClient) return

  menuList.value.forEach((menu) => {
    const menuElement = menu?.$el
    if (menuElement) {
      const container = menuElement.querySelector(
        `.${ns.namespace.value}-scrollbar__wrap`
      )
      let activeNode = menuElement.querySelector(
        `.${ns.b('node')}.in-active-path`
      )
      if (!activeNode) {
        const activeElements = menuElement.querySelectorAll(
          `.${ns.b('node')}.${ns.is('active')}`
        )
        activeNode = activeElements[activeElements.length - 1]
      }
      scrollIntoView(container, activeNode)
    }
  })
}

const handleKeyDown = (e: KeyboardEvent) => {
  const target = e.target as HTMLElement
  const code = getEventCode(e)

  switch (code) {
    case EVENT_CODE.up:
    case EVENT_CODE.down: {
      e.preventDefault()
      const distance = code === EVENT_CODE.up ? -1 : 1
      focusNode(
        getSibling(
          target,
          distance,
          `.${ns.b('node')}[tabindex="-1"]`