Skip to content

Instantly share code, notes, and snippets.

@dennishn
Created May 25, 2022 13:12
Show Gist options
  • Save dennishn/bb55d1a57c4a3cb4b0daa4605046c177 to your computer and use it in GitHub Desktop.
Save dennishn/bb55d1a57c4a3cb4b0daa4605046c177 to your computer and use it in GitHub Desktop.
import * as React from "React";
import { forwardRef, chakra, HTMLChakraProps, shouldForwardProp } from "@chakra-ui/react";
export type StateLayerState = "none" | "hover" | "pressed" | "dragged" | "focus";
interface StateLayerOptions {
forceState?: StateLayerState;
focusWithin?: boolean;
}
export interface StateLayerProps extends HTMLChakraProps<"div">, StateLayerOptions {}
const stateOpacity: Record<StateLayerState, string> = {
none: "0%",
hover: "8%",
focus: "12%",
pressed: "12%",
dragged: "16%",
};
const Root = forwardRef((props, ref) => (
<chakra.div
__css={{
position: "relative",
}}
{...props}
/>
));
const Content: React.FC = () => (
<chakra.div
__css={{
position: "relative",
zIndex: 2,
borderRadius: "inherit",
}}
/>
);
const Background: React.FC<StateLayerProps> = (props) => (
<chakra.div
__css={{
position: "absolute",
zIndex: 0,
top: 0,
left: 0,
width: "100%",
height: "100%",
boxSizing: "border-box",
borderRadius: "inherit",
bg: "currentColor",
...(!props.forceState && {
opacity: 0,
_groupHover: {
opacity: stateOpacity.hover,
},
_groupFocus: {
opacity: stateOpacity.focus,
},
_groupActive: {
opacity: stateOpacity.pressed,
},
}),
...(!props.forceState &&
props.focusWithin && {
_groupFocusWithin: {
opacity: stateOpacity.focus,
},
}),
...(props.forceState && {
opacity: stateOpacity[props.forceState],
}),
}}
/>
);
export const StateLayer = forwardRef<StateLayerProps, "div">(
({ children, forceState, focusWithin, ...rest }, ref) => {
return (
<Root ref={ref} {...rest} data-group>
<Content>{children}</Content>
<Background forceState={forceState} focusWithin={focusWithin} />
</Root>
);
}
);
export default StateLayer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment