# Popover Native

Native popover implementation using the browser's [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API/)

```js
const [show, setShow] = React.useState(false);
<>
  <SilkeButton label="Show popover" onClick={() => setShow(true)} />
  <SilkePopoverNative hide={!show} onRequestClose={() => setShow(false)}>
    <SilkeBox bg="neutral-20" pad column>
      <h1>Simple popover example</h1>
      <SilkeButton label="Close" onClick={() => setShow(false)} />
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## Placement Options

The "placement" prop controls where the popover appears relative to the anchor. Use "-start" or "-end" to align the popover's edges with the anchor's edges:

```js
const [show, setShow] = React.useState(false);
const [placement, setPlacement] = React.useState('bottom');
const placements = [
  'top',
  'top-start',
  'top-end',
  'right',
  'right-start',
  'right-end',
  'bottom',
  'bottom-start',
  'bottom-end',
  'left',
  'left-start',
  'left-end',
];

const PlacementSelect = () => {
  const groups = placements.reduce((acc, p) => {
    const group = p.split('-')[0];
    if (!acc[group]) {
      acc[group] = [];
    }
    acc[group].push(p);
    return acc;
  }, {});
  return (
    <SilkeBox column gap="s">
      {Object.entries(groups).map(([group, placements]) => {
        return (
          <SilkeBox key={group} column gap="s">
            <p>{group}</p>
            <SilkeBox flex wrap gap="s">
              {placements.map((p) => (
                <SilkeButton key={p} label={p} onClick={() => setPlacement(p)} />
              ))}
            </SilkeBox>
          </SilkeBox>
        );
      })}
    </SilkeBox>
  );
};

const ref = React.useRef();
<>
  <SilkeButton ref={ref} label="Show popover" onClick={() => setShow(true)} />
  <SilkePopoverNative
    hide={!show}
    anchor={ref}
    placement={placement}
    hideBackdrop
    onRequestClose={() => setShow(false)}
  >
    <SilkeBox bg="neutral-20" pad column gap="s">
      <h3>Placement</h3>
      <PlacementSelect />
      <SilkeButton label="Close" onClick={() => setShow(false)} />
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## With Offset

You can offset the popover position from the anchor point using "offsetX" and "offsetY":

```js
const [show, setShow] = React.useState(false);
const ref = React.useRef();
<>
  <SilkeButton ref={ref} label="Show popover" onClick={() => setShow(true)} />
  <SilkePopoverNative
    hide={!show}
    anchor={ref}
    placement="bottom"
    offsetX={100}
    offsetY={50}
    onRequestClose={() => setShow(false)}
  >
    <SilkeBox bg="neutral-20" pad column>
      <h2>Popover with offset</h2>
      <p>Offset 100px right, 50px down</p>
      <SilkeButton label="Close" onClick={() => setShow(false)} />
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## Hint Mode (Hover)

Use the "hint" prop to show the popover on hover using the [Interest Invoker API](https://css-tricks.com/a-first-look-at-the-interest-invoker-api-for-hover-triggered-popovers/). It automatically appears when hovering the anchor and stays visible when hovering the popover itself. No JavaScript is required - the browser handles all hover interactions:

```js
const ref = React.useRef();
<>
  <SilkeButton ref={ref} label="Hover me for a hint">
    <SilkeIcon icon="info" />
  </SilkeButton>
  <SilkePopoverNative hint anchor={ref} placement="bottom" hideBackdrop>
    <SilkeBox bg="neutral-20" pad="s" rounded="small">
      <p>This is a helpful hint that appears on hover!</p>
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## Without Backdrop

```js
const [show, setShow] = React.useState(false);
<>
  <SilkeButton label="Show popover (no backdrop)" onClick={() => setShow(true)} />
  <SilkePopoverNative hide={!show} hideBackdrop onRequestClose={() => setShow(false)}>
    <SilkeBox bg="neutral-20" pad column>
      <h2>Popover without backdrop</h2>
      <SilkeButton label="Close" onClick={() => setShow(false)} />
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## Auto-dismiss on Click Outside

The native popover automatically dismisses when clicking outside (light dismiss) or pressing Escape. Use "onRequestClose" to handle the dismissal:

```js
const [show, setShow] = React.useState(false);
<>
  <SilkeButton label="Show popover" onClick={() => setShow(true)} />
  <SilkePopoverNative
    hide={!show}
    onRequestClose={() => {
      console.log('Popover dismissed');
      setShow(false);
    }}
  >
    <SilkeBox bg="neutral-20" pad column>
      <h2>Click outside or press Escape to dismiss</h2>
      <SilkeButton label="Close manually" onClick={() => setShow(false)} />
    </SilkeBox>
  </SilkePopoverNative>
</>;
```

## Nested popovers

```js
const [show, setShow] = React.useState(false);
const [nestedShow, setNestedShow] = React.useState(false);
const buttonRef = React.useRef();
const nestedButtonRef = React.useRef();

<>
  <SilkeButton ref={buttonRef} label="Show popover" onClick={() => setShow(true)} />

  <SilkePopoverNative
    hide={!show}
    anchor={buttonRef}
    placement="bottom"
    hideBackdrop
    onRequestClose={() => setShow(false)}
  >
    <SilkeBox bg="neutral-20" pad column>
      <h2>Main popover</h2>
      <SilkeButton
        ref={nestedButtonRef}
        label="Show nested popover"
        onClick={() => setNestedShow(true)}
      />
    </SilkeBox>
    <SilkePopoverNative
      hide={!nestedShow}
      anchor={nestedButtonRef}
      placement="right"
      hideBackdrop
      onRequestClose={() => setNestedShow(false)}
    >
      <SilkeBox bg="neutral-20" pad column>
        <h2>Nested popover</h2>
      </SilkeBox>
    </SilkePopoverNative>
  </SilkePopoverNative>
</>;
```
