Skip to content
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

feat(Modal): modal improvements, add stories for main Modal and modal's layouts #2627

Merged
merged 37 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2d25116
docs(Modal): helper component for story to have modal opened by defau…
YossiSaadi Nov 7, 2024
c40c752
docs(Modal): helper hook for story to have modal opened by default wi…
YossiSaadi Nov 7, 2024
2663acd
docs(Modal): css to contain image with large component rule (dos and …
YossiSaadi Nov 7, 2024
4a35441
docs(ModalBasicLayout): story for modal layout
YossiSaadi Nov 7, 2024
4054b21
docs(ModalMediaLayout): story for modal layout
YossiSaadi Nov 7, 2024
71f0a6a
docs(ModalSideBySideLayout): story for modal layout
YossiSaadi Nov 7, 2024
2a23e5d
docs(Modal): story for modal's main page
YossiSaadi Nov 7, 2024
af3a116
docs(Modal): wrapping preview container logic in a decorator to not b…
YossiSaadi Nov 13, 2024
9d418c6
chore: fix eslint config so it won't yell on defaultProps missing on …
YossiSaadi Nov 7, 2024
017e89d
docs(ModalBasicLayout): use decorator for the preview container
YossiSaadi Nov 13, 2024
5f0af61
feat(ModalMediaLayout): remove footer shadow from layout
YossiSaadi Dec 4, 2024
1128bf3
docs(ModalMediaLayout): use decorator for the preview container
YossiSaadi Nov 13, 2024
d0cff9f
docs(ModalSideBySideLayout): use decorator for the preview container
YossiSaadi Nov 13, 2024
ed0c5be
docs(Modal): override the "preview" container to act as the viewport …
YossiSaadi Nov 14, 2024
39dfd2d
docs(Modal): rename decorator name to fit Storybook's format
YossiSaadi Nov 14, 2024
2600aec
docs(Modal): add related component for each layout
YossiSaadi Nov 14, 2024
b291fda
docs(Modal): fix prop name
YossiSaadi Nov 18, 2024
a02e7e4
docs(Modal): fix to TransitionView and useWizard's updated API
YossiSaadi Dec 4, 2024
9d5b89a
docs(Modal): fix images sizing in stories
YossiSaadi Nov 18, 2024
939e21c
feat(Modal): new modal responsiveness logic 7920875908
YossiSaadi Nov 22, 2024
315ed72
feat(ModalMediaLayout): do not allow scrollable abilities for media l…
YossiSaadi Dec 4, 2024
19fc9ec
feat(Modal): remove media hard-coded responsive height from media layout
YossiSaadi Dec 4, 2024
10b0482
docs(Modal): enhance stories for layout components
YossiSaadi Dec 4, 2024
3dfb803
docs(Modal): add props table for layout components stories
YossiSaadi Dec 4, 2024
253b51e
docs(Modal): make Confirm and Cancel buttons close the Modal
YossiSaadi Dec 4, 2024
1622443
docs(Modal): enhancements and fixes according to design
YossiSaadi Dec 4, 2024
dbdeff1
docs(Modal): fix - redundant background on Show Code button, prevent …
YossiSaadi Dec 4, 2024
26a5c8e
docs(Modal): make all side by side layout stories 400px height
YossiSaadi Dec 4, 2024
61d13be
docs(Modal): add jsdoc for all the props related to Modal
YossiSaadi Dec 4, 2024
380e596
test(ModalTopActions): fix text to match modified prop
YossiSaadi Dec 5, 2024
ee95b0e
docs(Modal): fix links and hierarchy of Modal related docs, hide temp…
YossiSaadi Dec 5, 2024
2a19285
build: fix lint
YossiSaadi Dec 5, 2024
bc0df76
feat(Modal): temporarily remove responsiveness of Modal
YossiSaadi Dec 5, 2024
3dd384f
docs: fix - retrieve mistakenly deleted css rule
YossiSaadi Dec 5, 2024
2c3b0fa
docs(Modal): change layouts placeholder images
YossiSaadi Dec 5, 2024
19e3135
docs(Modal): remove usage of index.ts for assets
YossiSaadi Dec 5, 2024
fc5d1bd
Merge branch 'refs/heads/master' into docs/yossi/new-modal-stories-77…
YossiSaadi Dec 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions packages/core/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,21 @@ module.exports = {
}
},
{
files: [
"*.stories.@(js|jsx|ts|tsx)",
"*.stories.helpers.@(js|jsx|ts|tsx)",
"src/storybook/decorators/**/with*.{js,jsx,ts,tsx}"
],
files: ["*.stories.@(js|jsx)", "*.stories.helpers.@(js|jsx)", "src/storybook/decorators/**/with*.{js,jsx}"],
rules: {
...commonRules,
"react-hooks/rules-of-hooks": "off",
"react/jsx-key": "off"
}
},
{
files: ["*.stories.@(ts|tsx)", "*.stories.helpers.@(ts|tsx)", "src/storybook/decorators/**/with*.{ts,tsx}"],
rules: {
...commonRules,
"react-hooks/rules-of-hooks": "off",
"react/jsx-key": "off",
"react/require-default-props": "off"
}
}
],
env: {
Expand Down
14 changes: 10 additions & 4 deletions packages/core/.storybook/manager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ addons.setConfig({
return <SidebarItem status={parameters.status}>{name.replace(storyStatus, "").trim()}</SidebarItem>;
},
filters: {
patterns: filterStory
patterns: shouldShowStory
},
showRoots: false
}
});

