Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[code-infra] Convert a few docs modules to ts #45548

Merged
merged 11 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"@types/gtag.js": "^0.0.20",
"@types/json2mq": "^0.2.2",
"@types/node": "^20.17.24",
"@types/nprogress": "^0.2.3",
"@types/prop-types": "^15.7.14",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
Expand Down
5 changes: 4 additions & 1 deletion docs/src/MuiPage.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import * as React from 'react';
import standardNavIcons from './modules/components/AppNavIcons';

export type MuiPageIcon = keyof typeof standardNavIcons | React.ComponentType;

export interface MuiPage {
pathname: string;
query?: object;
children?: MuiPage[];
disableDrawer?: boolean;
icon?: string | React.ComponentType;
icon?: MuiPageIcon;
/**
* Indicates if the pages are regarding some legacy API.
*/
Expand Down
3 changes: 1 addition & 2 deletions docs/src/featureToggle.js → docs/src/featureToggle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// need to use commonjs export so that @mui/internal-markdown can use
module.exports = {
export default {
enable_website_banner: true,
enable_docsnav_banner: true,
enable_job_banner: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ function nProgressDone() {
export function NextNProgressBar() {
const router = useRouter();
React.useEffect(() => {
const handleRouteChangeStart = (url, { shallow }) => {
const handleRouteChangeStart = (url: string, { shallow }: { shallow: boolean }) => {
if (!shallow) {
nProgressStart();
}
};

const handleRouteChangeDone = (url, { shallow }) => {
const handleRouteChangeDone = (url: string, { shallow }: { shallow: boolean }) => {
if (!shallow) {
nProgressDone();
}
Expand Down Expand Up @@ -96,7 +96,7 @@ const RootDiv = styled('div')(({ theme }) => {

const StyledAppBar = styled(AppBar, {
shouldForwardProp: (prop) => prop !== 'disablePermanent',
})(({ theme }) => {
})<{ disablePermanent: boolean }>(({ theme }) => {
return {
padding: theme.spacing(1.5),
transition: theme.transitions.create('width'),
Expand Down Expand Up @@ -131,7 +131,7 @@ const StyledAppBar = styled(AppBar, {

const NavIconButton = styled(IconButton, {
shouldForwardProp: (prop) => prop !== 'disablePermanent',
})(({ theme }) => ({
})<{ disablePermanent: boolean }>(({ theme }) => ({
variants: [
{
props: {
Expand Down Expand Up @@ -164,7 +164,14 @@ const StyledAppNavDrawer = styled(AppNavDrawer)(({ theme }) => ({

export const HEIGHT = 57;

export default function AppFrame(props) {
export interface AppFrameProps {
BannerComponent?: React.ElementType;
children: React.ReactNode;
className?: string;
disableDrawer?: boolean;
}

export default function AppFrame(props: AppFrameProps) {
const { children, disableDrawer = false, className, BannerComponent = AppFrameBanner } = props;
const t = useTranslate();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import Button from '@mui/material/Button';
import Divider from '@mui/material/Divider';
import { styled, alpha, ThemeProvider } from '@mui/material/styles';
import { styled, alpha, ThemeProvider, Theme } from '@mui/material/styles';
import List from '@mui/material/List';
import Drawer from '@mui/material/Drawer';
import Typography from '@mui/material/Typography';
Expand All @@ -21,17 +21,18 @@ import DoneRounded from '@mui/icons-material/DoneRounded';
import LogoWithCopyMenu from 'docs/src/components/action/LogoWithCopyMenu';
import AppNavDrawerItem from 'docs/src/modules/components/AppNavDrawerItem';
import { pageToTitleI18n } from 'docs/src/modules/utils/helpers';
import PageContext from 'docs/src/modules/components/PageContext';
import PageContext, { ProductVersion } from 'docs/src/modules/components/PageContext';
import { useTranslate } from '@mui/docs/i18n';
import MuiProductSelector from 'docs/src/modules/components/MuiProductSelector';
import { MuiPage } from 'docs/src/MuiPage';

// TODO: Collapse should expose an API to customize the duration based on the height.
function transitionTheme(theme) {
function transitionTheme(theme: Theme) {
return {
...theme,
transitions: {
...theme.transitions,
getAutoHeightDuration: (height) => {
getAutoHeightDuration: (height: number) => {
if (!height) {
return 0;
}
Expand All @@ -45,9 +46,9 @@ function transitionTheme(theme) {
};
}

const savedScrollTop = {};
const savedScrollTop: Record<string, number> = {};

const customButtonStyles = (theme) => ({
const customButtonStyles = (theme: Theme) => ({
pl: 1,
pr: '6px',
height: 26,
Expand All @@ -56,22 +57,26 @@ const customButtonStyles = (theme) => ({
letterSpacing: '0.01rem',
});

function ProductDrawerButton(props) {
interface ProductDrawerButtonProps {
productName: string;
}

function ProductDrawerButton(props: ProductDrawerButtonProps) {
const [open, setOpen] = React.useState(false);
const anchorRef = React.useRef(null);
const anchorRef = React.useRef<HTMLButtonElement>(null);

const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};

const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
const handleClose = (event: MouseEvent | TouchEvent) => {
if (anchorRef.current && anchorRef.current.contains(event.target as Node)) {
return;
}
setOpen(false);
};

function handleListKeyDown(event) {
function handleListKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
if (event.key === 'Tab') {
event.preventDefault();
setOpen(false);
Expand Down Expand Up @@ -138,7 +143,13 @@ ProductDrawerButton.propTypes = {
productName: PropTypes.string,
};

function ProductIdentifier(props) {
interface ProductIdentifierProps {
name: string;
metadata: string;
versionSelector: React.ReactNode;
}

function ProductIdentifier(props: ProductIdentifierProps) {
const { name, metadata, versionSelector } = props;
return (
<Box sx={{ flexGrow: 1 }}>
Expand Down Expand Up @@ -171,13 +182,19 @@ ProductIdentifier.propTypes = {
// To match scrollMarginBottom
const browserUrlPreviewMarge = 120;

function PersistScroll(props) {
interface PersistScrollProps {
children: React.ReactNode;
enabled: boolean;
slot: string;
}

function PersistScroll(props: PersistScrollProps) {
const { slot, children, enabled } = props;
const rootRef = React.useRef();
const rootRef = React.useRef<HTMLDivElement>(null);

useEnhancedEffect(() => {
const scrollContainer = rootRef.current ? rootRef.current.parentElement : null;
const activeDrawerLink = scrollContainer.querySelector('.app-drawer-active');
const activeDrawerLink = scrollContainer?.querySelector('.app-drawer-active');

if (!enabled || !scrollContainer || !activeDrawerLink || !activeDrawerLink.scrollIntoView) {
return undefined;
Expand Down Expand Up @@ -235,24 +252,38 @@ const AppNavPaperComponent = styled('div')(() => {
width: 'var(--MuiDocs-navDrawer-width)',
boxShadow: 'none',
border: '0 !important', // TODO add a Paper slot
overflowY: 'unset !important', // TODO add a Paper slot
overflowY: 'unset !important' as 'unset', // TODO add a Paper slot
boxSizing: 'border-box', // TODO have CssBaseline in the Next.js layout
};
});

function renderNavItems(options) {
interface RenderNavItemsOptions {
onClose: () => void;
pages: MuiPage[];
activePageParents: MuiPage[];
depth: number;
t: (key: string) => string;
}

function renderNavItems(options: RenderNavItemsOptions) {
const { pages, ...params } = options;

return (
<List>{pages.reduce((items, page) => reduceChildRoutes({ items, page, ...params }), [])}</List>
<List>
{pages.reduce(
(items, page) => reduceChildRoutes({ items, page, ...params }),
[] as React.ReactNode[],
)}
</List>
);
}

/**
* @param {object} context
* @param {import('docs/src/pages').MuiPage} context.page
*/
function reduceChildRoutes(context) {
interface ReduceChildRoutesContext extends Omit<RenderNavItemsOptions, 'pages'> {
items: React.ReactNode[];
page: MuiPage;
}

function reduceChildRoutes(context: ReduceChildRoutesContext): React.ReactNode[] {
const { onClose, activePageParents, items, depth, t } = context;
const { page } = context;
if (page.inSideNav === false) {
Expand Down Expand Up @@ -339,18 +370,26 @@ function reduceChildRoutes(context) {
// So: <SwipeableDrawer disableBackdropTransition={false} />
const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);

export default function AppNavDrawer(props) {
export interface AppNavDrawerProps {
className?: string;
disablePermanent: boolean;
mobileOpen: boolean;
onClose: () => void;
onOpen: () => void;
}

export default function AppNavDrawer(props: AppNavDrawerProps) {
const { className, disablePermanent, mobileOpen, onClose, onOpen } = props;
const { activePageParents, pages, productIdentifier } = React.useContext(PageContext);
const [anchorEl, setAnchorEl] = React.useState(null);
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
const t = useTranslate();
const mobile = useMediaQuery((theme) => theme.breakpoints.down('lg'));
const swipeableDrawer = disablePermanent || mobile;

const drawer = React.useMemo(() => {
const navItems = renderNavItems({ onClose, pages, activePageParents, depth: 0, t });

const renderVersionSelector = (versions) => {
const renderVersionSelector = (versions: ProductVersion[]) => {
if (!versions?.length) {
return null;
}
Expand Down
Loading