diff --git a/src/page-control/__tests__/page-control.test.tsx b/src/page-control/__tests__/page-control.test.tsx
new file mode 100644
index 0000000000..7e237a8f7c
--- /dev/null
+++ b/src/page-control/__tests__/page-control.test.tsx
@@ -0,0 +1,43 @@
+/*
+Copyright (c) Uber Technologies, Inc.
+
+This source code is licensed under the MIT license found in the
+LICENSE file in the root directory of this source tree.
+*/
+import * as React from 'react';
+import { render, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+
+import PageControl from '../page-control';
+
+describe('PageControl', () => {
+ it('does not throw when a dot is clicked and onPageChange is not supplied', () => {
+ const { getAllByRole } = render();
+ const dots = getAllByRole('radio');
+ expect(() => fireEvent.click(dots[1])).not.toThrow();
+ });
+
+ it('disables every dot and blocks page changes when disabled is set', () => {
+ const onPageChange = jest.fn();
+ const { getAllByRole } = render(
+
+ );
+ const dots = getAllByRole('radio');
+
+ dots.forEach((dot) => expect(dot).toBeDisabled());
+
+ fireEvent.click(dots[1]);
+ expect(onPageChange).not.toHaveBeenCalled();
+ });
+
+ it('calls onPageChange with the clicked page when enabled', () => {
+ const onPageChange = jest.fn();
+ const { getAllByRole } = render(
+
+ );
+ const dots = getAllByRole('radio');
+
+ fireEvent.click(dots[1]);
+ expect(onPageChange).toHaveBeenCalledWith({ nextPage: 2 });
+ });
+});
diff --git a/src/page-control/page-control.tsx b/src/page-control/page-control.tsx
index 1191f7d50a..c6c399b5dd 100644
--- a/src/page-control/page-control.tsx
+++ b/src/page-control/page-control.tsx
@@ -90,10 +90,11 @@ const PageControl = ({
$isVisible={isVisible(page)}
$size={getSize(page)}
checked={isActive(page)}
+ disabled={disabled}
key={page}
aria-label={`page ${page}`}
name={name}
- onChange={() => onPageChange({ nextPage: page })}
+ onChange={() => onPageChange?.({ nextPage: page })}
tabIndex={isActive(page) ? 0 : -1}
type="radio"
{...DotProps}