Add popover component
This commit is contained in:
		
							
								
								
									
										139
									
								
								components/Popover.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								components/Popover.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
import React, { ReactNode } from "react";
 | 
			
		||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
 | 
			
		||||
import { styled, keyframes } from "../stitches.config";
 | 
			
		||||
 | 
			
		||||
const slideUpAndFade = keyframes({
 | 
			
		||||
  "0%": { opacity: 0, transform: "translateY(2px)" },
 | 
			
		||||
  "100%": { opacity: 1, transform: "translateY(0)" },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const slideRightAndFade = keyframes({
 | 
			
		||||
  "0%": { opacity: 0, transform: "translateX(-2px)" },
 | 
			
		||||
  "100%": { opacity: 1, transform: "translateX(0)" },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const slideDownAndFade = keyframes({
 | 
			
		||||
  "0%": { opacity: 0, transform: "translateY(-2px)" },
 | 
			
		||||
  "100%": { opacity: 1, transform: "translateY(0)" },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const slideLeftAndFade = keyframes({
 | 
			
		||||
  "0%": { opacity: 0, transform: "translateX(2px)" },
 | 
			
		||||
  "100%": { opacity: 1, transform: "translateX(0)" },
 | 
			
		||||
});
 | 
			
		||||
const StyledContent = styled(PopoverPrimitive.Content, {
 | 
			
		||||
  borderRadius: 4,
 | 
			
		||||
  padding: "$3 $3",
 | 
			
		||||
  fontSize: 12,
 | 
			
		||||
  lineHeight: 1,
 | 
			
		||||
  color: "$text",
 | 
			
		||||
  boxShadow:
 | 
			
		||||
    "0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
 | 
			
		||||
  "@media (prefers-reduced-motion: no-preference)": {
 | 
			
		||||
    animationDuration: "400ms",
 | 
			
		||||
    animationTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)",
 | 
			
		||||
    willChange: "transform, opacity",
 | 
			
		||||
    '&[data-state="open"]': {
 | 
			
		||||
      '&[data-side="top"]': { animationName: slideDownAndFade },
 | 
			
		||||
      '&[data-side="right"]': { animationName: slideLeftAndFade },
 | 
			
		||||
      '&[data-side="bottom"]': { animationName: slideUpAndFade },
 | 
			
		||||
      '&[data-side="left"]': { animationName: slideRightAndFade },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  ".dark &": {
 | 
			
		||||
    backgroundColor: "$mauve5",
 | 
			
		||||
    boxShadow:
 | 
			
		||||
      "0px 10px 38px -10px rgba(22, 23, 24, 0.85), 0px 10px 20px -15px rgba(22, 23, 24, 0.6)",
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const StyledArrow = styled(PopoverPrimitive.Arrow, {
 | 
			
		||||
  fill: "$colors$mauve2",
 | 
			
		||||
  ".dark &": {
 | 
			
		||||
    fill: "$mauve5",
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const StyledClose = styled(PopoverPrimitive.Close, {
 | 
			
		||||
  all: "unset",
 | 
			
		||||
  fontFamily: "inherit",
 | 
			
		||||
  borderRadius: "100%",
 | 
			
		||||
  height: 25,
 | 
			
		||||
  width: 25,
 | 
			
		||||
  display: "inline-flex",
 | 
			
		||||
  alignItems: "center",
 | 
			
		||||
  justifyContent: "center",
 | 
			
		||||
  color: "$text",
 | 
			
		||||
  position: "absolute",
 | 
			
		||||
  top: 5,
 | 
			
		||||
  right: 5,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Exports
 | 
			
		||||
export const PopoverRoot = PopoverPrimitive.Root;
 | 
			
		||||
export const PopoverTrigger = PopoverPrimitive.Trigger;
 | 
			
		||||
export const PopoverContent = StyledContent;
 | 
			
		||||
export const PopoverArrow = StyledArrow;
 | 
			
		||||
export const PopoverClose = StyledClose;
 | 
			
		||||
 | 
			
		||||
// const PopoverDemo = () => (
 | 
			
		||||
//   <Popover>
 | 
			
		||||
//     <PopoverContent sideOffset={5}>
 | 
			
		||||
//       <Flex css={{ flexDirection: "column", gap: 10 }}>
 | 
			
		||||
//         <Text bold css={{ marginBottom: 10 }}>
 | 
			
		||||
//           Dimensions
 | 
			
		||||
//         </Text>
 | 
			
		||||
//         <Fieldset>
 | 
			
		||||
//           <Label htmlFor="width">Width</Label>
 | 
			
		||||
//           <Input id="width" defaultValue="100%" />
 | 
			
		||||
//         </Fieldset>
 | 
			
		||||
//         <Fieldset>
 | 
			
		||||
//           <Label htmlFor="maxWidth">Max. width</Label>
 | 
			
		||||
//           <Input id="maxWidth" defaultValue="300px" />
 | 
			
		||||
//         </Fieldset>
 | 
			
		||||
//         <Fieldset>
 | 
			
		||||
//           <Label htmlFor="height">Height</Label>
 | 
			
		||||
//           <Input id="height" defaultValue="25px" />
 | 
			
		||||
//         </Fieldset>
 | 
			
		||||
//         <Fieldset>
 | 
			
		||||
//           <Label htmlFor="maxHeight">Max. height</Label>
 | 
			
		||||
//           <Input id="maxHeight" defaultValue="none" />
 | 
			
		||||
//         </Fieldset>
 | 
			
		||||
//       </Flex>
 | 
			
		||||
//       <PopoverArrow />
 | 
			
		||||
//       <PopoverClose aria-label="Close">
 | 
			
		||||
//         <Cross2Icon />
 | 
			
		||||
//       </PopoverClose>
 | 
			
		||||
//     </PopoverContent>
 | 
			
		||||
//   </Popover>
 | 
			
		||||
// );
 | 
			
		||||
 | 
			
		||||
// export default PopoverDemo;
 | 
			
		||||
 | 
			
		||||
interface IPopover {
 | 
			
		||||
  content: string | ReactNode;
 | 
			
		||||
  open?: boolean;
 | 
			
		||||
  defaultOpen?: boolean;
 | 
			
		||||
  onOpenChange?: (open: boolean) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Popover: React.FC<IPopover> = ({
 | 
			
		||||
  children,
 | 
			
		||||
  content,
 | 
			
		||||
  open,
 | 
			
		||||
  defaultOpen = false,
 | 
			
		||||
  onOpenChange,
 | 
			
		||||
}) => (
 | 
			
		||||
  <PopoverRoot
 | 
			
		||||
    open={open}
 | 
			
		||||
    defaultOpen={defaultOpen}
 | 
			
		||||
    onOpenChange={onOpenChange}
 | 
			
		||||
  >
 | 
			
		||||
    <PopoverTrigger asChild>{children}</PopoverTrigger>
 | 
			
		||||
    <PopoverContent sideOffset={5}>
 | 
			
		||||
      {content} <PopoverArrow />
 | 
			
		||||
    </PopoverContent>
 | 
			
		||||
  </PopoverRoot>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export default Popover;
 | 
			
		||||
		Reference in New Issue
	
	Block a user