- π¦ Generate a 'spotlight' that follows the size and position of any active target.
- π Auto-updated after resizing or DOM changing.
- β‘οΈ Options to fit any position between smooth effect to high-efficiency performance.
- πͺ© Apply customized style to the 'light' easily.
- π½ β 2kB minzipped.
spotlight-demo.mov
| Description | Live demo |
|---|---|
| Basic | |
| Auto-updated resize | |
| Auto-updated DOM change | |
| Throttle | |
| Custom light style | |
| Pseudo light |
Note
- An animated active indicator for a component like
<ToggleButton>,<Tabs>. - A highlight effect for a self-controlled focused system, like the result list of a
<SearchBar>. - ...
npm install use-spotlight+import { useSpotlight } from 'use-spotlight'
() => {
const [active, setActive] = useState(-1)
// init hook
+ const { stage, actor, style } = useSpotlight()
return (
// set ref for 'stage'
<ul
+ ref={stage}
>
{list.map(({ val }) => (
<li
onClick={() => setActive(val)}
// set ref for 'actor'
+ ref={val === active ? actor : null}
>
{val}
</li>
))}
// set 'style' to the light
+ <i style={style} />
</ul>
)
}Parameters: SpotlightOptions
throttleWait: The number of milliseconds to throttle invocations to.default: 0stageBorderEdge: With default setting, the 'light' will be positioned relative to the padding edge of the 'stage', which will cause an offset if 'stage' has borders. Set totrue, if want to use the border edge, which will hurt performance but be more accurate on the position.default: falsestageMutation: Enable watching 'stage'childlistsubtreeDOM mutation.default: falselightPseudo:::beforeor::afterto enable pseudo element as 'light'. In this mode, there's no need to insert a 'light' element explicitly. It's useful for case that no extra element wanted under the 'stage'.default: null
Returns: Spotlight
stage: The RefCallback which will be assigned to node as container.actor: The RefCallback which will be assigned to node as target to follow.style: The CSSProperties for the node 'light'.size: The offset[x, y, width, height]between 'actor' and 'stage'.
Important
stageBorderEdge=trueusesgetComputedStyle()to calculate thebordersize of 'stage', but it's bad for performance, there're other alternatives to achieve this:- Use
outlineinstead ofborder. - Override the style of 'light':
top: -1 * var(--border-top-size-stage),left: -1 * var(--border-left-size-stage)
- Use
stageMutation=trueadd an extraMutationObserverto the 'stage', consider using the default setting unless it can not cover some of the cases.