Alert
tetra-ui/alertFreeComponent
Displays a callout for user attention.
Live preview
live · rendered by the registry
Rendered by tetra-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://tetra-ui.com/r/alert.jsonSource
1import { cva, type VariantProps } from "class-variance-authority";2import {3 Children,4 cloneElement,5 createContext,6 isValidElement,7 useContext,8 useMemo,9} from "react";10import { Text, View } from "react-native";11import { cn } from "@/lib/utils";1213// Types14type AlertVariant = VariantProps<typeof alertVariants>["variant"];1516type AlertContextValue = {17 variant: AlertVariant;18};1920type AlertProps = React.ComponentProps<typeof View> &21 VariantProps<typeof alertVariants> & {22 children?: React.ReactNode;23 };2425type AlertIconProps = {26 children: React.ReactNode;27 className?: string;28};2930type ClassNameElement = React.ReactElement<{ className?: string }>;3132type AlertSlot = "icon" | "action";3334type AlertSlotComponent = {35 displayName?: string;36 slot?: AlertSlot;37};3839// Context40const AlertContext = createContext<AlertContextValue | null>(null);4142const useAlertContext = () => {43 const context = useContext(AlertContext);44 if (!context) {45 throw new Error("Alert components must be used within an Alert");46 }47 return context;48};4950const getAlertSlot = (type: string | React.JSXElementConstructor<unknown>) => {51 if (typeof type === "string") {52 return;53 }5455 return (type as AlertSlotComponent).slot;56};5758// Components59export const Alert = ({60 children,61 className,62 variant = "default",63 style,64 ...props65}: AlertProps) => {66 const ctx = useMemo(67 () => ({68 variant,69 }),70 [variant]71 );7273 const childArray = Children.toArray(children);74 const icons: React.ReactNode[] = [];75 const actions: React.ReactNode[] = [];76 const content: React.ReactNode[] = [];7778 for (const child of childArray) {79 if (!isValidElement(child)) {80 content.push(child);81 continue;82 }8384 const slot = getAlertSlot(child.type);8586 if (slot === "icon") {87 icons.push(child);88 continue;89 }9091 if (slot === "action") {92 actions.push(child);93 continue;94 }9596 content.push(child);97 }9899 const hasAction = actions.length > 0;100101 return (102 <AlertContext.Provider value={ctx}>103 <View104 accessibilityRole="alert"105 className={cn(106 alertVariants({ className, variant }),107 hasAction && "pr-24"108 )}109 data-slot="alert"110 style={[111 {112 alignItems: "flex-start",113 flexDirection: "row",114 gap: 8,115 },116 style,117 ]}118 {...props}119 >120 {icons}121 <View122 className="min-w-0 flex-1 gap-0.5"123// … truncated
Files it writes
More from tetra-ui
All 41 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | tetra-ui | Components | Free | 1 dep | |
| Action Inputaction-input | tetra-ui | Components | Free | no deps | |
| Avataravatar | tetra-ui | Components | Free | no deps | |
| Badgebadge | tetra-ui | Components | Free | no deps | |
| Bottom Sheetbottom-sheet | tetra-ui | Components | Free | 4 deps · 7 files | |
| Buttonbutton | tetra-ui | Components | Free | no deps | |
| Cardcard | tetra-ui | Components | Free | no deps | |
| Checkboxcheckbox | tetra-ui | Components | Free | 1 dep |