function filterStory(item) {
/**
* In order to hide stories you need to add `tags: ['internal']` to the stories file metadata.
* In order to hide MDX, you need to add `Internal` to the title in the MDX's `Meta` declaration `title` or to the `title` in the stories file metadata.
*
* Notice that all stories are available in development mode and in Chromatic.
*/
function shouldShowStory(item) {
const isDev = isChromatic() || process.env.NODE_ENV === "development";
const isInternal = !item.tags?.includes?.("internal") && !item.title?.startsWith?.("Internal");
return isDev || isInternal;
const isPublic = !item.tags?.includes?.("internal") && !item.title?.startsWith?.("Internal");
return isDev || isPublic;
}
8 changes: 6 additions & 2 deletions packages/core/.storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,19 @@
.sbdocs .docs-story {
border: var(--sb-layout-border-color);
}
.sbdocs .docs-story > div {
.sbdocs .docs-story > div:first-child {
background: var(--sb-secondary-background-color);
}
.sbdocs .docs-story > div:nth-child(2) {
/* prevent Show Code from rendering above full-screen components (such as Modal's overlay) */
z-index: unset;
background: unset;
}

.sbdocs {
color: var(--sb-primary-text-color);
}

.sbdocs p a,
YossiSaadi marked this conversation as resolved.
Show resolved Hide resolved
.sbdocs ul li a {
color: var(--sb-link-color);
}
Expand Down
36 changes: 11 additions & 25 deletions packages/core/src/components/ModalNew/Modal/Modal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

display: flex;
flex-direction: column;
width: var(--modal-width, 50%);
max-height: var(--modal-max-height, 80%);
width: var(--modal-width);
max-height: var(--modal-max-height);
background-color: var(--primary-background-color);
overflow: hidden;
border-radius: var(--border-radius-big);
Expand All @@ -28,58 +28,44 @@

&.sizeSmall {
--modal-max-height: 50%;
--modal-width: 45%;
--modal-width: 460px;
}

&.sizeMedium {
--modal-max-height: 80%;
--modal-width: 50%;
--modal-width: 540px;
}

&.sizeLarge {
--modal-max-height: 80%;
--modal-width: 70%;
--modal-width: 800px;
}

@media (min-width: 1280px) {
&.sizeSmall {
--modal-width: 40%;
--modal-width: 480px;
}

&.sizeMedium {
--modal-width: 44%;
--modal-width: 580px;
}

&.sizeLarge {
--modal-width: 66%;
--modal-width: 840px;
}
}

@media (min-width: 1440px) {
&.sizeSmall {
--modal-width: 35%;
--modal-width: 520px;
}

&.sizeMedium {
--modal-width: 38%;
--modal-width: 620px;
}

&.sizeLarge {
--modal-width: 60%;
}
}

@media (min-width: 1720px) {
&.sizeSmall {
--modal-width: 34%;
}

&.sizeMedium {
--modal-width: 36%;
}

&.sizeLarge {
--modal-width: 58%;
--modal-width: 900px;
}
}
}
2 changes: 1 addition & 1 deletion packages/core/src/components/ModalNew/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const Modal = forwardRef(
{children}
<ModalTopActions
renderAction={renderHeaderAction}
color={closeButtonTheme}
theme={closeButtonTheme}
closeButtonAriaLabel={closeButtonAriaLabel}
onClose={onClose}
/>
Expand Down
35 changes: 34 additions & 1 deletion packages/core/src/components/ModalNew/Modal/Modal.types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,48 @@ export type ModalCloseEvent =
| React.KeyboardEvent<HTMLBodyElement>;

export interface ModalProps extends VibeComponentProps {
/**
* Unique identifier for the modal.
*/
id: string;
/**
* Controls the visibility of the modal.
*/
show: boolean;
/**
* Determines the width and max-height of the modal.
*/
size?: ModalSize;
closeButtonTheme?: ModalTopActionsProps["color"];
/**
* Theme color for the close button.
*/
closeButtonTheme?: ModalTopActionsProps["theme"];
/**
* Accessibility label for the close button.
*/
closeButtonAriaLabel?: ModalTopActionsProps["closeButtonAriaLabel"];
/**
* Callback fired when the modal should close.
*/
onClose?: (event: ModalCloseEvent) => void;
/**
* Additional action to render in the header area.
*/
renderHeaderAction?: ModalTopActionsProps["renderAction"];
/**
* Reference to an element that triggered the modal, used for animations.
*/
anchorElementRef?: React.RefObject<HTMLElement>;
/**
* When true, prevents closing the modal when clicking the overlay ("click-outside") or pressing ESC.
*/
alertModal?: boolean;
/**
* Modal content.
*/
children: React.ReactNode;
/**
* Additional inline styles for the modal.
*/
style?: React.CSSProperties;
}
131 changes: 131 additions & 0 deletions packages/core/src/components/ModalNew/Modal/__stories__/Modal.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { Canvas, Meta } from "@storybook/blocks";
import { ModalTip } from "./Modal.stories.helpers";
import { Overview as BasicModalPreview } from "../../layouts/ModalBasicLayout/__stories__/ModalBasicLayout.stories";
import { Overview as SideBySideModalPreview } from "../../layouts/ModalSideBySideLayout/__stories__/ModalSideBySideLayout.stories";
import { Overview as MediaModalPreview } from "../../layouts/ModalMediaLayout/__stories__/ModalMediaLayout.stories";
import { backdropDo, backdropDont, loadingDo, loadingDont, ctaDo, ctaDont } from "./assets";
import styles from "./Modal.stories.module.scss";
import { StorybookLink } from "vibe-storybook-components";
import {
DIALOG,
TIPSEEN,
TOOLTIP
} from "../../../../storybook/components/related-components/component-description-map";

<Meta title="Internal/Components/Modal [New]" />

# Modal

- [Overview](#overview)
- [Props](#props)
- [Usage](#usage)
- [Do's and dont's](do's-and-don'ts)
- [Related components](#related-components)
- [Feedback](#feedback)

## Overview

Modals help users focus on a single task or a piece of information by popping up and blocking the rest of the page’s content. Modals disappear when user complete a required action or dismiss it. Use modals for quick, infrequent tasks.

We have 3 different modal component, each one provide a different layout for a different use case:

### Basic modal

The Basic Modal is intended for straightforward tasks, like selecting items or gathering basic information. Basic Modals help users focus on a single task without distractions. These modals do not support images or videos.

<Canvas of={BasicModalPreview} sourceState="none" />

### Side by side modal

The Side-by-Side Modal offers two distinct sections: the left for text or inputs, and the right for supporting visuals.
It's ideal when users need to reference media alongside information.

<Canvas of={SideBySideModalPreview} sourceState="none" />

### Media modal

The Media Modal includes a highlighted media section followed by text, perfect for grabbing attention with visuals before users interact with the content. Ideal for introducing new features or onboarding.

<Canvas of={MediaModalPreview} sourceState="none" />

## Usage

<UsageGuidelines
guidelines={[
"Use modals only when you need the user's full, immediate attention.",
"Modals are centered on the page. To put the modal in focus, the rest of the page is dimmed.",
"All modals must have a title, a call to action, and a close button. The title and call to action should be simple and clear.",
"By default, users can close modals by clicking the close button, clicking outside the modal, or pressing the ESC key."
]}
/>

<ModalTip />

## Do's and don'ts

<ComponentRules
rules={[
{
componentContainerClassName: styles.largeComponentRule,
positive: {
component: <img src={backdropDo} alt="modal with a backdrop" style={{ maxWidth: "100%" }} />,
description: "Modal must include backdrop element."
},
negative: {
component: <img src={backdropDont} alt="modal without a backdrop" style={{ maxWidth: "100%" }} />,
description: "Don't remove the backdrop element of the modal or the modal's title."
}
},
{
componentContainerClassName: styles.largeComponentRule,
positive: {
component: (
<img
src={loadingDo}
alt="modal with skeleton components as a loading experience"
style={{ maxWidth: "100%" }}
/>
),
description: (
<>
Use our <StorybookLink page="Feedback/Skeleton">Skeleton</StorybookLink> component if loading is needed. Try
that at least the actions will appear immediately.
</>
)
},
negative: {
component: (
<img
src={loadingDont}
alt="modal with a spinner loading components as a loading experience"
style={{ maxWidth: "100%" }}
/>
),
description: "Don't use Loader component in case of necessary loading."
}
},
{
componentContainerClassName: styles.largeComponentRule,
positive: {
component: (
<img
src={ctaDo}
alt="modal with a footer that includes one primary action and one tertiary action"
style={{ maxWidth: "100%" }}
/>
),
description: "Use one primary button as your main call to action, for extra buttons use the tertiary button."
},
negative: {
component: (
<img src={ctaDont} alt="modal with a footer that includes two primary actions" style={{ maxWidth: "100%" }} />
),
description: "Don't use more than one primary button, we don't want to distract the user from the main action."
}
}
]}
/>

## Related components

<RelatedComponents componentsNames={[TOOLTIP, DIALOG, TIPSEEN]} />
Loading
Loading