Clawscale

Portal provider

PortalProvider sets where the portals in its subtree render and which class name they get. Popovers, tooltips, dialogs and drawers all render through portals. ClawscaleProvider includes one.

Usage#

import { PortalProvider } from "@clawscale/react";

For the whole app, pass the options to ClawscaleProvider.

<ClawscaleProvider portalClassName="app-portal">{children}</ClawscaleProvider>
  • portalContainer: the element that portals render into. Defaults to document.body.
  • portalClassName: a class name added to every portal element, for example to scope your CSS.

Examples#

Full screen panel#

In full screen, the browser shows only the full screen element and its descendants. A nested PortalProvider renders the panel's menus inside the panel, so they stay visible. Switch to full screen, then open the time range menu.

Throughput, us-east-1
import { Button, Card, H6, Menu, MenuItem, PopoverNext, PortalProvider } from "@clawscale/react";
import { useState } from "react";

const ranges = ["Last hour", "Last 24 hours", "Last 7 days"];

export default function PortalProviderFullscreen() {
  const [panel, setPanel] = useState<HTMLDivElement | null>(null);
  const [range, setRange] = useState("Last hour");
  const toggleFullscreen = () => {
    if (document.fullscreenElement) document.exitFullscreen();
    else panel?.requestFullscreen?.();
  };
  return (
    <Card ref={setPanel} style={{ display: "flex", alignItems: "center", gap: 8, width: "100%", maxWidth: 480 }}>
      <H6 style={{ flex: 1, margin: 0 }}>Throughput, us-east-1</H6>
      <PortalProvider portalContainer={panel ?? undefined}>
        <PopoverNext
          animation="minimal"
          arrow={false}
          placement="bottom-end"
          content={
            <Menu>
              {ranges.map((name) => (
                <MenuItem active={name === range} key={name} text={name} onClick={() => setRange(name)} />
              ))}
            </Menu>
          }
        >
          <Button endIcon="caret-down" text={range} />
        </PopoverNext>
      </PortalProvider>
      <Button aria-label="Toggle full screen" icon="fullscreen" onClick={toggleFullscreen} />
    </Card>
  );
}

A nested PortalProvider replaces both options for its subtree. The container prop of a single Portal wins over portalContainer.

Props interface#

interface PortalContextOptions@clawscale/react
PropsDescription
portalClassName
string
Additional CSS classes to add to all Portal elements in this React context.
portalContainer
HTMLElement
The HTML element that all Portal elements in this React context will be added as children to