{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"motion-action-bar","type":"registry:component","title":"Action Bar (Motion)","description":"ActionBar with motion: it rises in on a spring, settling with a hint of overshoot, and drops away quicker.","dependencies":["lucide-react","motion"],"registryDependencies":["https://dashral.com/r/utils.json","https://dashral.com/r/lib-locale.json","https://dashral.com/r/motion-reduced.json","https://dashral.com/r/motion-tokens.json","https://dashral.com/r/action-bar.json"],"files":[{"path":"registry/dashral/motion/action-bar.tsx","type":"registry:file","target":"components/dashral/motion/action-bar.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { motion } from \"motion/react\"\nimport { XIcon } from \"lucide-react\"\nimport type { ActionBarProps } from \"../action-bar\"\nimport { useLocale } from \"../lib/locale\"\nimport { cn } from \"../lib/utils\"\n\nimport { useReducedMotion } from \"../lib/motion-reduced\"\nimport { duration, ease, spring } from \"../lib/motion-tokens\"\n\nexport type { ActionBarProps } from \"../action-bar\"\n\n/**\n * The kit's ActionBar with motion: the same look and props. It rises in on the appear spring, settling with a hint of\n * overshoot, and drops away quicker. With reduced motion it only fades.\n */\nexport function ActionBar({\n  open,\n  count,\n  label,\n  actions,\n  onClear,\n  position = \"fixed\",\n  className,\n  classNames,\n  \"aria-label\": ariaLabel,\n  // Motion takes these itself; the bar's own handlers are kept.\n  onAnimationStart: _onAnimationStart,\n  onDrag: _onDrag,\n  onDragStart: _onDragStart,\n  onDragEnd: _onDragEnd,\n  ...props\n}: ActionBarProps) {\n  const { t } = useLocale()\n  const reduced = useReducedMotion()\n  // Keeps the last count while it drops away, so \"0 selected\" never shows on the way out.\n  const [shown, setShown] = React.useState(count)\n  if (open && count !== shown) setShown(count)\n  const text = label ?? (shown !== undefined ? t(\"selectedCount\", { count: shown }) : null)\n\n  return (\n    <motion.div\n      role=\"toolbar\"\n      data-slot=\"action-bar\"\n      data-state={open ? \"open\" : \"closed\"}\n      aria-label={ariaLabel ?? t(\"selectionActions\")}\n      aria-hidden={!open}\n      // While hidden it can't be tabbed into or clicked.\n      inert={!open}\n      onKeyDown={(event) => {\n        if (event.key === \"Escape\" && onClear) {\n          event.stopPropagation()\n          onClear()\n        }\n      }}\n      initial={false}\n      animate={open ? { y: 0, opacity: 1, visibility: \"visible\" } : { y: reduced ? 0 : 16, opacity: 0, transitionEnd: { visibility: \"hidden\" } }}\n      transition={\n        reduced\n          ? { duration: duration.fast }\n          : open\n            ? { ...spring.appear, opacity: { duration: duration.fast, ease: ease.enter } }\n            : { duration: duration.standard, ease: ease.exit }\n      }\n      className={cn(\n        \"flex items-center gap-2 rounded-xl border bg-popover p-1.5 ps-3 text-sm text-popover-foreground shadow-lg\",\n        position === \"fixed\" && \"fixed inset-x-4 bottom-4 z-40 mx-auto w-auto max-w-fit max-sm:max-w-none\",\n        className\n      )}\n      {...props}\n    >\n      {text !== null && (\n        <span role=\"status\" className={cn(\"min-w-0 shrink-0 font-medium tabular-nums whitespace-nowrap\", classNames?.label)}>\n          {text}\n        </span>\n      )}\n      <span aria-hidden className=\"mx-1 h-5 w-px shrink-0 bg-border\" />\n      <div className={cn(\"flex min-w-0 flex-1 items-center gap-1 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\", classNames?.actions)}>{actions}</div>\n      {onClear && (\n        <button\n          type=\"button\"\n          aria-label={t(\"clearSelection\")}\n          onClick={onClear}\n          className=\"grid size-8 shrink-0 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 [&_svg]:size-4\"\n        >\n          <XIcon aria-hidden />\n        </button>\n      )}\n    </motion.div>\n  )\n}\n"}]}