Block Ui
block-ui ui Overlay that blocks interaction during loading. Wraps content and shows a spinner + message overlay. The blocking prop toggles the blocked state with configurable overlay opacity, color, background blur, and custom icon/message slots. Composes the spinner primitive.
Also available for Vue ->Installation
$ pnpm dlx shadcn@latest add https://uipkge.dev/r/react/block-ui.json $ npx shadcn@latest add https://uipkge.dev/r/react/block-ui.json $ yarn dlx shadcn@latest add https://uipkge.dev/r/react/block-ui.json $ bunx shadcn@latest add https://uipkge.dev/r/react/block-ui.json Named registry:
npx shadcn@latest add @uipkge-react/block-ui Installs to: components/ui/block-ui/ Examples
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
blocking When true, the overlay is shown and the wrapped content is blocked. | boolean | — | optional |
message render prop is supplied via children. | React.ReactNode | — | optional |
opacity | number | — | optional |
overlayColor | string | — | optional |
blur | boolean | — | optional |
showSpinner | boolean | — | optional |
icon Custom icon node replacing the default Spinner (Vue #icon slot). | React.ReactNode | — | optional |
messageSlot Custom message node replacing the `message` string (Vue #message slot). | React.ReactNode | — | optional |
npm dependencies
Includes
Files installed (3)
-
components/ui/block-ui/BlockUi.tsx 2.7 kB
import * as React from 'react' import { cn } from '@/lib/utils' import { blockUiVariants } from './block-ui.variants' import { Spinner } from '@/components/ui/spinner' export interface BlockUiProps extends React.HTMLAttributes<HTMLDivElement> { /** When true, the overlay is shown and the wrapped content is blocked. */ blocking?: boolean /** Plain-text or rich message shown under the icon. Ignored when a message * render prop is supplied via children. */ message?: React.ReactNode opacity?: number overlayColor?: string blur?: boolean showSpinner?: boolean /** Custom icon node replacing the default Spinner (Vue #icon slot). */ icon?: React.ReactNode /** Custom message node replacing the `message` string (Vue #message slot). */ messageSlot?: React.ReactNode } const BlockUi = React.forwardRef<HTMLDivElement, BlockUiProps>( ( { className, children, blocking = false, message = 'Loading...', opacity = 0.6, overlayColor = '', blur = false, showSpinner = true, icon, messageSlot, ...props }, ref, ) => { const overlayStyle: React.CSSProperties = React.useMemo(() => { const style: React.CSSProperties = { opacity } if (overlayColor) style.backgroundColor = overlayColor return style }, [opacity, overlayColor]) return ( <div ref={ref} data-uipkge="" data-slot="block-ui" data-blocked={blocking ? '' : undefined} className={cn(blockUiVariants(), className)} {...props} > {/* Wrapped content */} <div className={cn( 'block-ui-content', blur && blocking && 'pointer-events-none blur-[2px] transition-[filter]', )} > {children} </div> {/* Blocking overlay */} {blocking && ( <div className="absolute inset-0 z-50 flex flex-col items-center justify-center gap-3" role="status" aria-live="polite" aria-busy="true" > {/* Background layer (opacity only affects this layer) */} <div className={cn('absolute inset-0', !overlayColor && 'bg-background')} style={overlayStyle} /> {/* Content layer (spinner + message stay fully opaque) */} {icon ?? (showSpinner && <Spinner size="lg" />)} {messageSlot ? ( <div className="text-foreground text-sm font-medium">{messageSlot}</div> ) : ( message && <p className="text-foreground text-sm font-medium">{message}</p> )} </div> )} </div> ) }, ) BlockUi.displayName = 'BlockUi' export { BlockUi } -
components/ui/block-ui/block-ui.variants.ts 0.2 kB
import type { VariantProps } from 'class-variance-authority' import { cva } from 'class-variance-authority' export const blockUiVariants = cva('relative inline-block') export type BlockUiVariants = VariantProps<typeof blockUiVariants> -
components/ui/block-ui/index.ts 0.1 kB
export { BlockUi, type BlockUiProps } from './BlockUi' export { blockUiVariants, type BlockUiVariants } from './block-ui.variants'
Raw manifest: https://uipkge.dev/r/react/block-ui.json