@linagora/twake-mui 15.2.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/components/Dialog/Dialog.stories.d.ts +1 -1
- package/dist/components/Dialog/Dialog.stories.js +1 -1
- package/dist/components/Dialog/index.d.ts +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/Dialogs/ConfirmDialog.d.ts +8 -0
- package/dist/components/Dialogs/ConfirmDialog.js +16 -0
- package/dist/components/Dialogs/DialogBackButton.d.ts +8 -0
- package/dist/components/Dialogs/DialogBackButton.js +14 -0
- package/dist/components/Dialogs/DialogCloseButton.d.ts +8 -0
- package/dist/components/Dialogs/DialogCloseButton.js +14 -0
- package/dist/components/Dialogs/DialogFluidContent.d.ts +12 -0
- package/dist/components/Dialogs/DialogFluidContent.js +11 -0
- package/dist/components/Dialogs/DialogNavButtons.d.ts +9 -0
- package/dist/components/Dialogs/DialogNavButtons.js +14 -0
- package/dist/components/Dialogs/Dialogs.stories.d.ts +33 -0
- package/dist/components/Dialogs/Dialogs.stories.js +177 -0
- package/dist/components/Dialogs/FixedActionsDialog.d.ts +8 -0
- package/dist/components/Dialogs/FixedActionsDialog.js +20 -0
- package/dist/components/Dialogs/FixedDialog.d.ts +8 -0
- package/dist/components/Dialogs/FixedDialog.js +20 -0
- package/dist/components/Dialogs/IllustrationDialog.d.ts +8 -0
- package/dist/components/Dialogs/IllustrationDialog.js +21 -0
- package/dist/components/Dialogs/InstallFlagshipAppDialog.d.ts +13 -0
- package/dist/components/Dialogs/InstallFlagshipAppDialog.js +26 -0
- package/dist/components/Dialogs/PermissionDialog.d.ts +11 -0
- package/dist/components/Dialogs/PermissionDialog.js +15 -0
- package/dist/components/Dialogs/PermissionDialogIcon.d.ts +3 -0
- package/dist/components/Dialogs/PermissionDialogIcon.js +8 -0
- package/dist/components/Dialogs/ShortcutDialog.d.ts +15 -0
- package/dist/components/Dialogs/ShortcutDialog.js +41 -0
- package/dist/components/Dialogs/SlideUpTransition.d.ts +5 -0
- package/dist/components/Dialogs/SlideUpTransition.js +6 -0
- package/dist/components/Dialogs/SpecificDialogs.stories.d.ts +7 -0
- package/dist/components/Dialogs/SpecificDialogs.stories.js +43 -0
- package/dist/components/Dialogs/StandardDialog.d.ts +11 -0
- package/dist/components/Dialogs/StandardDialog.js +21 -0
- package/dist/components/Dialogs/images/appStore.png +0 -0
- package/dist/components/Dialogs/images/installFlagshipAppQrCode.png +0 -0
- package/dist/components/Dialogs/images/playStore.png +0 -0
- package/dist/components/Dialogs/locales/de.json +25 -0
- package/dist/components/Dialogs/locales/en.json +25 -0
- package/dist/components/Dialogs/locales/es.json +25 -0
- package/dist/components/Dialogs/locales/fr.json +25 -0
- package/dist/components/Dialogs/locales/index.d.ts +177 -0
- package/dist/components/Dialogs/locales/index.js +8 -0
- package/dist/components/Dialogs/locales/it.json +25 -0
- package/dist/components/Dialogs/locales/ru.json +25 -0
- package/dist/components/Dialogs/locales/vi.json +25 -0
- package/dist/components/Dialogs/shortcutHelpers.d.ts +19 -0
- package/dist/components/Dialogs/shortcutHelpers.js +49 -0
- package/dist/components/Dialogs/types.d.ts +7 -0
- package/dist/components/Dialogs/types.js +1 -0
- package/dist/components/Dialogs/useDialogLayout.d.ts +40 -0
- package/dist/components/Dialogs/useDialogLayout.js +63 -0
- package/dist/index.d.ts +24 -1
- package/dist/index.js +12 -1
- package/dist/lib/overrides.js +71 -6
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
# @linagora/twake-mui [16.0.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@15.2.0...@linagora/twake-mui@16.0.0) (2026-10-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Code Refactoring
|
|
5
|
+
|
|
6
|
+
* **twake-mui:** Export Dialog as default only ([ed447eb](https://github.com/linagora/twake-ui/commit/ed447eb8041974c1b4d3b55bb7160740003a787e))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **twake-mui:** Migrate ConfirmDialog from cozy-ui ([62098f2](https://github.com/linagora/twake-ui/commit/62098f26bafbf660126e9a408fbb650d3914187b))
|
|
12
|
+
* **twake-mui:** Migrate FixedActionsDialog from cozy-ui ([61c34b1](https://github.com/linagora/twake-ui/commit/61c34b12069ab66d59498342790a26508f00d8a2))
|
|
13
|
+
* **twake-mui:** Migrate FixedDialog from cozy-ui ([bb6ba7f](https://github.com/linagora/twake-ui/commit/bb6ba7f66938fff8bd8cc51ab9c17c7554119394))
|
|
14
|
+
* **twake-mui:** Migrate IllustrationDialog from cozy-ui ([ba5525e](https://github.com/linagora/twake-ui/commit/ba5525ef40e9ec4d018c62ef96f9d6d8806c17fa))
|
|
15
|
+
* **twake-mui:** Migrate InstallFlagshipAppDialog from cozy-ui ([4869572](https://github.com/linagora/twake-ui/commit/48695729c9c89651d21f10140fa3fd83c6e2b1d4))
|
|
16
|
+
* **twake-mui:** Migrate PermissionDialog from cozy-ui ([b8f9628](https://github.com/linagora/twake-ui/commit/b8f962838b91c23b85d8528b07504be79d46f33f))
|
|
17
|
+
* **twake-mui:** Migrate ShortcutDialog from cozy-ui ([74c0614](https://github.com/linagora/twake-ui/commit/74c061468784736d77ef3a738b20ba4d0bfece15))
|
|
18
|
+
* **twake-mui:** Migrate StandardDialog from cozy-ui ([a43530f](https://github.com/linagora/twake-ui/commit/a43530f7906a39a518ae97a15b0e006d1e46ab71))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### BREAKING CHANGES
|
|
22
|
+
|
|
23
|
+
* **twake-mui:** DialogDefault is no longer exported. Import Dialog
|
|
24
|
+
instead.
|
|
25
|
+
|
|
1
26
|
# @linagora/twake-mui [15.2.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@15.1.0...@linagora/twake-mui@15.2.0) (2026-10-19)
|
|
2
27
|
|
|
3
28
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CrossMedium, FileTypeFolder, FileTypeText, Icon } from '@linagora/twake-icons';
|
|
2
2
|
import { Button, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, IconButton, List, ListItemIcon, Stack } from '@mui/material';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import
|
|
4
|
+
import Dialog from './index';
|
|
5
5
|
import ListItemButton from '../ListItemButton';
|
|
6
6
|
import ListItemText from '../ListItemText';
|
|
7
7
|
const sizes = ['small', 'medium', 'large', 'full'];
|
|
@@ -5,5 +5,5 @@ export interface DialogProps extends MuiDialogProps {
|
|
|
5
5
|
/** Paper width. Every size but `small` goes full screen on mobile */
|
|
6
6
|
size?: DialogSize;
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
declare const Dialog: React.FC<DialogProps>;
|
|
9
9
|
export default Dialog;
|
|
@@ -2,7 +2,7 @@ import { Dialog as MuiDialog } from '@mui/material';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { useBreakpoints } from '../../hooks/useBreakpoints';
|
|
5
|
-
|
|
5
|
+
const Dialog = ({ size = 'medium', fullScreen, classes, ...props }) => {
|
|
6
6
|
const { isMobile } = useBreakpoints();
|
|
7
7
|
return (React.createElement(MuiDialog, { fullScreen: fullScreen ?? (size !== 'small' && isMobile), classes: { ...classes, paper: cx(size, classes?.paper) }, ...props }));
|
|
8
8
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DialogSectionsProps } from './types';
|
|
3
|
+
import { DialogLayoutProps } from './useDialogLayout';
|
|
4
|
+
export interface ConfirmDialogProps extends DialogLayoutProps, DialogSectionsProps {
|
|
5
|
+
}
|
|
6
|
+
/** Small dialog asking to confirm an action, its title scrolling with the content */
|
|
7
|
+
declare const ConfirmDialog: ({ size, title, content, actions, actionsLayout, ...props }: ConfirmDialogProps) => React.ReactElement;
|
|
8
|
+
export default ConfirmDialog;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DialogContent, DialogTitle } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import DialogFluidContent from './DialogFluidContent';
|
|
4
|
+
import DialogNavButtons from './DialogNavButtons';
|
|
5
|
+
import { useDialogLayout } from './useDialogLayout';
|
|
6
|
+
import Dialog from '../Dialog';
|
|
7
|
+
/** Small dialog asking to confirm an action, its title scrolling with the content */
|
|
8
|
+
const ConfirmDialog = ({ size = 'small', title, content, actions, actionsLayout, ...props }) => {
|
|
9
|
+
const { id, fullScreen, dialogProps, dialogTitleProps, dialogActionsProps, dialogContentProps } = useDialogLayout({ ...props, size, isFluidTitle: true });
|
|
10
|
+
return (React.createElement(Dialog, { ...dialogProps },
|
|
11
|
+
React.createElement(DialogNavButtons, { id: id, fullScreen: fullScreen, onClose: props.onClose, onBack: props.onBack }),
|
|
12
|
+
React.createElement(DialogContent, { ...dialogContentProps },
|
|
13
|
+
React.createElement(DialogFluidContent, { header: title && (React.createElement("div", { className: "dialogTitleFluidContainer" },
|
|
14
|
+
React.createElement(DialogTitle, { ...dialogTitleProps }, title))), content: content, actions: actions, actionsLayout: actionsLayout, dialogActionsProps: dialogActionsProps }))));
|
|
15
|
+
};
|
|
16
|
+
export default ConfirmDialog;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IconButtonProps } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface DialogBackButtonProps extends IconButtonProps {
|
|
4
|
+
onClick: NonNullable<IconButtonProps['onClick']>;
|
|
5
|
+
}
|
|
6
|
+
/** Back button pinned to the top left corner of a dialog */
|
|
7
|
+
declare const DialogBackButton: ({ className, ...props }: DialogBackButtonProps) => React.ReactElement;
|
|
8
|
+
export default DialogBackButton;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Icon, Previous } from '@linagora/twake-icons';
|
|
2
|
+
import { IconButton } from '@mui/material';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useExtendI18n, useI18n } from 'twake-i18n';
|
|
6
|
+
import { locales } from './locales';
|
|
7
|
+
/** Back button pinned to the top left corner of a dialog */
|
|
8
|
+
const DialogBackButton = ({ className, ...props }) => {
|
|
9
|
+
useExtendI18n(locales);
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
return (React.createElement(IconButton, { ...props, "aria-label": t('Dialogs.backButton'), className: cx('dialogIconButton', 'dialogBackButton', className), size: "medium" },
|
|
12
|
+
React.createElement(Icon, { icon: Previous })));
|
|
13
|
+
};
|
|
14
|
+
export default DialogBackButton;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IconButtonProps } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface DialogCloseButtonProps extends IconButtonProps {
|
|
4
|
+
onClick: NonNullable<IconButtonProps['onClick']>;
|
|
5
|
+
}
|
|
6
|
+
/** Close button pinned to the top right corner of a dialog */
|
|
7
|
+
declare const DialogCloseButton: ({ className, ...props }: DialogCloseButtonProps) => React.ReactElement;
|
|
8
|
+
export default DialogCloseButton;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CrossMedium, Icon } from '@linagora/twake-icons';
|
|
2
|
+
import { IconButton } from '@mui/material';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useExtendI18n, useI18n } from 'twake-i18n';
|
|
6
|
+
import { locales } from './locales';
|
|
7
|
+
/** Close button pinned to the top right corner of a dialog */
|
|
8
|
+
const DialogCloseButton = ({ className, ...props }) => {
|
|
9
|
+
useExtendI18n(locales);
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
return (React.createElement(IconButton, { ...props, "aria-label": t('Dialogs.closeButton'), className: cx('dialogIconButton', 'dialogCloseButton', className), size: "medium" },
|
|
12
|
+
React.createElement(Icon, { icon: CrossMedium })));
|
|
13
|
+
};
|
|
14
|
+
export default DialogCloseButton;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DialogActionsProps } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { DialogSectionsProps } from './types';
|
|
4
|
+
export interface DialogFluidContentProps extends Omit<DialogSectionsProps, 'title'> {
|
|
5
|
+
/** Rendered above the content, inside the scrolling area */
|
|
6
|
+
header?: React.ReactNode;
|
|
7
|
+
dialogActionsProps: DialogActionsProps;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Content of a dialog whose actions follow the content, and stick to the bottom of the screen on mobile */
|
|
11
|
+
declare const DialogFluidContent: ({ header, content, actions, actionsLayout, dialogActionsProps, className }: DialogFluidContentProps) => React.ReactElement;
|
|
12
|
+
export default DialogFluidContent;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DialogActions } from '@mui/material';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/** Content of a dialog whose actions follow the content, and stick to the bottom of the screen on mobile */
|
|
5
|
+
const DialogFluidContent = ({ header, content, actions, actionsLayout, dialogActionsProps, className }) => (React.createElement("div", { className: cx('dialogContentInner withFluidActions', className) },
|
|
6
|
+
header,
|
|
7
|
+
React.createElement("div", { className: cx('dialogContentWrapper', {
|
|
8
|
+
withActions: Boolean(actions)
|
|
9
|
+
}) }, content),
|
|
10
|
+
actions && (React.createElement(DialogActions, { ...dialogActionsProps, disableSpacing: true, className: cx('dialogActionsFluid', { columnLayout: actionsLayout === 'column' }, dialogActionsProps.className) }, actions))));
|
|
11
|
+
export default DialogFluidContent;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DialogLayoutProps } from './useDialogLayout';
|
|
3
|
+
export interface DialogNavButtonsProps extends Pick<DialogLayoutProps, 'onClose' | 'onBack'> {
|
|
4
|
+
id: string;
|
|
5
|
+
fullScreen: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Close and back buttons of a dialog. On full screen, a single back button calls `onBack`, or `onClose` without it */
|
|
8
|
+
declare const DialogNavButtons: ({ id, fullScreen, onClose, onBack }: DialogNavButtonsProps) => React.ReactElement | null;
|
|
9
|
+
export default DialogNavButtons;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import DialogBackButton from './DialogBackButton';
|
|
3
|
+
import DialogCloseButton from './DialogCloseButton';
|
|
4
|
+
/** Close and back buttons of a dialog. On full screen, a single back button calls `onBack`, or `onClose` without it */
|
|
5
|
+
const DialogNavButtons = ({ id, fullScreen, onClose, onBack }) => {
|
|
6
|
+
const onBackOrClose = onBack ?? onClose;
|
|
7
|
+
if (fullScreen) {
|
|
8
|
+
return onBackOrClose ? (React.createElement(DialogBackButton, { onClick: onBackOrClose, "data-testid": `modal-backclose-button-${id}` })) : null;
|
|
9
|
+
}
|
|
10
|
+
return (React.createElement(React.Fragment, null,
|
|
11
|
+
onClose && (React.createElement(DialogCloseButton, { onClick: onClose, "data-testid": `modal-close-button-${id}` })),
|
|
12
|
+
onBack && (React.createElement(DialogBackButton, { onClick: onBack, "data-testid": `modal-back-button-${id}` }))));
|
|
13
|
+
};
|
|
14
|
+
export default DialogNavButtons;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { StandardDialogProps } from './StandardDialog';
|
|
4
|
+
declare const dialogs: {
|
|
5
|
+
StandardDialog: ({ title, content, actions, actionsLayout, ...props }: StandardDialogProps) => React.ReactElement;
|
|
6
|
+
ConfirmDialog: ({ size, title, content, actions, actionsLayout, ...props }: import("./ConfirmDialog").ConfirmDialogProps) => React.ReactElement;
|
|
7
|
+
FixedDialog: ({ title, content, actions, actionsLayout, ...props }: import("./FixedDialog").FixedDialogProps) => React.ReactElement;
|
|
8
|
+
FixedActionsDialog: ({ title, content, actions, actionsLayout, ...props }: import("./FixedActionsDialog").FixedActionsDialogProps) => React.ReactElement;
|
|
9
|
+
IllustrationDialog: ({ title, content, actions, actionsLayout, ...props }: import("./IllustrationDialog").IllustrationDialogProps) => React.ReactElement;
|
|
10
|
+
PermissionDialog: React.FC<StandardDialogProps>;
|
|
11
|
+
};
|
|
12
|
+
type DialogName = keyof typeof dialogs;
|
|
13
|
+
interface StoryArgs extends Pick<StandardDialogProps, 'size' | 'actionsLayout' | 'align' | 'disableTitleAutoPadding' | 'disableGutters' | 'fullScreen'> {
|
|
14
|
+
dialog: DialogName;
|
|
15
|
+
contentLength: 'short' | 'long';
|
|
16
|
+
longTitle: boolean;
|
|
17
|
+
hideTitle: boolean;
|
|
18
|
+
showActions: boolean;
|
|
19
|
+
withCloseButton: boolean;
|
|
20
|
+
withBackButton: boolean;
|
|
21
|
+
withBackground: boolean;
|
|
22
|
+
titleWithButton: boolean;
|
|
23
|
+
}
|
|
24
|
+
declare const meta: Meta<StoryArgs>;
|
|
25
|
+
export default meta;
|
|
26
|
+
type Story = StoryObj<typeof meta>;
|
|
27
|
+
export declare const Default: Story;
|
|
28
|
+
export declare const StandardDialogScreenshot: Story;
|
|
29
|
+
export declare const ConfirmDialogScreenshot: Story;
|
|
30
|
+
export declare const FixedDialogScreenshot: Story;
|
|
31
|
+
export declare const FixedActionsDialogScreenshot: Story;
|
|
32
|
+
export declare const IllustrationDialogScreenshot: Story;
|
|
33
|
+
export declare const PermissionDialogScreenshot: Story;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Attachment, Cloud, Dots, Icon, Pen, People } from '@linagora/twake-icons';
|
|
2
|
+
import { Button, IconButton, ListItemIcon, Menu, MenuItem, Stack, Typography } from '@mui/material';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import ConfirmDialog from './ConfirmDialog';
|
|
5
|
+
import FixedActionsDialog from './FixedActionsDialog';
|
|
6
|
+
import FixedDialog from './FixedDialog';
|
|
7
|
+
import IllustrationDialog from './IllustrationDialog';
|
|
8
|
+
import PermissionDialog from './PermissionDialog';
|
|
9
|
+
import StandardDialog from './StandardDialog';
|
|
10
|
+
import AlertProvider from '../../providers/AlertProvider';
|
|
11
|
+
import { useAlert } from '../../providers/AlertProvider/useAlert';
|
|
12
|
+
import BottomSheet from '../BottomSheet';
|
|
13
|
+
import BottomSheetItem from '../BottomSheet/BottomSheetItem';
|
|
14
|
+
import ListItemText from '../ListItemText';
|
|
15
|
+
const sizes = ['small', 'medium', 'large', 'full'];
|
|
16
|
+
const SHORT_TEXT = 'Ada Lovelace was an English mathematician and writer, chiefly known for her work on the Analytical Engine.';
|
|
17
|
+
const LONG_TEXT = Array.from({ length: 8 }, () => `${SHORT_TEXT} She was the first to recognise that the machine had applications beyond pure calculation, and published the first algorithm intended to be carried out by such a machine. As a result, she is often regarded as the first computer programmer.`).join('\n\n');
|
|
18
|
+
const BACKGROUND = 'linear-gradient(to bottom, rgba(41, 127, 242, 0.24), transparent 160px)';
|
|
19
|
+
const noop = () => undefined;
|
|
20
|
+
const PermissionDialogExample = ({ open, title, content, actions, actionsLayout, onClose }) => (React.createElement(PermissionDialog, { open: open, icon: Cloud, title: typeof title === 'string' ? title : 'PermissionDialog', content: content, actions: actions, actionsLayout: actionsLayout, onClose: onClose }));
|
|
21
|
+
const dialogs = {
|
|
22
|
+
StandardDialog,
|
|
23
|
+
ConfirmDialog,
|
|
24
|
+
FixedDialog,
|
|
25
|
+
FixedActionsDialog,
|
|
26
|
+
IllustrationDialog,
|
|
27
|
+
PermissionDialog: PermissionDialogExample
|
|
28
|
+
};
|
|
29
|
+
const DialogActionsExample = ({ onClose }) => (React.createElement(React.Fragment, null,
|
|
30
|
+
React.createElement(Button, { variant: "outlined", onClick: onClose }, "Close Modal"),
|
|
31
|
+
React.createElement(Button, null, "Do something")));
|
|
32
|
+
const TitleWithButton = () => (React.createElement(React.Fragment, null,
|
|
33
|
+
"This is the title",
|
|
34
|
+
React.createElement(IconButton, { "aria-label": "More" },
|
|
35
|
+
React.createElement(Icon, { icon: Dots }))));
|
|
36
|
+
const titleWithButtonProps = {
|
|
37
|
+
dialogTitle: {
|
|
38
|
+
className: 'u-flex u-flex-items-center u-flex-justify-between u-pv-0-s u-pv-1 u-pr-0-s'
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const InnerElements = () => {
|
|
42
|
+
const { showAlert } = useAlert();
|
|
43
|
+
const [isBottomSheetOpen, setBottomSheetOpen] = useState(false);
|
|
44
|
+
const [isInnerDialogOpen, setInnerDialogOpen] = useState(false);
|
|
45
|
+
const [isInnerConfirmOpen, setInnerConfirmOpen] = useState(false);
|
|
46
|
+
const [isSheetConfirmOpen, setSheetConfirmOpen] = useState(false);
|
|
47
|
+
const [menuAnchor, setMenuAnchor] = useState(null);
|
|
48
|
+
const closeMenu = () => setMenuAnchor(null);
|
|
49
|
+
return (React.createElement(React.Fragment, null,
|
|
50
|
+
React.createElement(Stack, { spacing: 1, sx: { mt: 2, alignItems: 'flex-start' } },
|
|
51
|
+
React.createElement(Button, { onClick: () => showAlert({ message: 'Hello', severity: 'success', duration: 5000 }) }, "Show an alert"),
|
|
52
|
+
React.createElement(Button, { onClick: () => setBottomSheetOpen(true) }, "Show inner bottom sheet"),
|
|
53
|
+
React.createElement(Button, { onClick: () => setInnerConfirmOpen(true) }, "Show inner confirm dialog"),
|
|
54
|
+
React.createElement(Button, { onClick: () => setInnerDialogOpen(true) }, "Show inner dialog"),
|
|
55
|
+
React.createElement(Button, { onClick: event => setMenuAnchor(event.currentTarget) }, "Show menu")),
|
|
56
|
+
React.createElement(Menu, { open: Boolean(menuAnchor), anchorEl: menuAnchor, onClose: closeMenu }, [
|
|
57
|
+
{ icon: Pen, label: 'Modify' },
|
|
58
|
+
{ icon: People, label: 'People' },
|
|
59
|
+
{ icon: Attachment, label: 'Attachment' }
|
|
60
|
+
].map(({ icon, label }) => (React.createElement(MenuItem, { key: label, onClick: closeMenu },
|
|
61
|
+
React.createElement(ListItemIcon, null,
|
|
62
|
+
React.createElement(Icon, { icon: icon })),
|
|
63
|
+
React.createElement(ListItemText, { primary: label }))))),
|
|
64
|
+
isInnerDialogOpen && (React.createElement(StandardDialog, { open: true, onClose: () => setInnerDialogOpen(false), title: "This is a simple title", content: "This is a simple content" })),
|
|
65
|
+
isInnerConfirmOpen && (React.createElement(ConfirmDialog, { open: true, onClose: () => setInnerConfirmOpen(false), title: "This is a simple title", content: "This is a simple content" })),
|
|
66
|
+
isBottomSheetOpen && (React.createElement(BottomSheet, { backdrop: true, onClose: () => setBottomSheetOpen(false) },
|
|
67
|
+
React.createElement(BottomSheetItem, null,
|
|
68
|
+
React.createElement(Button, { onClick: () => setSheetConfirmOpen(true), sx: { mb: 2 } }, "Show inner confirm dialog"),
|
|
69
|
+
LONG_TEXT,
|
|
70
|
+
isSheetConfirmOpen && (React.createElement(ConfirmDialog, { open: true, onClose: () => setSheetConfirmOpen(false), title: "This is a simple title", content: "This is a simple content" })))))));
|
|
71
|
+
};
|
|
72
|
+
const Playground = ({ dialog, contentLength, longTitle, hideTitle, showActions, withCloseButton, withBackButton, withBackground, titleWithButton, fullScreen, ...props }) => {
|
|
73
|
+
const { showAlert } = useAlert();
|
|
74
|
+
const [open, setOpen] = useState(false);
|
|
75
|
+
const DialogComponent = dialogs[dialog];
|
|
76
|
+
const close = () => setOpen(false);
|
|
77
|
+
const goBack = () => {
|
|
78
|
+
showAlert({ message: 'Back button has been pressed', severity: 'success' });
|
|
79
|
+
close();
|
|
80
|
+
};
|
|
81
|
+
const title = dialog === 'IllustrationDialog' ? (React.createElement(Icon, { icon: Cloud, size: 140 })) : titleWithButton ? (React.createElement(TitleWithButton, null)) : longTitle ? (`${dialog} - ${SHORT_TEXT}`) : (dialog);
|
|
82
|
+
return (React.createElement(React.Fragment, null,
|
|
83
|
+
React.createElement(Button, { onClick: () => setOpen(true) },
|
|
84
|
+
"Open ",
|
|
85
|
+
dialog),
|
|
86
|
+
open && (React.createElement(DialogComponent, { ...props, size: dialog === 'ConfirmDialog' || dialog === 'PermissionDialog'
|
|
87
|
+
? undefined
|
|
88
|
+
: props.size, open: true, fullScreen: fullScreen || undefined, onClose: withCloseButton ? close : undefined, onBack: withBackButton ? goBack : undefined, title: hideTitle ? undefined : title, componentsProps: titleWithButton ? titleWithButtonProps : undefined, background: withBackground ? BACKGROUND : undefined, content: React.createElement(React.Fragment, null,
|
|
89
|
+
React.createElement(Typography, { component: "div", variant: "body1" }, contentLength === 'long' ? LONG_TEXT : SHORT_TEXT),
|
|
90
|
+
React.createElement(InnerElements, null)), actions: showActions && React.createElement(DialogActionsExample, { onClose: close }) }))));
|
|
91
|
+
};
|
|
92
|
+
const meta = {
|
|
93
|
+
title: 'Dialogs',
|
|
94
|
+
parameters: { layout: 'centered' },
|
|
95
|
+
tags: ['autodocs'],
|
|
96
|
+
decorators: [
|
|
97
|
+
(Story) => (React.createElement(AlertProvider, null,
|
|
98
|
+
React.createElement(Story, null)))
|
|
99
|
+
],
|
|
100
|
+
argTypes: {
|
|
101
|
+
dialog: { control: 'select', options: Object.keys(dialogs) },
|
|
102
|
+
size: { control: 'select', options: sizes },
|
|
103
|
+
actionsLayout: { control: 'inline-radio', options: ['row', 'column'] },
|
|
104
|
+
align: { control: 'inline-radio', options: ['middle', 'top'] },
|
|
105
|
+
contentLength: { control: 'inline-radio', options: ['short', 'long'] },
|
|
106
|
+
disableTitleAutoPadding: { control: 'boolean' },
|
|
107
|
+
disableGutters: { control: 'boolean' },
|
|
108
|
+
fullScreen: { control: 'boolean' },
|
|
109
|
+
longTitle: { control: 'boolean' },
|
|
110
|
+
hideTitle: { control: 'boolean' },
|
|
111
|
+
showActions: { control: 'boolean' },
|
|
112
|
+
withCloseButton: { control: 'boolean' },
|
|
113
|
+
withBackButton: { control: 'boolean' },
|
|
114
|
+
withBackground: { control: 'boolean' },
|
|
115
|
+
titleWithButton: { control: 'boolean' }
|
|
116
|
+
},
|
|
117
|
+
args: {
|
|
118
|
+
dialog: 'StandardDialog',
|
|
119
|
+
size: 'medium',
|
|
120
|
+
actionsLayout: 'row',
|
|
121
|
+
align: 'middle',
|
|
122
|
+
contentLength: 'short',
|
|
123
|
+
disableTitleAutoPadding: false,
|
|
124
|
+
disableGutters: false,
|
|
125
|
+
fullScreen: false,
|
|
126
|
+
longTitle: false,
|
|
127
|
+
hideTitle: false,
|
|
128
|
+
showActions: true,
|
|
129
|
+
withCloseButton: true,
|
|
130
|
+
withBackButton: false,
|
|
131
|
+
withBackground: false,
|
|
132
|
+
titleWithButton: false
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
export default meta;
|
|
136
|
+
export const Default = {
|
|
137
|
+
render: args => React.createElement(Playground, { ...args })
|
|
138
|
+
};
|
|
139
|
+
const screenshotProps = {
|
|
140
|
+
open: true,
|
|
141
|
+
onClose: noop,
|
|
142
|
+
content: SHORT_TEXT,
|
|
143
|
+
actions: React.createElement(DialogActionsExample, { onClose: noop })
|
|
144
|
+
};
|
|
145
|
+
// Visual Regression - one story per dialog, since each one covers the screen
|
|
146
|
+
export const StandardDialogScreenshot = {
|
|
147
|
+
tags: ['argos'],
|
|
148
|
+
parameters: { layout: 'fullscreen' },
|
|
149
|
+
render: () => React.createElement(StandardDialog, { ...screenshotProps, title: "StandardDialog" })
|
|
150
|
+
};
|
|
151
|
+
export const ConfirmDialogScreenshot = {
|
|
152
|
+
tags: ['argos'],
|
|
153
|
+
parameters: { layout: 'fullscreen' },
|
|
154
|
+
render: () => (React.createElement(ConfirmDialog, { ...screenshotProps, title: "Are you sure?", content: "Content of a confirm dialog, precising what the actions will do, and asking the user if she is sure.", actions: React.createElement(React.Fragment, null,
|
|
155
|
+
React.createElement(Button, { variant: "outlined" }, "Close Modal"),
|
|
156
|
+
React.createElement(Button, { color: "error" }, "Do something destructive")) }))
|
|
157
|
+
};
|
|
158
|
+
export const FixedDialogScreenshot = {
|
|
159
|
+
tags: ['argos'],
|
|
160
|
+
parameters: { layout: 'fullscreen' },
|
|
161
|
+
render: () => (React.createElement(FixedDialog, { ...screenshotProps, title: "FixedDialog", content: LONG_TEXT }))
|
|
162
|
+
};
|
|
163
|
+
export const FixedActionsDialogScreenshot = {
|
|
164
|
+
tags: ['argos'],
|
|
165
|
+
parameters: { layout: 'fullscreen' },
|
|
166
|
+
render: () => (React.createElement(FixedActionsDialog, { ...screenshotProps, title: "FixedActionsDialog", content: LONG_TEXT }))
|
|
167
|
+
};
|
|
168
|
+
export const IllustrationDialogScreenshot = {
|
|
169
|
+
tags: ['argos'],
|
|
170
|
+
parameters: { layout: 'fullscreen' },
|
|
171
|
+
render: () => (React.createElement(IllustrationDialog, { ...screenshotProps, size: "small", title: React.createElement(Icon, { icon: Cloud, size: 140 }) }))
|
|
172
|
+
};
|
|
173
|
+
export const PermissionDialogScreenshot = {
|
|
174
|
+
tags: ['argos'],
|
|
175
|
+
parameters: { layout: 'fullscreen' },
|
|
176
|
+
render: () => (React.createElement(PermissionDialogExample, { ...screenshotProps, title: "Are you sure?", content: "Content of a confirm dialog, precising what the actions will do, and asking the user if she is sure." }))
|
|
177
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DialogSectionsProps } from './types';
|
|
3
|
+
import { DialogLayoutProps } from './useDialogLayout';
|
|
4
|
+
export interface FixedActionsDialogProps extends DialogLayoutProps, DialogSectionsProps {
|
|
5
|
+
}
|
|
6
|
+
/** Dialog whose actions stay visible while the title scrolls with a long content */
|
|
7
|
+
declare const FixedActionsDialog: ({ title, content, actions, actionsLayout, ...props }: FixedActionsDialogProps) => React.ReactElement;
|
|
8
|
+
export default FixedActionsDialog;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DialogActions, DialogContent, DialogTitle, Divider } from '@mui/material';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import DialogNavButtons from './DialogNavButtons';
|
|
5
|
+
import { useDialogLayout } from './useDialogLayout';
|
|
6
|
+
import Dialog from '../Dialog';
|
|
7
|
+
/** Dialog whose actions stay visible while the title scrolls with a long content */
|
|
8
|
+
const FixedActionsDialog = ({ title, content, actions, actionsLayout, ...props }) => {
|
|
9
|
+
const { id, fullScreen, dialogProps, dialogTitleProps, dividerProps, dialogActionsProps, dialogContentProps } = useDialogLayout({ ...props, isFluidTitle: true });
|
|
10
|
+
return (React.createElement(Dialog, { ...dialogProps },
|
|
11
|
+
React.createElement(DialogNavButtons, { id: id, fullScreen: fullScreen, onClose: props.onClose, onBack: props.onBack }),
|
|
12
|
+
React.createElement(DialogContent, { ...dialogContentProps },
|
|
13
|
+
React.createElement("div", { className: "dialogContentInner" },
|
|
14
|
+
title && (React.createElement("div", { className: "dialogTitleFluidContainer" },
|
|
15
|
+
React.createElement(DialogTitle, { ...dialogTitleProps }, title))),
|
|
16
|
+
content)),
|
|
17
|
+
React.createElement(Divider, { ...dividerProps }),
|
|
18
|
+
actions && (React.createElement(DialogActions, { ...dialogActionsProps, disableSpacing: true, className: cx({ columnLayout: actionsLayout === 'column' }, dialogActionsProps.className) }, actions))));
|
|
19
|
+
};
|
|
20
|
+
export default FixedActionsDialog;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DialogSectionsProps } from './types';
|
|
3
|
+
import { DialogLayoutProps } from './useDialogLayout';
|
|
4
|
+
export interface FixedDialogProps extends DialogLayoutProps, DialogSectionsProps {
|
|
5
|
+
}
|
|
6
|
+
/** Dialog whose title and actions stay visible while a long content scrolls between them */
|
|
7
|
+
declare const FixedDialog: ({ title, content, actions, actionsLayout, ...props }: FixedDialogProps) => React.ReactElement;
|
|
8
|
+
export default FixedDialog;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DialogActions, DialogContent, DialogTitle, Divider } from '@mui/material';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import DialogNavButtons from './DialogNavButtons';
|
|
5
|
+
import { useDialogLayout } from './useDialogLayout';
|
|
6
|
+
import Dialog from '../Dialog';
|
|
7
|
+
/** Dialog whose title and actions stay visible while a long content scrolls between them */
|
|
8
|
+
const FixedDialog = ({ title, content, actions, actionsLayout, ...props }) => {
|
|
9
|
+
const { id, fullScreen, dialogProps, dialogTitleProps, dividerProps, dialogActionsProps, dialogContentProps } = useDialogLayout(props);
|
|
10
|
+
return (React.createElement(Dialog, { ...dialogProps },
|
|
11
|
+
React.createElement(DialogNavButtons, { id: id, fullScreen: fullScreen, onClose: props.onClose, onBack: props.onBack }),
|
|
12
|
+
title && (React.createElement(React.Fragment, null,
|
|
13
|
+
React.createElement(DialogTitle, { ...dialogTitleProps }, title),
|
|
14
|
+
React.createElement(Divider, { ...dividerProps }))),
|
|
15
|
+
React.createElement(DialogContent, { ...dialogContentProps },
|
|
16
|
+
React.createElement("div", { className: "dialogContentInner" }, content)),
|
|
17
|
+
React.createElement(Divider, { ...dividerProps }),
|
|
18
|
+
actions && (React.createElement(DialogActions, { ...dialogActionsProps, disableSpacing: true, className: cx({ columnLayout: actionsLayout === 'column' }, dialogActionsProps.className) }, actions))));
|
|
19
|
+
};
|
|
20
|
+
export default FixedDialog;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DialogSectionsProps } from './types';
|
|
3
|
+
import { DialogLayoutProps } from './useDialogLayout';
|
|
4
|
+
export interface IllustrationDialogProps extends DialogLayoutProps, DialogSectionsProps {
|
|
5
|
+
}
|
|
6
|
+
/** Dialog whose title is an illustration, centered above a short content */
|
|
7
|
+
declare const IllustrationDialog: ({ title, content, actions, actionsLayout, ...props }: IllustrationDialogProps) => React.ReactElement;
|
|
8
|
+
export default IllustrationDialog;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DialogContent, DialogTitle } from '@mui/material';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import DialogFluidContent from './DialogFluidContent';
|
|
5
|
+
import DialogNavButtons from './DialogNavButtons';
|
|
6
|
+
import { useDialogLayout } from './useDialogLayout';
|
|
7
|
+
import Dialog from '../Dialog';
|
|
8
|
+
/** Dialog whose title is an illustration, centered above a short content */
|
|
9
|
+
const IllustrationDialog = ({ title, content, actions, actionsLayout, ...props }) => {
|
|
10
|
+
const { id, fullScreen, dialogProps, dialogTitleProps, dialogActionsProps, dialogContentProps } = useDialogLayout({
|
|
11
|
+
...props,
|
|
12
|
+
isFluidTitle: true,
|
|
13
|
+
disableTitleAutoPadding: true
|
|
14
|
+
});
|
|
15
|
+
return (React.createElement(Dialog, { ...dialogProps },
|
|
16
|
+
React.createElement(DialogNavButtons, { id: id, fullScreen: fullScreen, onClose: props.onClose, onBack: props.onBack }),
|
|
17
|
+
React.createElement(DialogContent, { ...dialogContentProps },
|
|
18
|
+
React.createElement(DialogFluidContent, { className: "u-pt-1-half", header: title && (React.createElement("div", { className: "dialogTitleFluidContainer" },
|
|
19
|
+
React.createElement(DialogTitle, { ...dialogTitleProps, className: cx('u-flex u-flex-justify-center', dialogTitleProps.className) }, title))), content: content, actions: actions, actionsLayout: actionsLayout, dialogActionsProps: dialogActionsProps }))));
|
|
20
|
+
};
|
|
21
|
+
export default IllustrationDialog;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface InstallFlagshipAppDialogProps {
|
|
3
|
+
onClose?: () => void;
|
|
4
|
+
/** Play Store link of the description */
|
|
5
|
+
playStoreUrl?: string;
|
|
6
|
+
/** App Store link of the description */
|
|
7
|
+
appStoreUrl?: string;
|
|
8
|
+
/** Image of a QR code leading to the download page of the app */
|
|
9
|
+
QRCode?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Invites to install the mobile app, through a QR code or the stores */
|
|
12
|
+
declare const InstallFlagshipAppDialog: ({ onClose, playStoreUrl, appStoreUrl, QRCode }: InstallFlagshipAppDialogProps) => React.ReactElement;
|
|
13
|
+
export default InstallFlagshipAppDialog;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Link, Typography } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useExtendI18n, useI18n } from 'twake-i18n';
|
|
4
|
+
import IllustrationDialog from './IllustrationDialog';
|
|
5
|
+
import appStoreIcon from './images/appStore.png';
|
|
6
|
+
import defaultQrCode from './images/installFlagshipAppQrCode.png';
|
|
7
|
+
import playStoreIcon from './images/playStore.png';
|
|
8
|
+
import { locales } from './locales';
|
|
9
|
+
/** Invites to install the mobile app, through a QR code or the stores */
|
|
10
|
+
const InstallFlagshipAppDialog = ({ onClose, playStoreUrl = 'https://play.google.com/store/apps/details?id=io.cozy.flagship.mobile', appStoreUrl = 'https://apps.apple.com/app/my-cozy/id1600636174', QRCode = defaultQrCode }) => {
|
|
11
|
+
useExtendI18n(locales);
|
|
12
|
+
const { t } = useI18n();
|
|
13
|
+
return (React.createElement(IllustrationDialog, { open: true, size: "small", onClose: onClose, componentsProps: { dialogTitle: { className: 'u-pt-2-half' } }, title: React.createElement(Link, { href: "https://cozy.io/download", target: "_blank", rel: "noopener noreferrer" },
|
|
14
|
+
React.createElement("img", { src: QRCode, width: "100%", alt: "", "aria-hidden": true }),
|
|
15
|
+
React.createElement("span", { className: "u-visuallyhidden" }, t('Dialogs.installFlagshipApp.linkLabel'))), content: React.createElement("div", { className: "u-ta-center" },
|
|
16
|
+
React.createElement(Typography, { gutterBottom: true, variant: "h3", color: "text.primary" }, t('Dialogs.installFlagshipApp.title')),
|
|
17
|
+
React.createElement(Typography, { color: "text.secondary", className: "u-ta-center", dangerouslySetInnerHTML: {
|
|
18
|
+
__html: t('Dialogs.installFlagshipApp.text', {
|
|
19
|
+
androidUrl: playStoreUrl,
|
|
20
|
+
androidIconSrc: playStoreIcon,
|
|
21
|
+
iosUrl: appStoreUrl,
|
|
22
|
+
iosIconSrc: appStoreIcon
|
|
23
|
+
})
|
|
24
|
+
} })) }));
|
|
25
|
+
};
|
|
26
|
+
export default InstallFlagshipAppDialog;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Icon } from '@linagora/twake-icons';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ConfirmDialogProps } from './ConfirmDialog';
|
|
4
|
+
export interface PermissionDialogProps extends Pick<ConfirmDialogProps, 'open' | 'content' | 'actions' | 'actionsLayout' | 'onClose'> {
|
|
5
|
+
/** Describes the action to be taken */
|
|
6
|
+
icon: React.ComponentProps<typeof Icon>['icon'];
|
|
7
|
+
title: string;
|
|
8
|
+
}
|
|
9
|
+
/** Dialog confirming an action on the system, such as a permission or an authentication */
|
|
10
|
+
declare const PermissionDialog: ({ open, icon, title, content, actions, actionsLayout, onClose }: PermissionDialogProps) => React.ReactElement;
|
|
11
|
+
export default PermissionDialog;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Icon } from '@linagora/twake-icons';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ConfirmDialog from './ConfirmDialog';
|
|
4
|
+
import PermissionDialogIcon from './PermissionDialogIcon';
|
|
5
|
+
/** Dialog confirming an action on the system, such as a permission or an authentication */
|
|
6
|
+
const PermissionDialog = ({ open, icon, title, content, actions, actionsLayout, onClose }) => (React.createElement(ConfirmDialog, { open: open, size: "small", disableTitleAutoPadding: true, classes: { paper: 'u-ov-visible' }, componentsProps: {
|
|
7
|
+
dialogTitle: {
|
|
8
|
+
className: 'u-flex u-flex-justify-center u-ta-center u-pt-2 u-pb-half'
|
|
9
|
+
},
|
|
10
|
+
dialogContent: { className: 'u-ov-visible' }
|
|
11
|
+
}, title: React.createElement(React.Fragment, null,
|
|
12
|
+
React.createElement(PermissionDialogIcon, { elevation: 2, className: "u-pos-absolute u-bdrs-circle u-flex" },
|
|
13
|
+
React.createElement(Icon, { className: "u-m-auto", icon: icon, size: 48 })),
|
|
14
|
+
title), content: content, actions: actions, actionsLayout: actionsLayout, onClose: onClose }));
|
|
15
|
+
export default PermissionDialog;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Round paper floating above the top edge of a permission dialog */
|
|
2
|
+
declare const PermissionDialogIcon: import("@emotion/styled").StyledComponent<import("@mui/material").PaperOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style" | "square" | "className" | "elevation" | "children" | "classes" | "sx" | "variant"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
3
|
+
export default PermissionDialogIcon;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Paper, styled } from '@mui/material';
|
|
2
|
+
/** Round paper floating above the top edge of a permission dialog */
|
|
3
|
+
const PermissionDialogIcon = styled(Paper)({
|
|
4
|
+
top: '-2.25rem',
|
|
5
|
+
width: '4.5rem',
|
|
6
|
+
height: '4.5rem'
|
|
7
|
+
});
|
|
8
|
+
export default PermissionDialogIcon;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SaveShortcut } from './shortcutHelpers';
|
|
3
|
+
export interface ShortcutDialogProps {
|
|
4
|
+
/** Shortcut to edit, which prefills the fields */
|
|
5
|
+
shortcut?: {
|
|
6
|
+
name?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Called with the file name and the URL of the shortcut */
|
|
10
|
+
onSave: SaveShortcut;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}
|
|
13
|
+
/** Creates or edits a shortcut to a URL. Must be rendered within an `AlertProvider` */
|
|
14
|
+
declare const ShortcutDialog: ({ shortcut, onSave, onClose }: ShortcutDialogProps) => React.ReactElement;
|
|
15
|
+
export default ShortcutDialog;
|