{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "scroll-fade",
  "title": "Scroll Fade",
  "description": "Fades a scroller's edges while there's more content past them.",
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "registryDependencies": [
    "https://constella.aayush.cv/r/base.json"
  ],
  "files": [
    {
      "path": "src/lib/constella/scroll-fade.stylex.ts",
      "content": "import * as stylex from \"@stylexjs/stylex\";\n\n// How deep each edge fades. Typed, so a scroll timeline can animate them.\nexport const scrollFadeVars = stylex.defineVars({\n  end: stylex.types.lengthPercentage(\"0px\"),\n  // How far short of the end `xEndAround`'s fade finishes, clearing what floats over that end.\n  endInset: stylex.types.lengthPercentage(\"0px\"),\n  start: stylex.types.lengthPercentage(\"0px\"),\n});\n",
      "type": "registry:lib"
    },
    {
      "path": "src/lib/constella/scroll-fade.ts",
      "content": "import * as stylex from \"@stylexjs/stylex\";\n\nimport { scrollFadeVars as fade } from \"@/lib/constella/scroll-fade.stylex\";\nimport { space } from \"@/lib/constella/tokens.stylex\";\n\nconst timeline = \"@supports (animation-timeline: scroll())\";\nconst noTimeline = \"@supports not (animation-timeline: scroll())\";\nconst rtl = \":is([dir='rtl'], [dir='rtl'] *)\";\nconst timelineAround = \"@supports (timeline-scope: none)\";\nconst noTimelineAround = \"@supports not (timeline-scope: none)\";\nconst timelineName = \"--scroll-fade\";\n\nconst depth = `min(12%, ${space.xl})`;\n// How far from an edge the content must be before that edge fades in full.\nconst reveal = `calc(2 * ${space.xl})`;\nconst ranges = `0 ${reveal}, calc(100% - ${reveal}) 100%`;\n\nconst fadeInStart = stylex.keyframes({\n  from: { [fade.start]: \"0px\" },\n  to: { [fade.start]: depth },\n});\nconst fadeOutEnd = stylex.keyframes({\n  from: { [fade.end]: depth },\n  to: { [fade.end]: \"0px\" },\n});\n\nconst stops = `transparent, #000 ${fade.start}, #000 calc(100% - ${fade.end}), transparent`;\n\nconst endStops = `#000 calc(100% - ${fade.endInset} - ${fade.end}), transparent calc(100% - ${fade.endInset})`;\n\n/** Fades a scroller's edges while there's more content past them. Pass to the element that scrolls. */\nconst scrollFade = stylex.create({\n  x: {\n    [fade.start]: { default: null, [noTimeline]: depth },\n    [fade.end]: { default: null, [noTimeline]: depth },\n    animationDuration: \"1ms\",\n    animationFillMode: \"both\",\n    animationName: {\n      default: null,\n      [timeline]: `${fadeInStart}, ${fadeOutEnd}`,\n    },\n    animationRange: ranges,\n    animationTimeline: \"scroll(self inline), scroll(self inline)\",\n    animationTimingFunction: \"linear\",\n    maskImage: {\n      default: `linear-gradient(to right, ${stops})`,\n      [rtl]: `linear-gradient(to left, ${stops})`,\n    },\n  },\n  /** Names the scroller's position, for `xEndAround` on an ancestor. */\n  source: {\n    scrollTimelineAxis: \"inline\",\n    scrollTimelineName: timelineName,\n  },\n  /** Fades only the right end, drawn by an ancestor of a left-to-right `source` scroller, so what the ancestor places beside the scroller (a code block's line numbers) stays unmasked. */\n  xEndAround: {\n    [fade.end]: { default: null, [noTimelineAround]: depth },\n    animationDuration: \"1ms\",\n    animationFillMode: \"both\",\n    animationName: { default: null, [timelineAround]: fadeOutEnd },\n    animationRange: `calc(100% - ${reveal}) 100%`,\n    animationTimeline: timelineName,\n    animationTimingFunction: \"linear\",\n    maskImage: `linear-gradient(to right, ${endStops})`,\n    timelineScope: timelineName,\n  },\n  y: {\n    [fade.start]: { default: null, [noTimeline]: depth },\n    [fade.end]: { default: null, [noTimeline]: depth },\n    animationDuration: \"1ms\",\n    animationFillMode: \"both\",\n    animationName: {\n      default: null,\n      [timeline]: `${fadeInStart}, ${fadeOutEnd}`,\n    },\n    animationRange: ranges,\n    animationTimeline: \"scroll(self block), scroll(self block)\",\n    animationTimingFunction: \"linear\",\n    maskImage: `linear-gradient(to bottom, ${stops})`,\n  },\n});\n\nexport { scrollFade };\n",
      "type": "registry:lib"
    }
  ],
  "docs": "Usage: https://constella.aayush.cv/docs/components/scroll-fade/index.md",
  "type": "registry:lib"
}