-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
/ok-to-test tags="@tag.Anvil" <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced a new `Sheet` component for modal-like overlays, enhancing content display. - Added a `Sidebar` component for improved navigation and organization within the design system. - **Improvements** - Enhanced styling and animations for the `Sheet` and `Sidebar` components, providing a more interactive user experience. - Updated dependencies to improve performance and accessibility. - **Documentation** - Added Storybook configurations for `Sheet` and `Sidebar` components, showcasing their functionality and usage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/11855312043> > Commit: f8f4d2c > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11855312043&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Anvil` > Spec: > <hr>Fri, 15 Nov 2024 11:40:45 UTC <!-- end of auto-generated comment: Cypress test results -->
- Loading branch information
Showing
25 changed files
with
946 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
app/client/packages/design-system/widgets/src/components/Sheet/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./src"; |
62 changes: 62 additions & 0 deletions
62
app/client/packages/design-system/widgets/src/components/Sheet/src/Sheet.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import clsx from "clsx"; | ||
import React, { forwardRef, type Ref, useRef } from "react"; | ||
import { | ||
Modal as HeadlessModal, | ||
Dialog as HeadlessDialog, | ||
ModalOverlay as HeadlessModalOverlay, | ||
} from "react-aria-components"; | ||
import { CSSTransition } from "react-transition-group"; | ||
|
||
import styles from "./styles.module.css"; | ||
import type { SheetProps } from "./types"; | ||
|
||
export function _Sheet(props: SheetProps, ref: Ref<HTMLDivElement>) { | ||
const { | ||
children, | ||
className, | ||
isOpen, | ||
onEntered, | ||
onExited, | ||
onOpenChange, | ||
position = "start", | ||
...rest | ||
} = props; | ||
const root = document.body.querySelector( | ||
"[data-theme-provider]", | ||
) as HTMLButtonElement; | ||
|
||
const overlayRef = useRef<HTMLDivElement>(); | ||
|
||
return ( | ||
<CSSTransition | ||
in={isOpen} | ||
nodeRef={overlayRef} | ||
onEntered={onEntered} | ||
onExited={onExited} | ||
timeout={300} | ||
unmountOnExit | ||
> | ||
<HeadlessModalOverlay | ||
UNSTABLE_portalContainer={root} | ||
className={clsx(styles.overlay, className)} | ||
isDismissable | ||
isOpen={isOpen} | ||
onOpenChange={onOpenChange} | ||
// @ts-expect-error TS is unable to infer the correct type for the render prop | ||
ref={overlayRef} | ||
> | ||
<HeadlessModal | ||
className={clsx(styles.sheet, styles[position])} | ||
ref={ref} | ||
{...rest} | ||
> | ||
<HeadlessDialog aria-label="Sheet" className={styles.dialog}> | ||
{children} | ||
</HeadlessDialog> | ||
</HeadlessModal> | ||
</HeadlessModalOverlay> | ||
</CSSTransition> | ||
); | ||
} | ||
|
||
export const Sheet = forwardRef(_Sheet); |
2 changes: 2 additions & 0 deletions
2
app/client/packages/design-system/widgets/src/components/Sheet/src/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { Sheet } from "./Sheet"; | ||
export { DialogTrigger as SheetTrigger } from "react-aria-components"; |
117 changes: 117 additions & 0 deletions
117
app/client/packages/design-system/widgets/src/components/Sheet/src/styles.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
.sheet { | ||
position: fixed; | ||
background: var(--color-bg-elevation-3); | ||
width: 80%; | ||
} | ||
|
||
.overlay { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
background: var(--color-bg-neutral-opacity); | ||
z-index: var(--z-index-99); | ||
contain: strict; | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
height: 100%; | ||
width: 100%; | ||
} | ||
|
||
.dialog { | ||
height: 100%; | ||
} | ||
|
||
.overlay[data-entering] { | ||
animation: fade-in 0.3s ease-in-out; | ||
} | ||
|
||
.overlay[data-exiting] { | ||
animation: fade-out 0.3s ease-in-out; | ||
} | ||
|
||
@keyframes fade-in { | ||
from { | ||
opacity: 0; | ||
} | ||
to { | ||
opacity: 1; | ||
} | ||
} | ||
|
||
@keyframes fade-out { | ||
from { | ||
opacity: 1; | ||
} | ||
to { | ||
opacity: 0; | ||
} | ||
} | ||
|
||
.start { | ||
top: 0; | ||
left: 0; | ||
bottom: 0; | ||
max-width: 90%; | ||
height: 100%; | ||
} | ||
|
||
.start[data-entering] { | ||
animation: slide-in-start 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
} | ||
|
||
.start[data-exiting] { | ||
animation: slide-out-start 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
} | ||
|
||
.end { | ||
top: 0; | ||
right: 0; | ||
bottom: 0; | ||
max-width: 90%; | ||
height: 100%; | ||
} | ||
|
||
.end[data-entering] { | ||
animation: slide-in-end 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
} | ||
|
||
.end[data-exiting] { | ||
animation: slide-out-end 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
} | ||
|
||
@keyframes slide-in-start { | ||
from { | ||
transform: translateX(-100%); | ||
} | ||
to { | ||
transform: translateX(0); | ||
} | ||
} | ||
|
||
@keyframes slide-out-start { | ||
from { | ||
transform: translateX(0); | ||
} | ||
to { | ||
transform: translateX(-100%); | ||
} | ||
} | ||
|
||
@keyframes slide-in-end { | ||
from { | ||
transform: translateX(100%); | ||
} | ||
to { | ||
transform: translateX(0); | ||
} | ||
} | ||
|
||
@keyframes slide-out-end { | ||
from { | ||
transform: translateX(0); | ||
} | ||
to { | ||
transform: translateX(100%); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
app/client/packages/design-system/widgets/src/components/Sheet/src/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { ModalOverlayProps as HeadlessModalOverlayProps } from "react-aria-components"; | ||
|
||
export interface SheetProps | ||
extends Omit<HeadlessModalOverlayProps, "position"> { | ||
/** | ||
* The position from which the sheet slides in | ||
* @default 'start' | ||
*/ | ||
position?: "start" | "end"; | ||
onEntered?: () => void; | ||
onExited?: () => void; | ||
} |
27 changes: 27 additions & 0 deletions
27
app/client/packages/design-system/widgets/src/components/Sheet/stories/Sheet.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from "react"; | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import { Sheet } from "../index"; | ||
import { SimpleSheet } from "./SimpleSheet"; | ||
|
||
const meta: Meta<typeof Sheet> = { | ||
title: "WDS/Widgets/Sheet", | ||
component: Sheet, | ||
render: (args) => <SimpleSheet {...args} />, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof Sheet>; | ||
|
||
// Default story with left position (start) | ||
export const Default: Story = { | ||
args: { | ||
position: "start", | ||
}, | ||
}; | ||
|
||
// Right position (end) | ||
export const RightPositioned: Story = { | ||
args: { | ||
position: "end", | ||
}, | ||
}; |
20 changes: 20 additions & 0 deletions
20
app/client/packages/design-system/widgets/src/components/Sheet/stories/SimpleSheet.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React, { useState } from "react"; | ||
import { Button } from "../../Button"; | ||
import { Sheet } from "../index"; | ||
import type { SheetProps } from "../src/types"; | ||
|
||
export const SimpleSheet = (props: Omit<SheetProps, "children">) => { | ||
const [isOpen, setIsOpen] = useState(props.isOpen); | ||
|
||
return ( | ||
<> | ||
<Button onPress={() => setIsOpen(!Boolean(isOpen))}>Sheet trigger</Button> | ||
<Sheet {...props} isOpen={isOpen} onOpenChange={setIsOpen}> | ||
<div style={{ padding: "1rem" } as React.CSSProperties}> | ||
<h3>Sheet Content</h3> | ||
<p>This is an example of sheet content.</p> | ||
</div> | ||
</Sheet> | ||
</> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
app/client/packages/design-system/widgets/src/components/Sidebar/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./src"; |
72 changes: 72 additions & 0 deletions
72
app/client/packages/design-system/widgets/src/components/Sidebar/src/Sidebar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import clsx from "clsx"; | ||
import * as React from "react"; | ||
import { type Ref, useRef } from "react"; | ||
import { Sheet } from "../../Sheet"; | ||
import { useSidebar } from "./use-sidebar"; | ||
import styles from "./styles.module.css"; | ||
import type { SidebarProps } from "./types"; | ||
import { CSSTransition } from "react-transition-group"; | ||
|
||
const _Sidebar = (props: SidebarProps, ref: Ref<HTMLDivElement>) => { | ||
const { | ||
children, | ||
className, | ||
collapsible = "offcanvas", | ||
onEntered, | ||
onExited, | ||
side = "start", | ||
variant = "sidebar", | ||
...rest | ||
} = props; | ||
const { isMobile, setOpen, state } = useSidebar(); | ||
const sidebarRef = useRef<HTMLDivElement>(); | ||
|
||
if (collapsible === "none") { | ||
return ( | ||
<div className={clsx(className)} ref={ref} {...props}> | ||
{children} | ||
</div> | ||
); | ||
} | ||
|
||
if (Boolean(isMobile)) { | ||
return ( | ||
<Sheet | ||
isOpen={state === "expanded"} | ||
onEntered={onEntered} | ||
onExited={onExited} | ||
onOpenChange={setOpen} | ||
position={side} | ||
> | ||
{children} | ||
</Sheet> | ||
); | ||
} | ||
|
||
return ( | ||
<CSSTransition | ||
in={state === "expanded"} | ||
nodeRef={sidebarRef} | ||
onEntered={onEntered} | ||
onExited={onExited} | ||
timeout={300} | ||
> | ||
<div | ||
className={clsx(styles.mainSidebar)} | ||
data-collapsible={state === "collapsed" ? collapsible : ""} | ||
data-side={side} | ||
data-state={state} | ||
data-variant={variant} | ||
// @ts-expect-error TS is unable to infer the correct type for the render prop | ||
ref={sidebarRef} | ||
> | ||
<div className={styles.fakeSidebar} /> | ||
<div className={clsx(styles.sidebar, className)} ref={ref} {...rest}> | ||
<div className={styles.sidebarContainer}>{children}</div> | ||
</div> | ||
</div> | ||
</CSSTransition> | ||
); | ||
}; | ||
|
||
export const Sidebar = React.forwardRef(_Sidebar); |
22 changes: 22 additions & 0 deletions
22
app/client/packages/design-system/widgets/src/components/Sidebar/src/SidebarContent.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import clsx from "clsx"; | ||
import React, { type ComponentProps, type Ref } from "react"; | ||
|
||
import styles from "./styles.module.css"; | ||
|
||
const _SidebarContent = ( | ||
props: ComponentProps<"div">, | ||
ref: Ref<HTMLDivElement>, | ||
) => { | ||
const { className, ...rest } = props; | ||
|
||
return ( | ||
<div | ||
className={clsx(styles.sidebarContent, className)} | ||
data-sidebar="content" | ||
ref={ref} | ||
{...rest} | ||
/> | ||
); | ||
}; | ||
|
||
export const SidebarContent = React.forwardRef(_SidebarContent); |
22 changes: 22 additions & 0 deletions
22
app/client/packages/design-system/widgets/src/components/Sidebar/src/SidebarInset.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import clsx from "clsx"; | ||
import * as React from "react"; | ||
import type { ComponentProps, Ref } from "react"; | ||
|
||
import styles from "./styles.module.css"; | ||
|
||
export const _SidebarInset = ( | ||
props: ComponentProps<"main">, | ||
ref: Ref<HTMLDivElement>, | ||
) => { | ||
const { className, ...rest } = props; | ||
|
||
return ( | ||
<main | ||
className={clsx(styles.sidebarInset, className)} | ||
ref={ref} | ||
{...rest} | ||
/> | ||
); | ||
}; | ||
|
||
export const SidebarInset = React.forwardRef(_SidebarInset); |
Oops, something went wrong.