primitives
Layered Shadow Tooltip
A CSS-art tooltip popup with a signature stacked box-shadow border technique — eight to ten concentric shadow layers build up a retro/pixel-art multi-ring outline effect on both the pill trigger and the floating popup. The popup slides up and fades in above the trigger on hover and keyboard focus (focus-visible ring, aria-describedby wiring, role='tooltip'). The star icon inside renders via a primary-token linear-gradient fill, and the decorative content-placeholder lines use token-derived colors throughout. No JS is required for the hover path; keyboard focus is tracked via a React state flag to show the tooltip for non-pointer users. The mount-gate pattern prevents hydration mismatch between SSR and the first client render.
Ported from SelfMadeSystem (MIT)
Install
1. Register the namespace (once per project):
// components.json — register the @bottega namespace once
{
"registries": {
"@bottega": { "url": "https://bottega.ariacode.ca/r/{name}.json" }
}
}2. Add the component:
npx shadcn add @bottega/layered-shadow-tooltipUsage
<LayeredShadowTooltip>
{/* children */}
</LayeredShadowTooltip>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| content | React.ReactNode | — | Text or node shown inside the tooltip popup. The default preview renders a star icon + two placeholder lines when this prop is omitted — supply a string for a real label. |
| children* | React.ReactNode | — | The trigger element that the tooltip is anchored to. |
| className | string | Additional class names merged onto the wrapper element. |
Source
"use client";
import { useEffect, useId, useRef, useState } from "react";
import type React from "react";
import { useReducedMotion } from "motion/react";
import styles from "./layered-shadow-tooltip.module.css";
export type LayeredShadowTooltipProps = {
/**
* Text or node shown inside the tooltip popup.
* The default preview renders a star icon + two placeholder lines
* when this prop is omitted — supply a string for a real label.
*/
content?: React.ReactNode;
/** The trigger element that the tooltip is anchored to. */
children: React.ReactNode;
/** Additional class names merged onto the wrapper element. */
className?: string;
};
/**
* Layered-shadow tooltip trigger element.
* The tooltip popup is shown above the trigger on hover AND keyboard focus.
* Accessibility: trigger is focusable, tooltip has role="tooltip",
* and the trigger is wired via aria-describedby.
*/
export function LayeredShadowTooltip({
content,
children,
className = "",
}: LayeredShadowTooltipProps) {
const tooltipId = useId();
const triggerRef = useRef<HTMLSpanElement>(null);
// Mount-gate + null-safe reduced-motion (avoids hydration mismatch).
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
const prefersReducedMotion = useReducedMotion();
const reduce = !mounted || prefersReducedMotion === null || prefersReducedMotion;
// Keyboard focus state drives the open class when mouse is not in play.
const [focused, setFocused] = useState(false);
const rootClassName = [
styles.container,
focused && styles.focused,
reduce && styles.reducedMotion,
className,
]
.filter(Boolean)
.join(" ");
const defaultContent = (
<>
{/* Decorative star icon — aria-hidden because it's purely visual. */}
<span aria-hidden="true" className={styles.iconWrap}>
<svg
className={styles.icon}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<defs>
<linearGradient y2="1" x2="0" id={`${tooltipId}-gradient`}>
<stop
style={{ stopColor: "color-mix(in oklch, var(--primary) 70%, var(--background))" }}
offset="0%"
/>
<stop
style={{ stopColor: "var(--primary)" }}
offset="100%"
/>
</linearGradient>
</defs>
<path
d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"
fill={`url(#${tooltipId}-gradient)`}
className={styles.starPath}
/>
</svg>
</span>
{/* Decorative content lines — represent text rows inside the tooltip. */}
<span aria-hidden="true" className={styles.lines}>
<span className={styles.line1} />
<span className={styles.line2} />
</span>
</>
);
return (
<span
ref={triggerRef}
className={rootClassName}
aria-describedby={tooltipId}
tabIndex={0}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
>
{/* Tooltip popup — absolutely positioned above the trigger. */}
<span
id={tooltipId}
role="tooltip"
className={styles.tooltip}
>
{content != null ? (
content
) : (
<>
{/* Decorative star in tooltip */}
<span aria-hidden="true" className={styles.iconWrap}>
<svg
className={styles.icon}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<path
d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"
fill={`url(#${tooltipId}-gradient)`}
className={styles.starPath}
/>
</svg>
</span>
<span aria-hidden="true" className={styles.lines}>
<span className={styles.line1} />
<span className={styles.line2} />
</span>
</>
)}
</span>
{/* Trigger body: children + decorative placeholder lines. */}
<span className={styles.body}>
{children}
<span aria-hidden="true" className={styles.lines}>
<span className={styles.line1} />
<span className={styles.line2} />
</span>
</span>
</span>
);
}
Dependencies
- motion
- @bottega/tokens