function InternalTab()

in src/tabs-motion/tabs.tsx [323:506]


function InternalTab({
  // @ts-ignore
  childKey,
  // @ts-ignore
  childIndex,
  // @ts-ignore
  activeKey,
  // @ts-ignore
  orientation,
  // @ts-ignore
  activeTabRef,
  // @ts-ignore
  updateHighlight,
  // @ts-ignore
  parseKeyDown,
  // @ts-ignore
  activateOnFocus,
  // @ts-ignore
  uid,
  // @ts-ignore
  disabled,
  // @ts-ignore
  sharedStylingProps,
  // @ts-ignore
  onChange,
  ...props
}) {
  const key = childKey || String(childIndex);
  const isActive = key == activeKey;
  const { artwork: Artwork, overrides = {}, tabRef, onClick, title, ...restProps } = props;

  // A way to share our internal activeTabRef via the "tabRef" prop.
  const ref = React.useRef();
  React.useImperativeHandle(tabRef, () => {
    return isActive ? activeTabRef.current : ref.current;
  });

  // Track tab dimensions in a ref after each render
  // This is used to compare params when the resize observer fires
  const tabLayoutParams = React.useRef({ length: 0, distance: 0 });
  React.useEffect(() => {
    tabLayoutParams.current = getLayoutParams(
      isActive ? activeTabRef.current : ref.current,
      orientation
    );
  });

  // We need to potentially update the active tab highlight when the width or
  // placement changes for a tab so we listen for resize updates in each tab.
  React.useEffect(() => {
    if (window.ResizeObserver) {
      const observer = new window.ResizeObserver((entries) => {
        if (entries[0] && entries[0].target) {
          const tabLayoutParamsAfterResize = getLayoutParams(entries[0].target, orientation);
          if (
            tabLayoutParamsAfterResize.length !== tabLayoutParams.current.length ||
            tabLayoutParamsAfterResize.distance !== tabLayoutParams.current.distance
          ) {
            updateHighlight();
          }
        }
      });
      observer.observe(isActive ? activeTabRef.current : ref.current);
      return () => {
        observer.disconnect();
      };
    }
  }, [activeKey, orientation]);

  React.useEffect(updateHighlight, [title]);

  // Collect overrides
  const { Tab: TabOverrides, ArtworkContainer: ArtworkContainerOverrides } = overrides;
  const [Tab, TabProps] = getOverrides(TabOverrides, StyledTab);
  const [ArtworkContainer, ArtworkContainerProps] = getOverrides(
    ArtworkContainerOverrides,
    StyledArtworkContainer
  );

  // Keyboard focus styling
  const [focusVisible, setFocusVisible] = React.useState(false);
  const handleFocus = React.useCallback((event: SyntheticEvent) => {
    if (isFocusVisible(event)) {
      setFocusVisible(true);
    }
  }, []);
  const handleBlur = React.useCallback(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    (event: SyntheticEvent) => {
      if (focusVisible !== false) {
        setFocusVisible(false);
      }
    },
    [focusVisible]
  );

  // Keyboard focus management
  // @ts-expect-error todo(flow->ts): deps are required
  const handleKeyDown = React.useCallback((event) => {
    // WAI-ARIA 1.1
    // https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel
    // We use directional keys to iterate focus through Tabs.

    // Find all tabs eligible for focus
    const availableTabs = [...event.target.parentNode.childNodes].filter(
      (node) => !node.disabled && node.getAttribute('role') === 'tab'
    );

    // Exit early if there are no other tabs available
    if (availableTabs.length === 1) return;

    // Find tab to focus, looping to start/end of list if necessary
    const currentTabIndex = availableTabs.indexOf(event.target);
    const action = parseKeyDown(event);
    if (action) {
      let nextTab: HTMLButtonElement | undefined | null;
      if (action === KEYBOARD_ACTION.previous) {
        if (availableTabs[currentTabIndex - 1]) {
          nextTab = availableTabs[currentTabIndex - 1];
        } else {
          nextTab = availableTabs[availableTabs.length - 1];
        }
      } else if (action === KEYBOARD_ACTION.next) {
        if (availableTabs[currentTabIndex + 1]) {
          nextTab = availableTabs[currentTabIndex + 1];
        } else {
          nextTab = availableTabs[0];
        }
      }
      if (nextTab) {
        // Focus the tab
        nextTab.focus();

        // Optionally activate the tab
        if (activateOnFocus) {
          nextTab.click();
        }
      }
      // Prevent default page scroll when in vertical orientation
      if (isVertical(orientation)) {
        event.preventDefault();
      }
    }
  });

  return (
    <Tab
      data-baseweb="tab"
      key={key}
      id={getTabId(uid, key)}
      role="tab"
      onKeyDown={handleKeyDown}
      aria-selected={isActive}
      aria-controls={getTabPanelId(uid, key)}
      tabIndex={isActive ? '0' : '-1'}
      ref={isActive ? activeTabRef : ref}
      disabled={!isActive && disabled}
      type="button" // so it doesn't trigger a submit when used inside forms
      $focusVisible={focusVisible}
      $isActive={isActive}
      {...sharedStylingProps}
      {...restProps}
      {...TabProps}
      // @ts-ignore
      onClick={(event) => {
        if (typeof onChange === 'function') onChange({ activeKey: key });
        if (typeof onClick === 'function') onClick(event);
      }}
      onFocus={forkFocus({ ...restProps, ...TabProps }, handleFocus)}
      onBlur={forkBlur({ ...restProps, ...TabProps }, handleBlur)}
    >
      {Artwork ? (
        <ArtworkContainer
          data-baseweb="artwork-container"
          {...sharedStylingProps}
          {...ArtworkContainerProps}
        >
          <Artwork size={20} color="contentPrimary" />
        </ArtworkContainer>
      ) : null}
      {title ? title : key}
    </Tab>
  );
}