github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/FloatDialog.tsx (about)

     1  import Popover from "@material-ui/core/Popover"
     2  import { makeStyles } from "@material-ui/core/styles"
     3  import React from "react"
     4  import styled from "styled-components"
     5  import { ReactComponent as CloseSvg } from "./assets/svg/close.svg"
     6  import { Color, Font, FontSize } from "./style-helpers"
     7  
     8  export type FloatDialogProps = {
     9    id?: string
    10    title: string | React.ReactElement
    11    open: boolean
    12    anchorEl: Element | null
    13    onClose: () => void
    14    children: any
    15    style?: any
    16    anchorOrigin?: any
    17    transformOrigin?: any
    18  }
    19  
    20  let TitleBar = styled.div`
    21    display: flex;
    22    flex-direction: row;
    23    justify-content: space-between;
    24    align-items: baseline;
    25    margin-bottom: 24px;
    26  `
    27  
    28  export let Title = styled.h2`
    29    font-family: ${Font.monospace};
    30    font-size: ${FontSize.default};
    31    line-height: 17px;
    32    font-weight: unset;
    33    margin: 0;
    34  `
    35  
    36  export let HR = styled.hr`
    37    border-top: 1px dashed ${Color.gray50};
    38    margin: 16px -20px 24px -20px;
    39    color: white;
    40  `
    41  
    42  let CloseButton = styled.button`
    43    display: flex;
    44    align-items: center;
    45    border: 0;
    46    cursor: pointer;
    47    background-color: white;
    48    transition: background-color 300ms ease;
    49    border-radius: 32px 32px;
    50    padding: 0;
    51  
    52    svg {
    53      fill: ${Color.gray20};
    54    }
    55  
    56    &:hover,
    57    &:active {
    58      background-color: ${Color.grayLightest};
    59    }
    60  `
    61  
    62  let Content = styled.div`
    63    font: ${Font.monospace};
    64    font-size: ${FontSize.small};
    65    line-height: 28px;
    66  `
    67  
    68  let useStyles = makeStyles((theme: any) => ({
    69    paper: {
    70      display: "flex",
    71      flexDirection: "column",
    72      background: "#fff",
    73      color: Color.gray10,
    74      boxShadow: "3px 3px 4px rgba(0, 0, 0, 0.5)",
    75      borderRadius: "8px",
    76      padding: "16px 20px",
    77      width: "400px",
    78    },
    79  }))
    80  
    81  // A generic dialog that floats in a part of the screen.
    82  // Intended to be attached to a menu button.
    83  export default function FloatDialog(props: FloatDialogProps) {
    84    const popoverClasses = useStyles()
    85  
    86    let title = props.title
    87    let titleEl = typeof title == "string" ? <Title>{title}</Title> : title
    88    let anchorOrigin = props.anchorOrigin ?? {
    89      vertical: "bottom",
    90      horizontal: "right",
    91    }
    92    let transformOrigin = props.transformOrigin ?? {
    93      vertical: "top",
    94      horizontal: "right",
    95    }
    96    return (
    97      <Popover
    98        id={props.id}
    99        classes={popoverClasses}
   100        open={props.open}
   101        onClose={props.onClose}
   102        anchorEl={props.anchorEl}
   103        anchorOrigin={anchorOrigin}
   104        transformOrigin={transformOrigin}
   105        disableScrollLock={true}
   106      >
   107        <TitleBar>
   108          {titleEl}
   109          <CloseButton aria-label="Close dialog" onClick={props.onClose}>
   110            <CloseSvg role="presentation" />
   111          </CloseButton>
   112        </TitleBar>
   113  
   114        <Content>{props.children}</Content>
   115      </Popover>
   116    )
   117  }