UNPKG

fumadocs-ui

Version:

The framework for building a documentation website in Next.js

55 lines (54 loc) 3.18 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useEffect, useState } from 'react'; import { X } from '../icons.js'; import { cn } from '../utils/cn.js'; import { buttonVariants } from '../components/ui/button.js'; export function Banner({ id, variant = 'normal', changeLayout = true, height = '3rem', rainbowColors = [ 'rgba(0,149,255,0.56)', 'rgba(231,77,255,0.77)', 'rgba(255,0,0,0.73)', 'rgba(131,255,166,0.66)', ], ...props }) { const [open, setOpen] = useState(true); const globalKey = id ? `nd-banner-${id}` : null; useEffect(() => { if (globalKey) setOpen(localStorage.getItem(globalKey) !== 'true'); }, [globalKey]); if (!open) return null; return (_jsxs("div", { id: id, ...props, className: cn('sticky top-0 z-40 flex flex-row items-center justify-center px-4 text-center text-sm font-medium', variant === 'normal' && 'bg-fd-secondary', variant === 'rainbow' && 'bg-fd-background', !open && 'hidden', props.className), style: { height, }, children: [changeLayout && open ? (_jsx("style", { children: globalKey ? `:root:not(.${globalKey}) { --fd-banner-height: ${height}; }` : `:root { --fd-banner-height: ${height}; }` })) : null, globalKey ? (_jsx("style", { children: `.${globalKey} #${id} { display: none; }` })) : null, globalKey ? (_jsx("script", { dangerouslySetInnerHTML: { __html: `if (localStorage.getItem('${globalKey}') === 'true') document.documentElement.classList.add('${globalKey}');`, } })) : null, variant === 'rainbow' ? flow({ colors: rainbowColors, }) : null, props.children, id ? (_jsx("button", { type: "button", "aria-label": "Close Banner", onClick: () => { setOpen(false); if (globalKey) localStorage.setItem(globalKey, 'true'); }, className: cn(buttonVariants({ color: 'ghost', className: 'absolute end-2 top-1/2 -translate-y-1/2 text-fd-muted-foreground/50', size: 'icon-sm', })), children: _jsx(X, {}) })) : null] })); } const maskImage = 'linear-gradient(to bottom,white,transparent), radial-gradient(circle at top center, white, transparent)'; function flow({ colors }) { return (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute inset-0 z-[-1]", style: { maskImage, maskComposite: 'intersect', animation: 'fd-moving-banner 20s linear infinite', backgroundImage: `repeating-linear-gradient(70deg, ${[...colors, colors[0]].map((color, i) => `${color} ${(i * 50) / colors.length}%`).join(', ')})`, backgroundSize: '200% 100%', filter: 'saturate(2)', } }), _jsx("style", { children: `@keyframes fd-moving-banner { from { background-position: 0% 0; } to { background-position: 100% 0; } }` })] })); }