Icon Box
icon-boxuiIcon container primitive with calibrated sizes (2xs to xl), surface variants (solid, outline, subtle, primary, muted), and 2.5D layered IconStack for empty states and feature hero cards.
Installation
$pnpm dlx shadcn@latest add https://uipkge.dev/r/react/icon-box.json$npx shadcn@latest add https://uipkge.dev/r/react/icon-box.json$yarn dlx shadcn@latest add https://uipkge.dev/r/react/icon-box.json$bunx shadcn@latest add https://uipkge.dev/r/react/icon-box.jsonNamed registry:
npx shadcn@latest add @uipkge-react/icon-boxInstalls to:components/ui/icon-box/Examples
Loading interactive previews…
Loading interactive previews…
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
iconOptional icon component rendered inside the box (e.g. a Lucide icon). | React.ComponentType<{ className?: string; 'aria-hidden'?: boolean | 'true' | 'false' }> | — | optional |
variant | IconBoxVariant | — | optional |
shape | IconBoxShape | — | optional |
size | IconBoxSize | — | optional |
iconClass | string | — | optional |
iconClassName@deprecated Use `iconClass`. Kept for backwards compatibility. | string | — | optional |
Used by
Files installed (3)
components/ui/icon-box/icon-box.tsx2.6 kB
import * as React from 'react' import { cn } from '@/lib/utils' export type IconBoxVariant = 'primary' | 'muted' | 'outline' | 'solid' | 'subtle' | 'destructive' | 'success' | 'warning' | 'ghost' | 'custom' export type IconBoxSize = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' export type IconBoxShape = 'rounded' | 'circle' | 'square' export interface IconBoxProps extends React.HTMLAttributes<HTMLDivElement> { /** Optional icon component rendered inside the box (e.g. a Lucide icon). */ icon?: React.ComponentType<{ className?: string; 'aria-hidden'?: boolean | 'true' | 'false' }> variant?: IconBoxVariant shape?: IconBoxShape size?: IconBoxSize iconClass?: string /** @deprecated Use `iconClass`. Kept for backwards compatibility. */ iconClassName?: string } const variantClasses: Record<IconBoxVariant, string> = { primary: 'bg-primary/10 text-primary', muted: 'bg-muted text-muted-foreground', outline: 'border border-border bg-background text-foreground shadow-xs', solid: 'bg-foreground text-background shadow-xs', subtle: 'bg-accent text-accent-foreground', destructive: 'bg-destructive/10 text-destructive', success: 'bg-success/15 text-success', warning: 'bg-warning/15 text-warning', ghost: 'text-muted-foreground hover:bg-accent hover:text-foreground', custom: '', } const shapeClasses: Record<IconBoxShape, string> = { rounded: 'rounded-lg', circle: 'rounded-full', square: 'rounded-none', } const sizeClasses: Record<IconBoxSize, string> = { '2xs': 'size-6 p-1', xs: 'size-7 p-1.5', sm: 'size-8 p-1.5', md: 'size-9 p-2', lg: 'size-11 p-2.5', xl: 'size-14 p-3.5', } const iconSizes: Record<IconBoxSize, string> = { '2xs': 'size-3', xs: 'size-3.5', sm: 'size-4', md: 'size-4.5', lg: 'size-6', xl: 'size-7', } const IconBox = React.forwardRef<HTMLDivElement, IconBoxProps>( ( { className, icon: Icon, variant = 'primary', shape = 'rounded', size = 'md', iconClass, iconClassName, children, ...props }, ref, ) => ( <div ref={ref} data-uipkge="" data-slot="icon-box" data-variant={variant} data-size={size} data-shape={shape} className={cn( 'inline-flex shrink-0 items-center justify-center transition-colors', variantClasses[variant], shapeClasses[shape], sizeClasses[size], className, )} {...props} > {children ? ( children ) : Icon ? ( <Icon className={cn(iconSizes[size], iconClass ?? iconClassName)} aria-hidden="true" /> ) : null} </div> ), ) IconBox.displayName = 'IconBox' export { IconBox }components/ui/icon-box/IconStack.tsx2.9 kB
'use client' import * as React from 'react' import { cn } from '@/lib/utils' export type IconStackVariant = 'primary' | 'muted' | 'destructive' | 'success' | 'warning' export type IconStackSize = 'sm' | 'md' | 'lg' | 'xl' export interface IconStackProps extends React.HTMLAttributes<HTMLDivElement> { icon?: React.ComponentType<{ className?: string; 'aria-hidden'?: boolean | 'true' | 'false' }> variant?: IconStackVariant size?: IconStackSize iconClass?: string } const sizeMap: Record<IconStackSize, { root: string; base: string; icon: string }> = { sm: { root: 'size-10', base: 'size-8 rounded-lg', icon: 'size-4' }, md: { root: 'size-14', base: 'size-11 rounded-xl', icon: 'size-5' }, lg: { root: 'size-18', base: 'size-14 rounded-2xl', icon: 'size-7' }, xl: { root: 'size-24', base: 'size-18 rounded-3xl', icon: 'size-9' }, } const variantMap: Record<IconStackVariant, { back: string; front: string; text: string }> = { primary: { back: 'bg-primary/20 border-primary/30', front: 'bg-background border-primary/20 shadow-primary/10', text: 'text-primary', }, muted: { back: 'bg-muted border-border', front: 'bg-card border-border shadow-black/5', text: 'text-muted-foreground', }, destructive: { back: 'bg-destructive/20 border-destructive/30', front: 'bg-background border-destructive/20 shadow-destructive/10', text: 'text-destructive', }, success: { back: 'bg-success/20 border-success/30', front: 'bg-background border-success/20 shadow-success/10', text: 'text-success', }, warning: { back: 'bg-warning/20 border-warning/30', front: 'bg-background border-warning/20 shadow-warning/10', text: 'text-warning', }, } export const IconStack = React.forwardRef<HTMLDivElement, IconStackProps>( ({ className, icon: Icon, variant = 'primary', size = 'md', iconClass, children, ...props }, ref) => { return ( <div ref={ref} data-uipkge="" data-slot="icon-stack" data-variant={variant} data-size={size} className={cn('relative inline-flex items-center justify-center select-none', sizeMap[size].root, className)} {...props} > <div aria-hidden="true" className={cn( 'absolute inset-0 m-auto rotate-6 border transition-transform duration-300', sizeMap[size].base, variantMap[variant].back, )} /> <div className={cn( 'relative z-10 flex items-center justify-center border shadow-md transition-transform duration-300 group-hover:-translate-y-0.5', sizeMap[size].base, variantMap[variant].front, variantMap[variant].text, )} > {children ? ( children ) : Icon ? ( <Icon className={cn(sizeMap[size].icon, iconClass)} aria-hidden="true" /> ) : null} </div> </div> ) }, ) IconStack.displayName = 'IconStack'components/ui/icon-box/index.ts0.2 kB
export { IconBox, type IconBoxProps, type IconBoxVariant, type IconBoxSize, type IconBoxShape } from './icon-box' export { IconStack, type IconStackProps, type IconStackVariant, type IconStackSize } from './IconStack'
Raw manifest:https://uipkge.dev/r/react/icon-box.json