- π¦ 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: 0
stageBorderEdge
: 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: false
stageMutation
: Enable watching 'stage'childlist
subtree
DOM mutation.default: false
lightPseudo
:::before
or::after
to 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=true
usesgetComputedStyle()
to calculate theborder
size of 'stage', but it's bad for performance, there're other alternatives to achieve this:- Use
outline
instead ofborder
. - Override the style of 'light':
top: -1 * var(--border-top-size-stage)
,left: -1 * var(--border-left-size-stage)
- Use
stageMutation=true
add an extraMutationObserver
to the 'stage', consider using the default setting unless it can not cover some of the cases.