Repository: expo/expo
File: docs/ui/components/Snippet/blocks/Terminal.tsx (TypeScript)

Code before:
import { useEffect, useMemo, useState } from 'react';

import { CODE } from '~/ui/components/Text';
import { useIsMobileView } from '~/ui/components/utils/isMobileView';

import { Select } from '../../Select';
import { Snippet } from '../Snippet';
import { SnippetAction } from '../SnippetAction';
import { SnippetContent } from '../SnippetContent';
import { SnippetHeader } from '../SnippetHeader';
import { CopyAction } from '../actions/CopyAction';

type PackageManagerKey = 'npm' | 'yarn' | 'pnpm' | 'bun';
type PackageManagerCommandSet = Partial<Record<PackageManagerKey, string[]>>;

type TerminalProps = {
  cmd: string[];
  cmdCopy?: string;
  hideOverflow?: boolean;
  title?: string;
  className?: string;
  browserAction?: {
    href: string;
    label: string;
  };
  packageManagers?: PackageManagerCommandSet;
};

type CopyButtonProps = Pick<TerminalProps, 'cmd' | 'cmdCopy'>;

type BrowserActionProps = NonNullable<TerminalProps['browserAction']>;

type PackageTabsProps = {
  managers: PackageManagerKey[];
  activeManager: PackageManagerKey | null;
  onSelect: (manager: PackageManagerKey) => void;
  className?: string;
};

type PackageManagerState = {
  availableManagers: PackageManagerKey[];
  activeManager: PackageManagerKey | null;
  activeCmd: string[];
  shouldShowPackageTabs: boolean;
  setActiveManager: (manager: PackageManagerKey) => void;
};

const STORAGE_KEY = 'expo-docs-terminal-package-manager';

const PACKAGE_MANAGER_ORDER: PackageManagerKey[] = ['npm', 'yarn', 'pnpm', 'bun'];
const PACKAGE_MANAGER_LABELS: Record<PackageManagerKey, string> = {

Review comment (suggestion):
Thoughts on using a union type here instead?

So `cmd` could be `cmd: string[] | PackageManagerCommandSet` and we don't need the extra prop.

Code after:
import { useEffect, useMemo, useState } from 'react';

import { CODE } from '~/ui/components/Text';
import { useIsMobileView } from '~/ui/components/utils/isMobileView';

import { Select } from '../../Select';
import { Snippet } from '../Snippet';
import { SnippetAction } from '../SnippetAction';
import { SnippetContent } from '../SnippetContent';
import { SnippetHeader } from '../SnippetHeader';
import { CopyAction } from '../actions/CopyAction';

type PackageManagerKey = 'npm' | 'yarn' | 'pnpm' | 'bun';
type PackageManagerCommandSet = Partial<Record<PackageManagerKey, string[]>>;

type TerminalProps = {
  cmd: string[] | PackageManagerCommandSet;
  cmdCopy?: string;
  hideOverflow?: boolean;
  title?: string;
  className?: string;
  browserAction?: {
    href: string;
    label: string;
  };
};

type CopyButtonProps = {
  cmd: string[];
  cmdCopy?: string;
};

type BrowserActionProps = NonNullable<TerminalProps['browserAction']>;

type PackageTabsProps = {
  managers: PackageManagerKey[];
  activeManager: PackageManagerKey | null;
  onSelect: (manager: PackageManagerKey) => void;
  className?: string;
};

type PackageManagerState = {
  availableManagers: PackageManagerKey[];
  activeManager: PackageManagerKey | null;
  activeCmd: string[];
  shouldShowPackageTabs: boolean;
  setActiveManager: (manager: PackageManagerKey) => void;
};

const STORAGE_KEY = 'expo-docs-terminal-package-manager';