-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(drawer): basic drawer component
Add basic drawer component with supporting component `DrawerItems`
- Loading branch information
1 parent
dc5b58a
commit e74ce8a
Showing
12 changed files
with
256 additions
and
0 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
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,30 @@ | ||
import * as React from "react"; | ||
import type { DrawerOwnProps } from "./types"; | ||
import type { PolymorphicWithRef } from "../types"; | ||
import DrawerBase from "./DrawerBase"; | ||
import { DrawerItems } from "../DrawerItems"; | ||
|
||
type DrawerProps<T extends React.ElementType> = PolymorphicWithRef< | ||
T, | ||
DrawerOwnProps | ||
>; | ||
|
||
type DrawerElement = <E extends React.ElementType = "nav">( | ||
props: DrawerProps<E> | ||
) => React.ReactElement<DrawerProps<E>>; | ||
|
||
const Drawer: DrawerElement = React.forwardRef( | ||
<T extends React.ElementType>( | ||
props: DrawerProps<T>, | ||
innerRef: typeof props.ref | ||
) => { | ||
const { component = "nav", ...rest } = props; | ||
return ( | ||
<DrawerBase as={component as typeof component} ref={innerRef} {...rest} /> | ||
); | ||
} | ||
); | ||
|
||
export default Object.assign(Drawer, { | ||
Items: DrawerItems, | ||
}); |
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,29 @@ | ||
import type { DrawerOwnProps } from "./types"; | ||
import styled, { CSSObject } from "@emotion/styled"; | ||
import { useTheme } from "../theme"; | ||
import { useMemo } from "react"; | ||
|
||
const DrawerBase = styled("nav", { | ||
label: "Drawer", | ||
})<Partial<DrawerOwnProps>>(() => { | ||
const { theme, type } = useTheme(); | ||
|
||
const _background = useMemo(() => new Map<typeof type, CSSObject>(), [type]) | ||
.set("light", { | ||
background: theme.colorStyles.sys.light.surface, | ||
}) | ||
.set("dark", { | ||
background: theme.colorStyles.sys.dark.surface, | ||
}) | ||
.get(type) as CSSObject; | ||
return Object.assign( | ||
{ | ||
width: "100%", | ||
height: "100%", | ||
maxWidth: theme.pxToRem(360), | ||
}, | ||
_background | ||
); | ||
}); | ||
|
||
export default DrawerBase; |
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 { default as Drawer } from "./Drawer"; |
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,3 @@ | ||
export type DrawerOwnProps = { | ||
variant?: "standard" | "modal"; | ||
}; |
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,82 @@ | ||
import type { DrawerItemOwnProps } from "./types"; | ||
import styled, { CSSObject } from "@emotion/styled"; | ||
import { useMemo } from "react"; | ||
import { useTheme } from "../theme"; | ||
|
||
const BaseDrawerItem = styled("li", { | ||
label: "DrawerItem", | ||
})<Partial<DrawerItemOwnProps>>(({ dense, active = false }) => { | ||
const { theme, type } = useTheme(); | ||
const _dense = useMemo(() => new Map<typeof dense, CSSObject>(), []); | ||
_dense.set(true, { | ||
minHeight: theme.pxToRem(48), | ||
}); | ||
const _active = useMemo(() => new Map<typeof active, CSSObject>(), []); | ||
_active.set(true, { | ||
backgroundColor: new Map<typeof type, string>() | ||
.set("light", theme.colorStyles.sys.light.secondaryContainer) | ||
.set("dark", theme.colorStyles.sys.dark.secondaryContainer) | ||
.get(type), | ||
}); | ||
const _rippleBG = useMemo(() => new Map<typeof type, string>(), []); | ||
_rippleBG | ||
.set("dark", theme.colorStyles.readOnly.dark.onSecondaryContainer.opacity12) | ||
.set( | ||
"light", | ||
theme.colorStyles.readOnly.light.onSecondaryContainer.opacity12 | ||
); | ||
const _hover = useMemo(() => new Map<typeof type, CSSObject>(), []); | ||
_hover | ||
.set("light", { | ||
[`&: after`]: { | ||
background: | ||
theme.colorStyles.readOnly.light.onSecondaryContainer.opacity08, | ||
}, | ||
}) | ||
.set("dark", { | ||
[`&: after`]: { | ||
backgroundColor: | ||
theme.colorStyles.readOnly.dark.onSecondaryContainer.opacity08, | ||
}, | ||
}); | ||
|
||
return Object.assign( | ||
{ | ||
display: "flex", | ||
alignItems: "center", | ||
minHeight: theme.pxToRem(56), | ||
paddingInline: theme.pxToRem(28), | ||
position: "relative", | ||
overflow: "hidden", | ||
boxSizing: "content-box", | ||
borderRadius: theme.pxToRem(28), | ||
|
||
[`&: hover`]: { | ||
..._hover.get(type), | ||
backgroundClip: "border-box", | ||
}, | ||
[`> [data-label="drawer"]`]: { | ||
flexGrow: 1, | ||
paddingRight: theme.pxToRem(12), | ||
}, | ||
[`> [data-icon="drawer"]`]: { | ||
paddingRight: theme.pxToRem(12), | ||
}, | ||
[`> [data-ripple]`]: { | ||
background: _rippleBG.get(type), | ||
}, | ||
[`&: after`]: { | ||
content: "''", | ||
position: "absolute", | ||
top: 0, | ||
left: 0, | ||
width: "100%", | ||
height: "100%", | ||
}, | ||
}, | ||
_dense.get(dense), | ||
_active.get(active) | ||
); | ||
}); | ||
|
||
export default BaseDrawerItem; |
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,46 @@ | ||
import * as React from "react"; | ||
import type { DrawerItemOwnProps } from "./types"; | ||
import type { PolymorphicWithRef } from "../types"; | ||
import BaseDrawerItem from "./BaseDrawerItem"; | ||
import { LabelTypography } from "../LabelTypography"; | ||
import { Icon } from "../Icon"; | ||
import { useEventListener } from "../hooks"; | ||
import rippleEffect from "../utils/events/rippleEffect"; | ||
|
||
type LabelProps = React.ComponentProps<typeof LabelTypography> & { | ||
labelText?: string; | ||
}; | ||
|
||
type DrawerItemProps<T extends React.ElementType = "li"> = PolymorphicWithRef< | ||
T, | ||
DrawerItemOwnProps | ||
>; | ||
type DrawerItemElement = <T extends React.ElementType = "li">( | ||
props: DrawerItemProps<T> | ||
) => React.ReactElement<DrawerItemProps<T>>; | ||
|
||
const DrawerItem: DrawerItemElement = React.forwardRef( | ||
<T extends React.ElementType = "li">( | ||
props: DrawerItemProps<T>, | ||
innerRef: typeof props.ref | ||
) => { | ||
const { component = "li", ...rest } = props; | ||
const itemRef = React.useRef(null); | ||
// forwarding the ref using imperative API | ||
React.useImperativeHandle(innerRef, () => itemRef.current); | ||
|
||
// useEventListener to add ripple effect | ||
useEventListener( | ||
"mousedown", | ||
(event) => rippleEffect(event, itemRef), | ||
itemRef | ||
); | ||
return <BaseDrawerItem as={component} ref={itemRef} {...rest} />; | ||
} | ||
); | ||
|
||
export default Object.assign(DrawerItem, { | ||
Label: (props: LabelProps) => | ||
React.cloneElement(<LabelTypography />, props, [props.labelText]), | ||
Icon: Icon, | ||
}); |
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 { default as DrawerItem } from "./DrawerItem"; |
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,4 @@ | ||
export type DrawerItemOwnProps = { | ||
dense?: true; | ||
active?: boolean; | ||
}; |
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,9 @@ | ||
import styled from "@emotion/styled"; | ||
|
||
const BaseDrawerItems = styled("ul", { | ||
label: "DrawerItems", | ||
})(() => { | ||
return {}; | ||
}); | ||
|
||
export default BaseDrawerItems; |
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,49 @@ | ||
import * as React from "react"; | ||
import type { PolymorphicWithRef } from "../types"; | ||
import BaseDrawerItems from "./BaseDrawerItems"; | ||
import { DrawerItem } from "../DrawerItem"; | ||
|
||
type Props = { | ||
label: React.ComponentProps<typeof DrawerItem.Label> & { | ||
[`data-label`]?: string; | ||
}; | ||
icon: React.ComponentProps<typeof DrawerItem.Icon> & { | ||
[`data-icon`]?: string; | ||
}; | ||
}; | ||
type DrawerItemsProps<T extends React.ElementType> = PolymorphicWithRef< | ||
T, | ||
{ | ||
children: (Item: typeof DrawerItem, props: Props) => React.ReactNode; | ||
} | ||
>; | ||
type DrawerItemsElement = <E extends React.ElementType = "ul">( | ||
props: DrawerItemsProps<E> | ||
) => React.ReactElement<DrawerItemsProps<E>>; | ||
|
||
const DrawerItems: DrawerItemsElement = React.forwardRef( | ||
<T extends React.ElementType>( | ||
props: DrawerItemsProps<T>, | ||
innerRef: typeof props.ref | ||
) => { | ||
const { component = "ul", children, ...rest } = props; | ||
return ( | ||
<BaseDrawerItems | ||
as={component as typeof component} | ||
ref={innerRef} | ||
{...rest} | ||
> | ||
{children(DrawerItem, { | ||
label: { | ||
component: "span", | ||
size: "large", | ||
["data-label"]: "drawer", | ||
}, | ||
icon: { ["data-icon"]: "drawer" }, | ||
})} | ||
</BaseDrawerItems> | ||
); | ||
} | ||
); | ||
|
||
export default DrawerItems; |
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 { default as DrawerItems } from "./DrawerItems"; |