feat: DialogProvider component (#198)
* feat: somewhat working DialogProvider * feat: handle multiple dialogs properly, initial focus let's just ignore that showFocus=true doesn't work with "nested" dialogs Co-authored-by: Razboy20 <Razboy20@users.noreply.github.com> * feat: rework code * feat: add default styles to prompts * refactor: fix stylings --------- Co-authored-by: Razboy20 <Razboy20@users.noreply.github.com> Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
169
src/stories/components/DialogProvider.stories.tsx
Normal file
169
src/stories/components/DialogProvider.stories.tsx
Normal file
@@ -0,0 +1,169 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Button } from '@views/components/common/Button';
|
||||
import DialogProvider, { usePrompt } from '@views/components/common/DialogProvider/DialogProvider';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import MaterialSymbolsExpandAllRoundedIcon from '~icons/material-symbols/expand-all-rounded';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Common/DialogProvider',
|
||||
component: DialogProvider,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
args: {},
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof DialogProvider>;
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: { children: undefined },
|
||||
render: () => (
|
||||
<DialogProvider>
|
||||
<InnerComponent />
|
||||
</DialogProvider>
|
||||
),
|
||||
};
|
||||
|
||||
const InnerComponent = () => {
|
||||
const showDialog = usePrompt();
|
||||
|
||||
const myShow = () => {
|
||||
showDialog({
|
||||
title: 'Dialog Title',
|
||||
description: 'Dialog Description',
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
buttons: close => (
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
Close
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Button variant='filled' color='ut-burntorange' icon={MaterialSymbolsExpandAllRoundedIcon} onClick={myShow}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const FiveDialogs: Story = {
|
||||
args: { children: undefined },
|
||||
render: () => (
|
||||
<DialogProvider>
|
||||
<Text variant='p'>They'll open with 100ms delay</Text>
|
||||
<FiveDialogsInnerComponent />
|
||||
</DialogProvider>
|
||||
),
|
||||
};
|
||||
|
||||
const FiveDialogsInnerComponent = () => {
|
||||
const showDialog = usePrompt();
|
||||
|
||||
const myShow = () => {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
setTimeout(
|
||||
() =>
|
||||
showDialog({
|
||||
title: `Dialog #${i}`,
|
||||
description:
|
||||
'Deleting Main Schedule is permanent and will remove all added courses from that schedule.',
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
buttons: close => (
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
Close
|
||||
</Button>
|
||||
),
|
||||
}),
|
||||
100 * i
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Button variant='filled' color='ut-burntorange' icon={MaterialSymbolsExpandAllRoundedIcon} onClick={myShow}>
|
||||
Open Dialogs
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const NestedDialogs: Story = {
|
||||
args: { children: undefined },
|
||||
render: () => (
|
||||
<DialogProvider>
|
||||
<NestedDialogsInnerComponent />
|
||||
</DialogProvider>
|
||||
),
|
||||
};
|
||||
|
||||
const NestedDialogsInnerComponent = () => {
|
||||
const showDialog = usePrompt();
|
||||
|
||||
const myShow = () => {
|
||||
showDialog({
|
||||
title: 'Dialog Title',
|
||||
description: 'Dialog Description',
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
buttons: close => (
|
||||
<>
|
||||
<NestedDialogsInnerComponent />
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
Close
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Button variant='filled' color='ut-burntorange' icon={MaterialSymbolsExpandAllRoundedIcon} onClick={myShow}>
|
||||
Open Next Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const DialogWithOnClose: Story = {
|
||||
args: { children: undefined },
|
||||
render: () => (
|
||||
<DialogProvider>
|
||||
<DialogWithOnCloseInnerComponent />
|
||||
</DialogProvider>
|
||||
),
|
||||
};
|
||||
|
||||
const DialogWithOnCloseInnerComponent = () => {
|
||||
const showDialog = usePrompt();
|
||||
const [timesClosed, setTimesClosed] = useState(0);
|
||||
|
||||
const myShow = () => {
|
||||
showDialog({
|
||||
title: 'Dialog Title',
|
||||
description: 'Dialog Description',
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
buttons: close => (
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
Close
|
||||
</Button>
|
||||
),
|
||||
onClose: () => {
|
||||
setTimesClosed(prev => prev + 1);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>
|
||||
You closed the button below {timesClosed} {timesClosed === 1 ? 'time' : 'times'}
|
||||
</h1>
|
||||
<Button variant='filled' color='ut-burntorange' icon={MaterialSymbolsExpandAllRoundedIcon} onClick={myShow}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user