mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-28 03:52:35 +00:00

Enforcing inclusion of our OSS license at the top of .ts and .tsx files. Also updates any relevant files in the repo that were previously missing the license comment. An additional `@license` comment is added to client/web/src/index.tsx to preserve the license in generated Javascript. Updates #10261 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
|
import cx from "classnames"
|
|
import React, { ReactNode } from "react"
|
|
|
|
type Props = {
|
|
className?: string
|
|
content: ReactNode
|
|
children: ReactNode
|
|
|
|
/**
|
|
* asChild renders the trigger element without wrapping it in a button. Use
|
|
* this when you want to use a `button` element as the trigger.
|
|
*/
|
|
asChild?: boolean
|
|
/**
|
|
* side is the side of the direction from the target element to render the
|
|
* popover.
|
|
*/
|
|
side?: "top" | "bottom" | "left" | "right"
|
|
/**
|
|
* sideOffset is how far from a give side to render the popover.
|
|
*/
|
|
sideOffset?: number
|
|
/**
|
|
* align is how to align the popover with the target element.
|
|
*/
|
|
align?: "start" | "center" | "end"
|
|
/**
|
|
* alignOffset is how far off of the alignment point to render the popover.
|
|
*/
|
|
alignOffset?: number
|
|
|
|
open?: boolean
|
|
onOpenChange?: (open: boolean) => void
|
|
}
|
|
|
|
/**
|
|
* Popover is a UI component that allows rendering unique controls in a floating
|
|
* popover, attached to a trigger element. It appears on click and manages focus
|
|
* on its own behalf.
|
|
*
|
|
* To use the Popover, pass the content as children, and give it a `trigger`:
|
|
*
|
|
* <Popover trigger={<span>Open popover</span>}>
|
|
* <p>Hello world!</p>
|
|
* </Popover>
|
|
*
|
|
* By default, the toggle is wrapped in an accessible <button> tag. You can
|
|
* customize by providing your own button and using the `asChild` prop.
|
|
*
|
|
* <Popover trigger={<Button>Hello</Button>} asChild>
|
|
* <p>Hello world!</p>
|
|
* </Popover>
|
|
*
|
|
* The former style is recommended whenever possible.
|
|
*/
|
|
export default function Popover(props: Props) {
|
|
const {
|
|
children,
|
|
className,
|
|
content,
|
|
side,
|
|
sideOffset,
|
|
align,
|
|
alignOffset,
|
|
asChild,
|
|
open,
|
|
onOpenChange,
|
|
} = props
|
|
|
|
return (
|
|
<PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
|
|
<PopoverPrimitive.Trigger asChild={asChild}>
|
|
{children}
|
|
</PopoverPrimitive.Trigger>
|
|
<PortalContainerContext.Consumer>
|
|
{(portalContainer) => (
|
|
<PopoverPrimitive.Portal container={portalContainer}>
|
|
<PopoverPrimitive.Content
|
|
className={cx(
|
|
"origin-radix-popover shadow-popover bg-white rounded-md z-50",
|
|
"state-open:animate-scale-in state-closed:animate-scale-out",
|
|
className
|
|
)}
|
|
side={side}
|
|
sideOffset={sideOffset}
|
|
align={align}
|
|
alignOffset={alignOffset}
|
|
collisionPadding={12}
|
|
>
|
|
{content}
|
|
</PopoverPrimitive.Content>
|
|
</PopoverPrimitive.Portal>
|
|
)}
|
|
</PortalContainerContext.Consumer>
|
|
</PopoverPrimitive.Root>
|
|
)
|
|
}
|
|
|
|
Popover.defaultProps = {
|
|
sideOffset: 10,
|
|
}
|
|
|
|
const PortalContainerContext = React.createContext<HTMLElement | undefined>(
|
|
undefined
|
|
)
|