Installation
npm install react-driftkitInteractive Demo
Active
off · ⌘⇧C toggles
Box model
on
Colors + contrast
Spacing
A11y (role + name + state)
Turn on the picker, then hover any of these elements — including this text. The overlay shows the box-model layers and the bubble reports the tag, selector, dimensions, font, color + background + WCAG contrast, and padding/margin.
card.accent
card.dark
Nothing selected yet. Click an element while the picker is on.
API Reference
| Prop | Type | Default |
|---|---|---|
active Controlled active state. Omit for uncontrolled. | boolean | — |
defaultActive Uncontrolled initial active state. | boolean | false |
on Event handlers: activeChange, select, hover. All optional. | InspectorBubbleEvents | — |
on.activeChange Fires whenever active toggles — click-select, Escape, or the hotkey. | (active: boolean) => void | — |
on.select Fires on click with the selected element and its info snapshot. | (el: Element, info: ElementInfo) => void | — |
on.hover Fires whenever the hovered element changes while active. | (el: Element | null, info: ElementInfo | null) => void | — |
behavior Behavior knobs: hotkey, ignoreSelector, exitOnSelect, exitOnEscape. | InspectorBubbleBehavior | — |
behavior.hotkey Keyboard shortcut to toggle active, e.g. "cmd+shift+c". Supports cmd/meta, ctrl, shift, alt/option + key. | string | — |
behavior.ignoreSelector CSS selector for elements the picker skips. Elements with [data-inspector-bubble-ignore] are always skipped. | string | — |
behavior.exitOnSelect Deactivate after a successful click-select. | boolean | true |
behavior.exitOnEscape Deactivate when Escape is pressed. | boolean | true |
highlight Highlight layer: boxModel, outline, colors. | InspectorBubbleHighlight | — |
highlight.boxModel Render the 4-layer DevTools box model (margin / border / padding / content). | boolean | true |
highlight.outline Render a single outline around the element instead of the box model. | boolean | !boxModel |
highlight.colors Override overlay colors: margin, border, padding, content, outline. | InspectorBubbleColors | DevTools-like defaults |
bubble Info bubble: enabled, fields, render. | InspectorBubbleBubble | — |
bubble.enabled Render the info bubble. Set false to show only the highlight. | boolean | true |
bubble.render Full escape hatch — replaces the default bubble content. | (info: ElementInfo) => ReactNode | — |
bubble.fields Per-field toggles for the default bubble. | InspectorBubbleFields | all true |
bubble.fields.tag Lowercase tag name. | boolean | true |
bubble.fields.selector Short CSS selector ( #id, [data-testid], or tag.class1.class2). | boolean | true |
bubble.fields.dimensions Rendered width × height. | boolean | true |
bubble.fields.font Font size, rendered family (first loaded font from the declared list), and weight. | boolean | true |
bubble.fields.colors Foreground + effective background swatches and WCAG contrast ratio. | boolean | true |
bubble.fields.spacing Padding and margin values (T R B L). | boolean | true |
bubble.fields.role ARIA role (explicit or implicit from the tag). | boolean | true |
bubble.fields.accessibleName Computed accessible name (aria-labelledby → aria-label → alt → <label> → text content). | boolean | true |
bubble.fields.a11yState tabindex, focusable, disabled, hidden, expanded/pressed/checked/selected when set. | boolean | true |
zIndex z-index for the overlay and bubble. | number | 2147483647 |
style Inline styles merged with the default bubble wrapper. | CSSProperties | {} |
className CSS class added to the default bubble wrapper. | string | '' |
Overlay elements carry data-inspector-bubble-ignore, so the picker never highlights itself. Add this attribute to your own UI (toolbar buttons, the toggle that controls the picker, etc.) to exempt it from selection.
Code Examples
tsx
import { useState } from 'react';
import { InspectorBubble } from 'react-driftkit';
function App() {
const [active, setActive] = useState(false);
return (
<>
<button
data-inspector-bubble-ignore
onClick={() => setActive(a => !a)}
>
{active ? 'Stop inspecting' : 'Inspect element'}
</button>
<InspectorBubble
active={active}
behavior={{ hotkey: 'cmd+shift+c' }}
on={{
activeChange: setActive,
select: (el, info) => console.log('selected', el, info),
}}
/>
</>
);
}Types
typescript
interface ElementInfo {
element: Element;
tag: string;
selector: string;
rect: DOMRect;
font: {
family: string; // declared font-family list
rendered: string; // first family the browser actually has loaded
size: string;
weight: string;
lineHeight: string;
};
color: string;
backgroundColor: string;
contrastRatio: number | null;
padding: { top: number; right: number; bottom: number; left: number };
margin: { top: number; right: number; bottom: number; left: number };
border: { top: number; right: number; bottom: number; left: number };
a11y: {
role: string | null;
explicitRole: boolean;
accessibleName: string | null;
ariaLabel: string | null;
ariaLabelledBy: string | null;
ariaDescribedBy: string | null;
tabIndex: number | null;
focusable: boolean;
disabled: boolean;
hidden: boolean;
expanded: boolean | null;
pressed: boolean | 'mixed' | null;
checked: boolean | 'mixed' | null;
selected: boolean | null;
};
}
interface InspectorBubbleProps {
active?: boolean;
defaultActive?: boolean;
on?: {
activeChange?: (active: boolean) => void;
select?: (element: Element, info: ElementInfo) => void;
hover?: (element: Element | null, info: ElementInfo | null) => void;
};
behavior?: {
hotkey?: string;
ignoreSelector?: string;
exitOnSelect?: boolean; // default true
exitOnEscape?: boolean; // default true
};
highlight?: {
boxModel?: boolean; // default true — 4-layer DevTools model
outline?: boolean; // defaults to !boxModel
colors?: {
margin?: string;
border?: string;
padding?: string;
content?: string;
outline?: string;
};
};
bubble?: {
enabled?: boolean;
fields?: {
tag?: boolean;
selector?: boolean;
dimensions?: boolean;
font?: boolean;
colors?: boolean;
spacing?: boolean;
role?: boolean;
accessibleName?: boolean;
a11yState?: boolean;
};
render?: (info: ElementInfo) => ReactNode;
};
zIndex?: number;
className?: string;
style?: CSSProperties;
}Enjoying react-driftkit?
Star the repo on GitHub to help more devs discover it.