{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "notification",
  "title": "Notification",
  "description": "Notification from the Get IT Done design system.",
  "dependencies": [
    "class-variance-authority@^0.7.0",
    "lucide-react@^0.379.0"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/labels-context.json",
    "https://zero-design.itdone.de/r/recipes.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/notification.tsx",
      "content": "'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport * as React from 'react';\n\nimport { focusRing } from '@/lib/recipes';\nimport { cn } from '@/lib/utils';\nimport { useLabels } from '@/components/ui/labels-context';\n\n// Figma: Notification 1135:618 (Alerts & notifications). Passive, dismissible message card with optional icon tile, avatar, media, progress and actions.\nconst notificationVariants = cva('relative flex w-full gap-3 rounded-surface p-4 shadow-elevation-raised', {\n  variants: {\n    variant: {\n      default: 'border border-solid border-border bg-card text-text-default',\n      // Dark snackbar for short confirmations (\"Task deleted, Undo\").\n      inverse: 'items-center bg-background-inverse text-text-inverse',\n    },\n    layout: {\n      // Leading visual beside the text.\n      desktop: 'flex-row',\n      // Leading visual above the text, actions full width.\n      mobile: 'flex-col',\n    },\n  },\n  defaultVariants: { variant: 'default', layout: 'desktop' },\n});\n\n// Lets NotificationAction pick readable colours on the inverse surface without a prop.\nconst NotificationToneContext = React.createContext<'default' | 'inverse'>('default');\n\nconst iconToneClass = {\n  neutral: 'bg-muted text-icon-default',\n  brand: 'bg-background-brand-subtle text-icon-brand',\n  success: 'bg-background-success-subtle text-icon-success',\n  warning: 'bg-background-warning-subtle text-icon-warning',\n  destructive: 'bg-background-destructive-subtle text-icon-destructive',\n  info: 'bg-background-info-subtle text-icon-info',\n} as const;\n\nexport interface NotificationProps\n  extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,\n    VariantProps<typeof notificationVariants> {\n  title: React.ReactNode;\n  description?: React.ReactNode;\n  // Glyph for the round icon tile (see iconTone).\n  icon?: React.ReactNode;\n  iconTone?: keyof typeof iconToneClass;\n  // Avatar slot, shown instead of the icon tile.\n  avatar?: React.ReactNode;\n  // Image or preview below the text.\n  media?: React.ReactNode;\n  // Upload progress 0..100. Renders a labelled progress bar.\n  progress?: number;\n  progressLabel?: React.ReactNode;\n  // Text-style actions (Dismiss, Undo, View changes).\n  actions?: React.ReactNode;\n  // Renders a close button and calls this when pressed.\n  onDismiss?: () => void;\n  dismissLabel?: string;\n}\n\nconst Notification = React.forwardRef<HTMLDivElement, NotificationProps>(\n  (\n    {\n      className,\n      variant = 'default',\n      layout = 'desktop',\n      title,\n      description,\n      icon,\n      iconTone = 'neutral',\n      avatar,\n      media,\n      progress,\n      progressLabel,\n      actions,\n      onDismiss,\n      dismissLabel: dismissLabelProp,\n      role = 'status',\n      ...props\n    },\n    ref,\n  ) => {\n    const l = useLabels();\n    const dismissLabel = dismissLabelProp ?? l.dismiss;\n    const lead = avatar ? (\n      <div className=\"shrink-0\">{avatar}</div>\n    ) : icon ? (\n      <span\n        className={cn(\n          'flex h-avatar-md w-avatar-md shrink-0 items-center justify-center rounded-full',\n          iconToneClass[iconTone],\n        )}\n      >\n        {icon}\n      </span>\n    ) : null;\n    const inverse = variant === 'inverse';\n    return (\n      <NotificationToneContext.Provider value={inverse ? 'inverse' : 'default'}>\n        <div ref={ref} role={role} className={cn(notificationVariants({ variant, layout }), className)} {...props}>\n          {lead}\n          <div className={cn('flex min-w-0 flex-1 gap-3', inverse ? 'flex-wrap items-center' : 'flex-col', inverse && onDismiss && 'pr-8')}>\n            {/* DR-WBDASH-042: room for the close button only when there is one. On the inverse surface the whole row (title and actions) keeps it, the actions wrap below a title that does not fit beside them instead of squeezing it to 0px */}\n            <div className={cn('flex min-w-0 flex-col gap-1', !inverse && onDismiss && 'pr-8')}>\n              <p className={cn('typography-ui-medium', inverse ? 'text-text-inverse' : 'text-text-default')}>{title}</p>\n              {description ? (\n                <p className={cn('typography-ui', inverse ? 'text-text-inverse-subtle' : 'text-text-subtle')}>{description}</p>\n              ) : null}\n            </div>\n            {media}\n            {progress !== undefined ? (\n              <div className=\"flex flex-col gap-1\">\n                <div\n                  role=\"progressbar\"\n                  aria-valuemin={0}\n                  aria-valuemax={100}\n                  aria-valuenow={progress}\n                  aria-label={typeof title === 'string' ? title : undefined}\n                  className=\"h-2 w-full overflow-hidden rounded-full bg-muted\"\n                >\n                  <div\n                    className=\"h-full rounded-full bg-background-brand-bold-default\"\n                    style={{ width: `${Math.min(100, Math.max(0, progress))}%` }}\n                  />\n                </div>\n                {progressLabel ? (\n                  <span className={cn('typography-ui self-end', inverse ? 'text-text-inverse-subtle' : 'text-text-subtle')}>\n                    {progressLabel}\n                  </span>\n                ) : null}\n              </div>\n            ) : null}\n            {actions ? (\n              <div\n                className={cn(\n                  'flex min-w-0 flex-wrap items-center gap-3',\n                  layout === 'mobile' && !inverse && 'flex-col items-stretch [&>*]:w-full',\n                )}\n              >\n                {actions}\n              </div>\n            ) : null}\n          </div>\n          {onDismiss ? (\n            <button\n              type=\"button\"\n              aria-label={dismissLabel}\n              onClick={onDismiss}\n              className={cn(\n                'absolute right-3 top-3 inline-flex h-6 w-6 items-center justify-center rounded-item transition-colors',\n                inverse\n                  ? 'text-text-inverse hover:bg-background-inverted'\n                  : 'text-icon-subtle hover:bg-muted hover:text-text-default',\n                ...focusRing,\n              )}\n            >\n              <X className=\"h-icon-sm w-icon-sm\" aria-hidden=\"true\" />\n            </button>\n          ) : null}\n        </div>\n      </NotificationToneContext.Provider>\n    );\n  },\n);\nNotification.displayName = 'Notification';\n\n// Text-style action for a Notification (Dismiss, Undo, Changelog).\nexport interface NotificationActionProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  // Defaults to the tone of the surrounding Notification.\n  tone?: 'default' | 'inverse';\n}\n\nconst NotificationAction = React.forwardRef<HTMLButtonElement, NotificationActionProps>(\n  ({ className, type = 'button', tone, ...props }, ref) => {\n    const inherited = React.useContext(NotificationToneContext);\n    const inverse = (tone ?? inherited) === 'inverse';\n    return (\n      <button\n        ref={ref}\n        type={type}\n        className={cn(\n          'typography-ui-medium inline-flex h-6 items-center rounded-item transition-colors',\n          inverse\n            ? 'text-text-inverse hover:underline'\n            : 'text-text-subtle hover:text-text-default last:text-text-default',\n          ...focusRing,\n          className,\n        )}\n        {...props}\n      />\n    );\n  },\n);\nNotificationAction.displayName = 'NotificationAction';\n\nexport { Notification, NotificationAction, notificationVariants };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}