@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
87 lines (86 loc) • 4.31 kB
JavaScript
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] }));
}