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? )
SpotlightOptions
Parameters: -
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
Spotlight
Returns: -
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.