UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

87 lines (86 loc) 4.31 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /* * Copyright 2025 The Kubernetes Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Box from '@mui/material/Box'; import MuiDialog from '@mui/material/Dialog'; import MuiDialogTitle from '@mui/material/DialogTitle'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import React from 'react'; import { useTranslation } from 'react-i18next'; import ActionButton from './ActionButton'; // We export the ConfirmDialog from here because it was declared in this file before being // moved to its own. export { ConfirmDialog } from './ConfirmDialog'; /** * This is like Material-ui DialogTitle but fixes some a11y issues. * * First, it needs a h1 because other page content is aria-diable=true'd * * Additionally, it also focuses the title text as that is where * reading can begin. */ export function DialogTitle(props) { const { children, focusTitle, buttons, disableTypography = false, id, ...other } = props; const focusedRef = React.useCallback((node) => { if (node !== null && focusTitle) { node.setAttribute('tabindex', '-1'); node.focus(); } }, [focusTitle]); // Don't render heading if there's no content to avoid empty heading violations if (!children && (!buttons || buttons.length === 0)) { return null; } return (_jsx(MuiDialogTitle, { style: { display: 'flex' }, ...other, children: _jsxs(Grid, { container: true, justifyContent: "space-between", alignItems: "center", children: [children && (_jsx(Grid, { item: true, children: disableTypography ? (_jsx("div", { id: id, children: children })) : (_jsx(Typography, { id: id, ref: focusedRef, variant: "h1", style: { fontSize: '1.25rem', fontWeight: 500, lineHeight: 1.6, }, children: children })) })), buttons && buttons.length > 0 && (_jsx(Grid, { item: true, children: _jsx(Box, { children: buttons.map((button, index) => { return _jsx(React.Fragment, { children: button }, index); }) }) }))] }) })); } export function Dialog(props) { const { title, withFullScreen = false, children, onFullScreenToggled, titleProps, ...other } = props; const [fullScreen, setFullScreen] = React.useState(false); const { t } = useTranslation(); function handleFullScreen() { setFullScreen(fs => { const newFullScreenState = !fs; if (!!onFullScreenToggled) { onFullScreenToggled(newFullScreenState); } return newFullScreenState; }); } function FullScreenButton() { if (!withFullScreen) { return null; } return (_jsx(ActionButton, { description: t('Toggle fullscreen'), onClick: handleFullScreen, icon: fullScreen ? 'mdi:fullscreen-exit' : 'mdi:fullscreen' })); } function CloseButton() { return (_jsx(ActionButton, { description: t('Close'), onClick: () => { props.onClose && props.onClose({}, 'escapeKeyDown'); }, icon: 'mdi:close' })); } const generatedId = React.useId(); const titleId = titleProps?.id || generatedId; const dialogAriaProps = title ? { 'aria-labelledby': titleId } : {}; return (_jsxs(MuiDialog, { maxWidth: "lg", scroll: "paper", fullWidth: true, fullScreen: fullScreen, ...dialogAriaProps, ...other, children: [(!!title || withFullScreen) && ( // eslint-disable-next-line react-hooks/static-components _jsx(DialogTitle, { ...titleProps, id: titleId, buttons: [_jsx(FullScreenButton, {}), _jsx(CloseButton, {})], children: title })), children] })); }