-
Notifications
You must be signed in to change notification settings - Fork 10
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
fix(Modal): animation update, new variant, close button always visible #1224
Changes from 5 commits
e093fde
d9e1a83
9e62613
266d9e1
4fa9168
79dc1a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||
import { ArgTypes, Meta, Title } from '@storybook/blocks'; | ||||||
import { ArgTypes, Meta, Title, Canvas } from '@storybook/blocks'; | ||||||
|
||||||
import * as ModalStories from './Modal.stories'; | ||||||
|
||||||
|
@@ -8,24 +8,31 @@ import * as ModalStories from './Modal.stories'; | |||||
|
||||||
[Component API](#ComponentAPI) | [Content Spec](#ContentSpec) | ||||||
|
||||||
## How to use modals | ||||||
|
||||||
### Default Modal | ||||||
|
||||||
Default Modal window is used to gather user input without navigating away from the current page. | ||||||
|
||||||
Use it for Data Entry: | ||||||
- <b>Edit</b> details or preferences. | ||||||
- <b>Invite</b> agents | ||||||
- <b>Gather</b> necessary information for specific tasks | ||||||
|
||||||
Modal includes: | ||||||
|
||||||
- Form fields | ||||||
- Labels and placeholders for guidance | ||||||
- Error messages and validation | ||||||
- Submit (Primary button kind) and cancel buttons (Secondary, Plain buttons kinds) | ||||||
|
||||||
<Canvas of={ModalStories.Modal} sourceState="none" /> | ||||||
|
||||||
#### Example implementation | ||||||
|
||||||
```jsx | ||||||
import { GreetingQuickReply } from '@livechat/design-system-icons'; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add the import statements |
||||||
|
||||||
<Modal | ||||||
heading={ | ||||||
<ModalHeader | ||||||
title="Modal Header" | ||||||
iconProps={{ | ||||||
source: GreetingQuickReply, | ||||||
kind: 'primary', | ||||||
size: 'large', | ||||||
}} | ||||||
> | ||||||
Modal description | ||||||
</ModalHeader> | ||||||
} | ||||||
heading='Modal header' | ||||||
footer={ | ||||||
<div> | ||||||
<Button size="medium" kind="secondary"> | ||||||
|
@@ -39,7 +46,111 @@ import { GreetingQuickReply } from '@livechat/design-system-icons'; | |||||
onClose={() => {}} | ||||||
> | ||||||
Modal content | ||||||
</Modal>; | ||||||
</Modal> | ||||||
``` | ||||||
|
||||||
### Action Modal - Info <a id="ActionModalInfo" /> | ||||||
|
||||||
Info modal used to provide important information without requiring immediate action. | ||||||
|
||||||
Use it for: | ||||||
- <b>General notifications</b> - Inform users about updates, news, or general information that doesn’t need immediate action. | ||||||
- <b>Instructions or tips</b> - Provide guidance or tips related to the current task or feature. | ||||||
- <b>Announcements</b> - Share announcements, such as new features, upcoming maintenance, or scheduled downtime. | ||||||
- <b>Confirmation of actions</b> - Confirm that an action has been successfully completed (e.g., "Your changes have been saved"). | ||||||
- <b>Educational content</b> - Offer tutorials, walkthroughs, or additional information about how to use a feature. | ||||||
|
||||||
Info modal includes: | ||||||
- An icon to indicate the type of information (e.g., info icon). | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
- Action Title | ||||||
- Action Description | ||||||
- An acknowledgment primary button (e.g., "OK", "Got it"). | ||||||
- Optional secondary button if further action might be needed (e.g., "Learn More"). | ||||||
- Close icon | ||||||
|
||||||
<Canvas of={ModalStories.ActionModal} sourceState="none" /> | ||||||
|
||||||
#### Example implementation | ||||||
|
||||||
```jsx | ||||||
<Modal {...props}> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add the import statements |
||||||
<ActionModalContent | ||||||
icon={ | ||||||
<Icon | ||||||
source={Error} | ||||||
size="xxxlarge" | ||||||
customColor="var(--content-basic-disabled)" | ||||||
/> | ||||||
} | ||||||
heading="Action Modal Header" | ||||||
actions={ | ||||||
<> | ||||||
<Button size="large">Button</Button> | ||||||
<Button size="large" kind="primary"> | ||||||
Button | ||||||
</Button> | ||||||
</> | ||||||
} | ||||||
> | ||||||
Amet minim mollit non deserunt ullamco est sit aliqua dolor do amet sint. | ||||||
Velit officia consequat duis enim velit mollit. Exercitation veniam | ||||||
consequat sunt nostrud amet. | ||||||
</ActionModalContent> | ||||||
</Modal> | ||||||
``` | ||||||
|
||||||
### Action Modal - Confirmation | ||||||
|
||||||
A Confirmation Modal is used to verify a user's intent before proceeding with important actions. | ||||||
|
||||||
Use it in these scenarios: | ||||||
- <b>Deleting Data</b>: Prevent accidental data loss. | ||||||
- <b>Submitting a Form</b>: Confirm critical information submission. | ||||||
- <b>Exiting or Logging Out</b>: Ensure unsaved changes are saved or confirm exit. | ||||||
- <b>Executing a Command</b>: Double-check significant commands (e.g., start/stop services). | ||||||
- <b>Irreversible Actions</b>: Confirm actions that cannot be undone. | ||||||
|
||||||
Confirmation modal includes: | ||||||
- Attention icon. (error) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
- Action Title | ||||||
- Action Description | ||||||
- Primary (kind=Destructive) and secondary buttons (optional). | ||||||
- Close icon | ||||||
|
||||||
The implementation is the same as [Action Modal - Info](#ActionModalInfo) | ||||||
|
||||||
### Full space content “Promo modal” | ||||||
|
||||||
A Promotional Modal is used to introduce new features or updates to users in an engaging way. | ||||||
|
||||||
Use it for: | ||||||
- <b>New Feature Announcements</b>: Highlight and explain new features or tools. | ||||||
- <b>Product Updates</b>: Inform users about major updates or improvements. | ||||||
- <b>Special Offers</b>: Promote limited-time deals, discounts, or promotions. | ||||||
- <b>User Onboarding</b>: Guide new users through key features and benefits. | ||||||
- <b>Engagement Boost</b>: Encourage users to try out new or underused features. | ||||||
|
||||||
<Canvas of={ModalStories.ModalWithFullSpaceContent} sourceState="none" /> | ||||||
|
||||||
```jsx | ||||||
<Modal | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add the import statements |
||||||
labelHeading={ | ||||||
<ModalHeader | ||||||
title="Modal Header" | ||||||
avatarProps={{ | ||||||
type: 'image', | ||||||
size: 'small', | ||||||
src: 'https://cdn-labs.livechat-files.com/api/file/lc/img/100019504/df59da4b5b0cdb6030efb08787fd255d.jpg', | ||||||
}} | ||||||
> | ||||||
{' '} | ||||||
Modal description{' '} | ||||||
</ModalHeader> | ||||||
} | ||||||
fullSpaceContent | ||||||
> | ||||||
<YourCustomStyledContent /> | ||||||
</Modal> | ||||||
``` | ||||||
|
||||||
## Component API <a id="ComponentAPI" /> | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
import * as React from 'react'; | ||
|
||
import { GreetingQuickReply } from '@livechat/design-system-icons'; | ||
import { GreetingQuickReply, Error } from '@livechat/design-system-icons'; | ||
import { Meta, StoryFn } from '@storybook/react'; | ||
|
||
import noop from '../../utils/noop'; | ||
import { Button } from '../Button'; | ||
import { Icon } from '../Icon'; | ||
|
||
import { ActionModalContent } from './components/ActionModalContent'; | ||
import { | ||
ModalContent, | ||
ModalFullSpaceContent, | ||
|
@@ -24,7 +26,7 @@ import { | |
export default { | ||
title: 'Components/Modal', | ||
component: ModalComponent, | ||
subcomponents: { ModalHeader }, | ||
subcomponents: { ModalHeader, ActionModalContent, ModalBase }, | ||
parameters: { | ||
viewMode: 'story', | ||
previewTabs: { | ||
|
@@ -51,7 +53,15 @@ const StoryTemplate: StoryFn<ModalProps> = ({ | |
const [isOpen, setIsOpen] = React.useState(true); | ||
|
||
return ( | ||
<> | ||
<div | ||
style={{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please move it to const, outside the component's body. Every inline object or a functions are recreated on each render and we do not want that :) |
||
width: '80vh', | ||
height: '50vh', | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}} | ||
> | ||
<Button onClick={() => setIsOpen(true)}>Open modal</Button> | ||
{isOpen && ( | ||
<ModalComponent | ||
|
@@ -62,7 +72,7 @@ const StoryTemplate: StoryFn<ModalProps> = ({ | |
{children} | ||
</ModalComponent> | ||
)} | ||
</> | ||
</div> | ||
); | ||
}; | ||
|
||
|
@@ -130,6 +140,36 @@ ModalWithFullSpaceContent.args = { | |
footer: null, | ||
} as ModalProps; | ||
|
||
export const ActionModal = StoryTemplate.bind({}); | ||
ActionModal.args = { | ||
...defaultModalProps, | ||
children: ( | ||
<ActionModalContent | ||
icon={ | ||
<Icon | ||
source={Error} | ||
size="xxxlarge" | ||
customColor="var(--content-basic-disabled)" | ||
/> | ||
} | ||
heading="Action Modal Header" | ||
actions={ | ||
<> | ||
<Button size="large">Button</Button> | ||
<Button size="large" kind="primary"> | ||
Button | ||
</Button> | ||
</> | ||
} | ||
> | ||
Amet minim mollit non deserunt ullamco est sit aliqua dolor do amet sint. | ||
Velit officia consequat duis enim velit mollit. Exercitation veniam | ||
consequat sunt nostrud amet. | ||
</ActionModalContent> | ||
), | ||
footer: null, | ||
} as ModalProps; | ||
|
||
export const ModalPortal = ({ | ||
children, | ||
...args | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
$base-class: 'action-modal-content'; | ||
|
||
.#{$base-class} { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
padding-top: var(--spacing-3); | ||
padding-bottom: var(--spacing-10); | ||
width: 100%; | ||
max-width: 480px; | ||
height: 100%; | ||
|
||
&__icon { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
margin-bottom: var(--spacing-3); | ||
min-width: 48px; | ||
min-height: 48px; | ||
} | ||
|
||
&__heading { | ||
margin-top: 0; | ||
margin-bottom: var(--spacing-2); | ||
} | ||
|
||
&__content { | ||
margin-bottom: var(--spacing-10); | ||
text-align: center; | ||
} | ||
|
||
&__actions { | ||
display: flex; | ||
gap: var(--spacing-2); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.