use-spotlight
v1.1.0
Published
A react hook that generates an animated 'spotlight' follows the active target.
Downloads
33
Maintainers
Readme
Features
- 🔦 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.
Demo
https://github.com/9am/use-spotlight/assets/1435457/5b570780-abb7-4df9-9e19-7454eafecce4
Live demos
|Description|Live demo| |:---------:|:-------:| | Basic | | | Auto-updated resize | | | Auto-updated DOM change | | | Throttle | | | Custom light style | | | Pseudo light | |
Use cases
[!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>
.- ...
Usage
Install
npm install use-spotlight
JSX
+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>
)
}
Documentation
useSpotlight( SpotlightOptions? )
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)
stageMutation=true
add an extraMutationObserver
to the 'stage', consider using the default setting unless it can not cover some of the cases.