ronantakizawa/codereview-bench huggingface dataset:
Repository: storybookjs/storybook
File: code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts (TypeScript)

Code before:
import { resolvePackageDir } from 'storybook/internal/common';

import { join } from 'pathe';
import type { ResolvedConfig, ViteDevServer } from 'vite';

const entryPath = '/vite-inject-mocker-entry.js';

let server: ViteDevServer;

export const viteInjectMockerRuntime = (options: {
  previewConfigPath?: string | null;
}): import('vite').Plugin => {
  // Get the actual file path so Vite can resolve relative imports
  const mockerRuntimePath = join(
    resolvePackageDir('storybook'),
    'dist',
    'mocking-utils',
    'mocker-runtime.js'
  );

  let viteConfig: ResolvedConfig;

  return {
    name: 'vite:storybook-inject-mocker-runtime',
    enforce: 'pre',
    buildStart() {
      if (viteConfig.command === 'build') {
        this.emitFile({
          type: 'chunk',
          id: join(resolvePackageDir('storybook'), 'dist', 'mocking-utils', 'mocker-runtime.js'),
          fileName: entryPath.slice(1),
        });
      }
    },
    configResolved(config) {
      viteConfig = config;
    },
    configureServer(server_) {

Review comment (suggestion):
I think it's safer to rely on `storybook`'s exports instead of digging directly into the `dist`. You should be able to do that with:

`fileURLToPath(import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime'))`

Code after:
import { fileURLToPath } from 'node:url';

import type { ResolvedConfig } from 'vite';

const ENTRY_PATH = '/vite-inject-mocker-entry.js';

export const viteInjectMockerRuntime = (options: {
  previewConfigPath?: string | null;
}): import('vite').Plugin => {
  // Get the actual file path so Vite can resolve relative imports
  const mockerRuntimePath = fileURLToPath(
    import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime')
  );

  let viteConfig: ResolvedConfig;

  return {
    name: 'vite:storybook-inject-mocker-runtime',
    enforce: 'pre',
    buildStart() {
      if (viteConfig.command === 'build') {
        this.emitFile({
          type: 'chunk',
          id: mockerRuntimePath,
          fileName: ENTRY_PATH.slice(1),
        });
      }
    },
    configResolved(config) {
      viteConfig = config;
    },
    configureServer(server) {
      if (options.previewConfigPath) {
        server.watcher.on('change', (file) => {
          if (file === options.previewConfigPath) {
            server.ws.send({
              type: 'custom',
              event: 'invalidate-mocker',
Repository: storybookjs/storybook
File: code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts (TypeScript)

Code before:
import { resolvePackageDir } from 'storybook/internal/common';

import { join } from 'pathe';
import type { ResolvedConfig, ViteDevServer } from 'vite';

const entryPath = '/vite-inject-mocker-entry.js';

let server: ViteDevServer;

export const viteInjectMockerRuntime = (options: {
  previewConfigPath?: string | null;
}): import('vite').Plugin => {
  // Get the actual file path so Vite can resolve relative imports
  const mockerRuntimePath = join(
    resolvePackageDir('storybook'),
    'dist',
    'mocking-utils',
    'mocker-runtime.js'
  );

  let viteConfig: ResolvedConfig;

  return {
    name: 'vite:storybook-inject-mocker-runtime',
    enforce: 'pre',
    buildStart() {
      if (viteConfig.command === 'build') {
        this.emitFile({
          type: 'chunk',
          id: join(resolvePackageDir('storybook'), 'dist', 'mocking-utils', 'mocker-runtime.js'),
          fileName: entryPath.slice(1),

Review comment (suggestion):
nit


```suggestion
const ENTRY_PATH = '/vite-inject-mocker-entry.js';
```

Code after:
import { fileURLToPath } from 'node:url';

import type { ResolvedConfig } from 'vite';

const ENTRY_PATH = '/vite-inject-mocker-entry.js';

export const viteInjectMockerRuntime = (options: {
  previewConfigPath?: string | null;
}): import('vite').Plugin => {
  // Get the actual file path so Vite can resolve relative imports
  const mockerRuntimePath = fileURLToPath(
    import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime')
  );

  let viteConfig: ResolvedConfig;

  return {
    name: 'vite:storybook-inject-mocker-runtime',
    enforce: 'pre',
    buildStart() {
      if (viteConfig.command === 'build') {
        this.emitFile({
          type: 'chunk',
          id: mockerRuntimePath,
          fileName: ENTRY_PATH.slice(1),
        });
      }
    },
    configResolved(config) {
      viteConfig = config;
    },
Repository: storybookjs/storybook
File: code/core/src/mocking-utils/runtime.ts (TypeScript)

Code before:
import { readFileSync } from 'node:fs';

import { join } from 'pathe';

import { resolvePackageDir } from '../common';

/**
 * Returns the bundled mocker runtime script content. This is used by builders (webpack5, vite,
 * etc.) to inject the mocker runtime into the preview iframe.
 */
export function getMockerRuntime(): string {
  return readFileSync(
    join(resolvePackageDir('storybook'), 'dist', 'mocking-utils', 'mocker-runtime.js'),
    'utf-8'
  );
}


Review comment (suggestion):
same comment about using `import.meta.resolve` here instead.

Code after:
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';

/**
 * Returns the bundled mocker runtime script content. This is used by builders (webpack5, vite,
 * etc.) to inject the mocker runtime into the preview iframe.
 */
export function getMockerRuntime(): string {
  return readFileSync(
    fileURLToPath(import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime')),
    'utf-8'
  );
}
Repository: storybookjs/storybook
File: code/addons/docs/src/blocks/components/Preview.tsx (TypeScript)

Code before:
  }
  return null;
}

const PositionedToolbar = styled(Toolbar)({
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  height: 40,
});

const Relative = styled.div(({ theme }) => ({
  overflow: 'hidden',
  position: 'relative',
  display: 'flex',
  flexWrap: 'wrap',
  gap: theme.layoutMargin,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

export const Preview: FC<PreviewProps> = ({
  isLoading,
  isColumn,
  columns,
  children,
  withSource,
  withToolbar = false,
  isExpanded = false,
  additionalActions,
  className,
  layout = 'padded',
  inline = false,
  ...props
}) => {
  const [expanded, setExpanded] = useState(isExpanded);
  const { source, actionItem } = getSource(withSource, expanded, setExpanded);
  const [scale, setScale] = useState(1);
  const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview', 'sb-unstyled']);

  const defaultActionItems = withSource ? [actionItem] : [];
  const [additionalActionItems, setAdditionalActionItems] = useState(
    additionalActions ? [...additionalActions] : []
  );
  const actionItems = [...defaultActionItems, ...additionalActionItems];


Review comment (suggestion):

```suggestion

/**
 * A preview component for showing one or more component `Story` items. The preview also shows the
 * source for the component as a drop-down.
 */
```

Code after:
  }
  return null;
}

const PositionedToolbar = styled(Toolbar)({
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  height: 40,
});

const Relative = styled.div(({ theme }) => ({
  overflow: 'hidden',
  position: 'relative',
  display: 'flex',
  flexWrap: 'wrap',
  gap: theme.layoutMargin,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

/**
 * A preview component for showing one or more component `Story` items. The preview also shows the
 * source for the component as a drop-down.
 */
export const Preview: FC<PreviewProps> = ({
  isLoading,
  isColumn,
  columns,
  children,
  withSource,
  withToolbar = false,
  isExpanded = false,
  additionalActions,
  className,
  layout = 'padded',
  inline = false,
  ...props
}) => {
  const [expanded, setExpanded] = useState(isExpanded);
  const { source, actionItem } = getSource(withSource, expanded, setExpanded);
  const [scale, setScale] = useState(1);
  const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview', 'sb-unstyled']);

  const defaultActionItems = withSource ? [actionItem] : [];
  const [additionalActionItems, setAdditionalActionItems] = useState(
Repository: storybookjs/storybook
File: code/core/src/components/components/syntaxhighlighter/syntaxhighlighter.tsx (TypeScript)

Code before:
    return renderer;
  }
  if (renderer) {
    return ({ rows, ...rest }: SyntaxHighlighterRendererProps) =>
      renderer({ rows: rows.map((row) => processLineNumber(row)), ...rest });
  }
  return defaultRenderer;
};

export interface SyntaxHighlighterState {
  copied: boolean;
}

export const SyntaxHighlighter = ({
  children,
  language = 'jsx',
  copyable = false,
  bordered = false,
  padded = false,
  format = true,
  formatter = undefined,
  className = undefined,
  showLineNumbers = false,
  ...rest
}: SyntaxHighlighterProps) => {
  if (typeof children !== 'string' || !children.trim()) {
    return null;
  }

  const [highlightableCode, setHighlightableCode] = useState('');

  useEffect(() => {
    if (formatter) {
      formatter(format, children).then(setHighlightableCode);
    } else {
      setHighlightableCode(children.trim());
    }
  }, [children, format, formatter]);

  const [copied, setCopied] = useState(false);

  const onClick = useCallback(
    (e: MouseEvent<HTMLButtonElement>) => {
      e.preventDefault();
      copyToClipboard(highlightableCode)
        .then(() => {
          setCopied(true);
          globalWindow.setTimeout(() => setCopied(false), 1500);
        })
        .catch(logger.error);
    },

Review comment (suggestion):
```suggestion
// copied from @types/react-syntax-highlighter/index.d.ts

export const SyntaxHighlighter = ({
```

Code after:
      key: `code-segement${i}`,
    });
  });
};

const wrapRenderer = (
  renderer: SyntaxHighlighterRenderer | undefined,
  showLineNumbers: boolean
) => {
  if (!showLineNumbers) {
    return renderer;
  }
  if (renderer) {
    return ({ rows, ...rest }: SyntaxHighlighterRendererProps) =>
      renderer({ rows: rows.map((row) => processLineNumber(row)), ...rest });
  }
  return defaultRenderer;
};

export interface SyntaxHighlighterState {
  copied: boolean;
}

// copied from @types/react-syntax-highlighter/index.d.ts

export const SyntaxHighlighter = ({
  children,
  language = 'jsx',
  copyable = false,
  bordered = false,
  padded = false,
  format = true,
  formatter = undefined,
  className = undefined,
  showLineNumbers = false,
  ...rest
}: SyntaxHighlighterProps) => {
  if (typeof children !== 'string' || !children.trim()) {
    return null;
  }

  const [highlightableCode, setHighlightableCode] = useState('');

  useEffect(() => {
    if (formatter) {
      formatter(format, children).then(setHighlightableCode);
    } else {
      setHighlightableCode(children.trim());
    }
  }, [children, format, formatter]);
Repository: storybookjs/storybook
File: code/core/src/components/components/syntaxhighlighter/syntaxhighlighter.tsx (TypeScript)

Code before:
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
  ({ theme }) => themedSyntax(theme)
);

export interface PreProps {
  padded?: boolean;
}

const Pre = styled.pre<PreProps>(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));

const Code = styled.div(({ theme }) => ({
  flex: 1,
  paddingLeft: 2,
  opacity: 1,
  fontFamily: theme.typography.fonts.mono,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

const processLineNumber = (row: any) => {
  const children = [...row.children];
  const lineNumberNode = children[0];
  const lineNumber = lineNumberNode.children[0].value;
  const processedLineNumberNode = {
    ...lineNumberNode,
    children: [],
    // empty the line-number element
    properties: {
      ...lineNumberNode.properties,
      'data-line-number': lineNumber,
      // remove the userSelect: none style, which will produce extra empty lines when copy-pasting in firefox
      style: { ...lineNumberNode.properties.style, userSelect: 'auto' },
    },
  };
  children[0] = processedLineNumberNode;
  return { ...row, children };
};

Review comment (suggestion):
```suggestion
/*
We can't use `code` since PrismJS races for it.
See https://github.com/storybookjs/storybook/issues/18090
 */
const Code = styled.div(({ theme }) => ({
```

Code after:
      maxWidth: '100%',
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
  ({ theme }) => themedSyntax(theme)
);

export interface PreProps {
  padded?: boolean;
}

const Pre = styled.pre<PreProps>(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));

/*
We can't use `code` since PrismJS races for it.
See https://github.com/storybookjs/storybook/issues/18090
 */
const Code = styled.div(({ theme }) => ({
  flex: 1,
  paddingLeft: 2, // TODO: To match theming/global.ts for now
  opacity: 1,
  fontFamily: theme.typography.fonts.mono,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

const processLineNumber = (row: any) => {
  const children = [...row.children];
  const lineNumberNode = children[0];
  const lineNumber = lineNumberNode.children[0].value;
  const processedLineNumberNode = {
    ...lineNumberNode,
    // empty the line-number element
    children: [],
    properties: {
      ...lineNumberNode.properties,
      // add a data-line-number attribute to line-number element, so we can access the line number with `content: attr(data-line-number)`
      'data-line-number': lineNumber,
      // remove the 'userSelect: none' style, which will produce extra empty lines when copy-pasting in firefox
Repository: storybookjs/storybook
File: code/core/src/components/components/syntaxhighlighter/syntaxhighlighter.tsx (TypeScript)

Code before:
    '> div': {
      width: 'fit-content',
      maxWidth: '100%',
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
  ({ theme }) => themedSyntax(theme)
);

export interface PreProps {
  padded?: boolean;
}

const Pre = styled.pre<PreProps>(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));

const Code = styled.div(({ theme }) => ({
  flex: 1,
  paddingLeft: 2,
  opacity: 1,
  fontFamily: theme.typography.fonts.mono,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

const processLineNumber = (row: any) => {
  const children = [...row.children];
  const lineNumberNode = children[0];
  const lineNumber = lineNumberNode.children[0].value;
  const processedLineNumberNode = {
    ...lineNumberNode,
    children: [],
    // empty the line-number element
    properties: {
      ...lineNumberNode.properties,
      'data-line-number': lineNumber,
      // remove the userSelect: none style, which will produce extra empty lines when copy-pasting in firefox
      style: { ...lineNumberNode.properties.style, userSelect: 'auto' },
    },
  };

Review comment (suggestion):
```suggestion
  paddingLeft: 2, // TODO: To match theming/global.ts for now
```

Code after:
    maxWidth: '100%',
    '> div': {
      width: 'fit-content',
      maxWidth: '100%',
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
  ({ theme }) => themedSyntax(theme)
);

export interface PreProps {
  padded?: boolean;
}

const Pre = styled.pre<PreProps>(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));

/*
We can't use `code` since PrismJS races for it.
See https://github.com/storybookjs/storybook/issues/18090
 */
const Code = styled.div(({ theme }) => ({
  flex: 1,
  paddingLeft: 2, // TODO: To match theming/global.ts for now
  opacity: 1,
  fontFamily: theme.typography.fonts.mono,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

const processLineNumber = (row: any) => {
  const children = [...row.children];
  const lineNumberNode = children[0];
  const lineNumber = lineNumberNode.children[0].value;
  const processedLineNumberNode = {
    ...lineNumberNode,
    // empty the line-number element
    children: [],
    properties: {
      ...lineNumberNode.properties,
Repository: storybookjs/storybook
File: code/core/src/components/components/syntaxhighlighter/syntaxhighlighter.tsx (TypeScript)

Code before:
  padded?: boolean;
  showLineNumbers?: boolean;
}

const Wrapper = styled.div<WrapperProps>(
  ({ theme }) => ({
    position: 'relative',
    overflow: 'hidden',
    display: 'flex',
    flexWrap: 'wrap',
    gap: theme.layoutMargin,
    color: theme.color.defaultText,
  }),
  ({ theme, bordered }) =>
    bordered
      ? {
          border: `1px solid ${theme.appBorderColor}`,
          borderRadius: theme.borderRadius,
          background: theme.background.content,
        }
      : {},
  ({ showLineNumbers }) =>
    showLineNumbers
      ? {
          '.react-syntax-highlighter-line-number::before': {
            content: 'attr(data-line-number)',
          },
        }
      : {}
);

const UnstyledScroller = ({ children, className }: ScrollAreaProps) => (
  <ScrollArea horizontal vertical className={className}>
    {children}
  </ScrollArea>
);
const Scroller = styled(UnstyledScroller)(
  {
    position: 'relative',
    width: 'fit-content',
    maxWidth: '100%',
    '> div': {
      width: 'fit-content',
      maxWidth: '100%',
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
  ({ theme }) => themedSyntax(theme)

Review comment (suggestion):
```suggestion
          // use the before pseudo element to display line numbers
          '.react-syntax-highlighter-line-number::before': {
```

Code after:
  padded?: boolean;
  showLineNumbers?: boolean;
}

const Wrapper = styled.div<WrapperProps>(
  ({ theme }) => ({
    position: 'relative',
    overflow: 'hidden',
    display: 'flex',
    flexWrap: 'wrap',
    gap: theme.layoutMargin,
    color: theme.color.defaultText,
  }),
  ({ theme, bordered }) =>
    bordered
      ? {
          border: `1px solid ${theme.appBorderColor}`,
          borderRadius: theme.borderRadius,
          background: theme.background.content,
        }
      : {},
  ({ showLineNumbers }) =>
    showLineNumbers
      ? {
          // use the before pseudo element to display line numbers
          '.react-syntax-highlighter-line-number::before': {
            content: 'attr(data-line-number)',
          },
        }
      : {}
);

const UnstyledScroller = ({ children, className }: ScrollAreaProps) => (
  <ScrollArea horizontal vertical className={className}>
    {children}
  </ScrollArea>
);
const Scroller = styled(UnstyledScroller)(
  {
    position: 'relative',
    width: 'fit-content',
    maxWidth: '100%',
    '> div': {
      width: 'fit-content',
      maxWidth: '100%',
      '> div > pre': {
        width: 'fit-content',
        maxWidth: '100%',
      },
    },
  },
Repository: storybookjs/storybook
File: code/addons/docs/src/blocks/components/Preview.tsx (TypeScript)

Code before:
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  height: 40,
});

const Relative = styled.div(({ theme }) => ({
  overflow: 'hidden',
  position: 'relative',
  display: 'flex',
  flexWrap: 'wrap',
  gap: theme.layoutMargin,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

export const Preview: FC<PreviewProps> = ({
  isLoading,
  isColumn,
  columns,
  children,
  withSource,
  withToolbar = false,
  isExpanded = false,
  additionalActions,
  className,
  layout = 'padded',
  inline = false,
  ...props
}) => {
  const [expanded, setExpanded] = useState(isExpanded);
  const { source, actionItem } = getSource(withSource, expanded, setExpanded);
  const [scale, setScale] = useState(1);
  const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview', 'sb-unstyled']);

  const defaultActionItems = withSource ? [actionItem] : [];
  const [additionalActionItems, setAdditionalActionItems] = useState(
    additionalActions ? [...additionalActions] : []
  );
  const actionItems = [...defaultActionItems, ...additionalActionItems];

  const { window: globalWindow } = globalThis;

  const context = useContext(DocsContext);

  const copyToClipboard = useCallback(async (text: string) => {

Review comment (suggestion):
```suggestion
/**
 * A preview component for showing one or more component `Story` items. The preview also shows the
 * source for the component as a drop-down.
 */
export const Preview: FC<PreviewProps> = ({
```

Code after:
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  height: 40,
});

const Relative = styled.div(({ theme }) => ({
  overflow: 'hidden',
  position: 'relative',
  display: 'flex',
  flexWrap: 'wrap',
  gap: theme.layoutMargin,
}));

const RelativeActionBar = styled(ActionBar)({
  position: 'relative',
  marginLeft: 'auto',
  alignSelf: 'flex-end',
});

/**
 * A preview component for showing one or more component `Story` items. The preview also shows the
 * source for the component as a drop-down.
 */
export const Preview: FC<PreviewProps> = ({
  isLoading,
  isColumn,
  columns,
  children,
  withSource,
  withToolbar = false,
  isExpanded = false,
  additionalActions,
  className,
  layout = 'padded',
  inline = false,
  ...props
}) => {
  const [expanded, setExpanded] = useState(isExpanded);
  const { source, actionItem } = getSource(withSource, expanded, setExpanded);
  const [scale, setScale] = useState(1);
  const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview', 'sb-unstyled']);

  const defaultActionItems = withSource ? [actionItem] : [];
  const [additionalActionItems, setAdditionalActionItems] = useState(
    additionalActions ? [...additionalActions] : []
  );
  const actionItems = [...defaultActionItems, ...additionalActionItems];

  const { window: globalWindow } = globalThis;