{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "motion-style",
  "title": "Motion Style",
  "description": "Switch the whole set between Calm, Springy, Snappy and Playful motion with one setting.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion",
    "@keyframery/segmented-control"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/motion-style.tsx",
      "content": "\"use client\"\n\n/* Keyframery's four motion styles, on top of `@ui-sdk/react/preferences`.\n\n   Every Keyframery duration is written as calc(Nms * var(--kf-speed, 1)) and every easing reads\n   --ease-house, --ease-spring or --ease-pop, so one `data-motion` attribute changes how the whole set\n   moves: calm (slower, no bounce), springy (the default), snappy (fast, crisp) and playful (more spring).\n\n   `motionStyle` is the preference: global (on <html>, so popups at the end of <body> follow it too)\n   and saved in localStorage. Mount `MotionStyle` once to apply it. `createMotionStyle({ global: false })`\n   makes a scoped one: its attribute goes on the MotionStyle element (display: contents) and only the\n   content inside follows it. */\n\nimport { createLocalStorage, createPreference } from \"@ui-sdk/core\"\nimport { Preferences } from \"@ui-sdk/react/preferences\"\nimport * as React from \"react\"\n\nexport * from \"@ui-sdk/react/preferences\"\n\nconst motionStyles = [\"calm\", \"springy\", \"snappy\", \"playful\"] as const\n\ntype MotionStyleValue = (typeof motionStyles)[number]\n\nfunction createMotionStyle({\n  global = true,\n  storageKey = \"kf-motion-style\",\n}: {\n  /** Put the attribute on <html> (default) or only on the MotionStyle element. */\n  global?: boolean\n  /** The localStorage key; null keeps the choice for this visit only. */\n  storageKey?: string | null\n} = {}) {\n  return createPreference({\n    values: motionStyles,\n    defaultValue: \"springy\",\n    attribute: \"data-motion\",\n    global,\n    storage: storageKey ? createLocalStorage(storageKey) : undefined,\n  })\n}\n\ntype MotionStylePreference = ReturnType<typeof createMotionStyle>\n\nconst motionStyle = createMotionStyle()\n\n/* The springy reset (a springy area inside a calm page) lives in the motion tokens, with the other styles. */\nfunction MotionStyle({\n  preference = motionStyle,\n  ...props\n}: Omit<React.ComponentProps<typeof Preferences>, \"preferences\"> & { preference?: MotionStylePreference }) {\n  return (\n    <Preferences preferences={[preference]} {...props} />\n  )\n}\n\nexport { createMotionStyle, MotionStyle, motionStyle, type MotionStylePreference, motionStyles, type MotionStyleValue }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/motion-style.tsx"
    },
    {
      "path": "registry/components/keyframery/motion-style.tsx",
      "content": "\"use client\"\n\n/* Styled motion style switcher: a segmented control whose key stretches between the four styles.\n   It mounts MotionStyle itself, so dropping it anywhere applies the choice to <html>. */\n\nimport * as React from \"react\"\n\nimport {\n  MotionStyle,\n  motionStyle,\n  type MotionStylePreference,\n  motionStyles,\n  type MotionStyleValue,\n  usePreference,\n} from \"@/components/keyframery/primitives/motion-style\"\nimport { SegmentedControl, SegmentedControlItem } from \"@/components/keyframery/segmented-control\"\n\nconst labels: Record<MotionStyleValue, string> = {\n  calm: \"Calm\",\n  springy: \"Springy\",\n  snappy: \"Snappy\",\n  playful: \"Playful\",\n}\n\nfunction MotionStyleSwitcher({\n  preference = motionStyle,\n  \"aria-label\": ariaLabel = \"Motion style\",\n  ...props\n}: Omit<React.ComponentProps<typeof SegmentedControl>, \"value\" | \"defaultValue\" | \"onValueChange\" | \"children\"> & {\n  preference?: MotionStylePreference\n}) {\n  const { value } = usePreference(preference)\n  return (\n    <MotionStyle preference={preference}>\n      <SegmentedControl\n        aria-label={ariaLabel}\n        value={value}\n        onValueChange={(next, details) => {\n          if (next) preference.set(next as MotionStyleValue, { reason: \"press\", event: details.event })\n        }}\n        {...props}\n      >\n        {motionStyles.map((style) => (\n          <SegmentedControlItem key={style} value={style}>\n            {labels[style]}\n          </SegmentedControlItem>\n        ))}\n      </SegmentedControl>\n    </MotionStyle>\n  )\n}\n\nexport { createMotionStyle, MotionStyle, motionStyle, motionStyles, type MotionStyleValue } from \"@/components/keyframery/primitives/motion-style\"\nexport { MotionStyleSwitcher }\n",
      "type": "registry:component",
      "target": "components/keyframery/motion-style.tsx"
    }
  ],
  "type": "registry:component"
}