Announcement
scrollxui/announcementFreeComponent
An announcement component that highlights key info with icons, effects, and expandable content.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/announcement.jsonSource
1'use client';2import React, { useState, useRef, useEffect, useCallback } from 'react';3import { createPortal } from 'react-dom';4import type { ComponentProps, HTMLAttributes, ReactNode } from 'react';5import { Badge } from '@/components/ui/badge';6import { cn } from '@/lib/utils';7import {8 motion,9 AnimatePresence,10 useAnimationFrame,11 useMotionTemplate,12 useMotionValue,13 useTransform,14} from 'motion/react';15import { ChevronDown } from 'lucide-react';16import LustreText from '@/components/ui/lustretext';1718const EXPANDABLE_CONTENT_SYMBOL = Symbol.for('AnnouncementExpandedContent');1920const MovingBorder = ({21 children,22 duration = 3000,23 rx,24 ry,25 ...otherProps26}: {27 children: React.ReactNode;28 duration?: number;29 rx?: string;30 ry?: string;31} & React.SVGProps<SVGSVGElement>) => {32 const pathRef = useRef<SVGRectElement | null>(null);33 const progress = useMotionValue(0);3435 useAnimationFrame((time) => {36 const length = pathRef.current?.getTotalLength?.();37 if (length) {38 const pxPerMillisecond = length / duration;39 progress.set((time * pxPerMillisecond) % length);40 }41 });4243 const x = useTransform(44 progress,45 (val) => pathRef.current?.getPointAtLength(val).x ?? 0,46 );47 const y = useTransform(48 progress,49 (val) => pathRef.current?.getPointAtLength(val).y ?? 0,50 );51 const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`;5253 return (54 <>55 <svg56 xmlns='http://www.w3.org/2000/svg'57 preserveAspectRatio='none'58 className='absolute h-full w-full'59 width='100%'60 height='100%'61 {...otherProps}62 >63 <rect64 fill='none'65 width='100%'66 height='100%'67 rx={rx}68 ry={ry}69 ref={pathRef}70 />71 </svg>72 <motion.div73 style={{74 position: 'absolute',75 top: 0,76 left: 0,77 display: 'inline-block',78 transform,79 }}80 >81 {children}82 </motion.div>83 </>84 );85};8687export type AnnouncementProps = Omit<ComponentProps<typeof Badge>, 'ref'> & {88 styled?: boolean;89 animation?: 'fade';90 icon?: ReactNode;91 iconPosition?: 'left' | 'right';92 shiny?: boolean;93 movingBorder?: boolean;94 movingBorderDuration?: number;95 movingBorderClassName?: string;96};9798function AnnouncementComponent({99 variant = 'outline',100 styled = false,101 animation = 'fade',102 icon,103 iconPosition = 'left',104// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep | |
| Aurora Dotsaurora-dots | scrollxui | Components | Free | 2 deps |
