bits-lab 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -2
  3. package/dist/Accordion.d.ts +52 -0
  4. package/dist/Accordion.js +192 -0
  5. package/dist/AchievementToast.d.ts +36 -0
  6. package/dist/AchievementToast.js +162 -0
  7. package/dist/AgentCard.d.ts +41 -0
  8. package/dist/AgentCard.js +168 -0
  9. package/dist/ArcadeButtons.d.ts +23 -0
  10. package/dist/ArcadeButtons.js +169 -0
  11. package/dist/AuroraBands.d.ts +19 -0
  12. package/dist/AuroraBands.js +126 -0
  13. package/dist/AvatarTooltips.d.ts +32 -0
  14. package/dist/AvatarTooltips.js +121 -0
  15. package/dist/BarRace.d.ts +39 -0
  16. package/dist/BarRace.js +227 -0
  17. package/dist/BentoGrid.d.ts +50 -0
  18. package/dist/BentoGrid.js +145 -0
  19. package/dist/BootSequence.d.ts +48 -0
  20. package/dist/BootSequence.js +234 -0
  21. package/dist/BreadcrumbTrail.d.ts +31 -0
  22. package/dist/BreadcrumbTrail.js +181 -0
  23. package/dist/CRTPower.d.ts +30 -0
  24. package/dist/CRTPower.js +142 -0
  25. package/dist/CardDeck.d.ts +29 -0
  26. package/dist/CardDeck.js +154 -0
  27. package/dist/ChangelogTimeline.d.ts +35 -0
  28. package/dist/ChangelogTimeline.js +137 -0
  29. package/dist/ChapterProgress.d.ts +23 -0
  30. package/dist/ChapterProgress.js +211 -0
  31. package/dist/ChatBubbles.d.ts +42 -0
  32. package/dist/ChatBubbles.js +198 -0
  33. package/dist/ChiptuneKit.d.ts +158 -0
  34. package/dist/ChiptuneKit.js +207 -0
  35. package/dist/CipherCard.d.ts +22 -0
  36. package/dist/CipherCard.js +91 -0
  37. package/dist/CloudSky.d.ts +28 -0
  38. package/dist/CloudSky.js +222 -0
  39. package/dist/CodeRain.d.ts +24 -0
  40. package/dist/CodeRain.js +158 -0
  41. package/dist/CodeShowcase.d.ts +50 -0
  42. package/dist/CodeShowcase.js +307 -0
  43. package/dist/ColorDial.d.ts +42 -0
  44. package/dist/ColorDial.js +288 -0
  45. package/dist/CommandPalette.d.ts +59 -0
  46. package/dist/CommandPalette.js +349 -0
  47. package/dist/CompareSlider.d.ts +33 -0
  48. package/dist/CompareSlider.js +152 -0
  49. package/dist/Confetti.d.ts +61 -0
  50. package/dist/Confetti.js +176 -0
  51. package/dist/ConnectBeams.d.ts +39 -0
  52. package/dist/ConnectBeams.js +132 -0
  53. package/dist/ContextOrb.d.ts +34 -0
  54. package/dist/ContextOrb.js +269 -0
  55. package/dist/ContourLines.d.ts +20 -0
  56. package/dist/ContourLines.js +159 -0
  57. package/dist/Coverflow.d.ts +27 -0
  58. package/dist/Coverflow.js +167 -0
  59. package/dist/CursorAttractor.d.ts +21 -0
  60. package/dist/CursorAttractor.js +136 -0
  61. package/dist/CutReveal.d.ts +21 -0
  62. package/dist/CutReveal.js +116 -0
  63. package/dist/DateRange.d.ts +45 -0
  64. package/dist/DateRange.js +327 -0
  65. package/dist/DeviceFrame.d.ts +30 -0
  66. package/dist/DeviceFrame.js +145 -0
  67. package/dist/DiffReveal.d.ts +36 -0
  68. package/dist/DiffReveal.js +247 -0
  69. package/dist/DirectionHover.d.ts +15 -0
  70. package/dist/DirectionHover.js +90 -0
  71. package/dist/Discard.d.ts +18 -0
  72. package/dist/Discard.js +61 -0
  73. package/dist/DitherField.d.ts +15 -0
  74. package/dist/DitherField.js +157 -0
  75. package/dist/DotGlobe.d.ts +48 -0
  76. package/dist/DotGlobe.js +312 -0
  77. package/dist/DotMap.d.ts +47 -0
  78. package/dist/DotMap.js +172 -0
  79. package/dist/DropZone.d.ts +57 -0
  80. package/dist/DropZone.js +304 -0
  81. package/dist/DynamicIsland.d.ts +32 -0
  82. package/dist/DynamicIsland.js +92 -0
  83. package/dist/EdgeFX.d.ts +27 -0
  84. package/dist/EdgeFX.js +98 -0
  85. package/dist/ElasticString.d.ts +22 -0
  86. package/dist/ElasticString.js +127 -0
  87. package/dist/ExpandCard.d.ts +44 -0
  88. package/dist/ExpandCard.js +182 -0
  89. package/dist/FeatureTabs.d.ts +34 -0
  90. package/dist/FeatureTabs.js +169 -0
  91. package/dist/FeedList.d.ts +37 -0
  92. package/dist/FeedList.js +163 -0
  93. package/dist/FlickerGrid.d.ts +29 -0
  94. package/dist/FlickerGrid.js +156 -0
  95. package/dist/FocusGrid.d.ts +20 -0
  96. package/dist/FocusGrid.js +48 -0
  97. package/dist/FocusPull.d.ts +26 -0
  98. package/dist/FocusPull.js +106 -0
  99. package/dist/Footprints.d.ts +24 -0
  100. package/dist/Footprints.js +126 -0
  101. package/dist/FunnelFlow.d.ts +34 -0
  102. package/dist/FunnelFlow.js +267 -0
  103. package/dist/GameOver.d.ts +46 -0
  104. package/dist/GameOver.js +191 -0
  105. package/dist/GaugeMeter.d.ts +38 -0
  106. package/dist/GaugeMeter.js +195 -0
  107. package/dist/GlassPanel.d.ts +27 -0
  108. package/dist/GlassPanel.js +80 -0
  109. package/dist/GrainFX.d.ts +34 -0
  110. package/dist/GrainFX.js +122 -0
  111. package/dist/GravityBox.d.ts +30 -0
  112. package/dist/GravityBox.js +220 -0
  113. package/dist/HealthBar.d.ts +33 -0
  114. package/dist/HealthBar.js +140 -0
  115. package/dist/Heatmap.d.ts +42 -0
  116. package/dist/Heatmap.js +232 -0
  117. package/dist/HexField.d.ts +29 -0
  118. package/dist/HexField.js +188 -0
  119. package/dist/HoldToConfirm.d.ts +29 -0
  120. package/dist/HoldToConfirm.js +163 -0
  121. package/dist/HorizontalTrack.d.ts +28 -0
  122. package/dist/HorizontalTrack.js +195 -0
  123. package/dist/HotbarDock.d.ts +40 -0
  124. package/dist/HotbarDock.js +148 -0
  125. package/dist/InkText.d.ts +27 -0
  126. package/dist/InkText.js +65 -0
  127. package/dist/InlineEdit.d.ts +30 -0
  128. package/dist/InlineEdit.js +198 -0
  129. package/dist/InteractiveGrid.d.ts +25 -0
  130. package/dist/InteractiveGrid.js +194 -0
  131. package/dist/InventoryGrid.d.ts +45 -0
  132. package/dist/InventoryGrid.js +272 -0
  133. package/dist/JellyBlob.d.ts +30 -0
  134. package/dist/JellyBlob.js +209 -0
  135. package/dist/KineticHeadline.d.ts +30 -0
  136. package/dist/KineticHeadline.js +133 -0
  137. package/dist/LavaLamp.d.ts +21 -0
  138. package/dist/LavaLamp.js +133 -0
  139. package/dist/LetterSwap.d.ts +20 -0
  140. package/dist/LetterSwap.js +78 -0
  141. package/dist/LevelMap.d.ts +35 -0
  142. package/dist/LevelMap.js +189 -0
  143. package/dist/LightShafts.d.ts +22 -0
  144. package/dist/LightShafts.js +170 -0
  145. package/dist/LightboxGallery.d.ts +26 -0
  146. package/dist/LightboxGallery.js +327 -0
  147. package/dist/LinkPeek.d.ts +36 -0
  148. package/dist/LinkPeek.js +194 -0
  149. package/dist/LogoOrbit.d.ts +37 -0
  150. package/dist/LogoOrbit.js +117 -0
  151. package/dist/Marquee.d.ts +33 -0
  152. package/dist/Marquee.js +148 -0
  153. package/dist/MarqueeLine.d.ts +33 -0
  154. package/dist/MarqueeLine.js +167 -0
  155. package/dist/MasonryWall.d.ts +13 -0
  156. package/dist/MasonryWall.js +90 -0
  157. package/dist/MegaMenu.d.ts +32 -0
  158. package/dist/MegaMenu.js +280 -0
  159. package/dist/MeteorShower.d.ts +24 -0
  160. package/dist/MeteorShower.js +155 -0
  161. package/dist/Minimap.d.ts +21 -0
  162. package/dist/Minimap.js +236 -0
  163. package/dist/MobileTabBar.d.ts +38 -0
  164. package/dist/MobileTabBar.js +148 -0
  165. package/dist/MorphDialog.d.ts +34 -0
  166. package/dist/MorphDialog.js +199 -0
  167. package/dist/MorphPopover.d.ts +33 -0
  168. package/dist/MorphPopover.js +168 -0
  169. package/dist/MorphWords.d.ts +18 -0
  170. package/dist/MorphWords.js +136 -0
  171. package/dist/OTPInput.d.ts +43 -0
  172. package/dist/OTPInput.js +174 -0
  173. package/dist/OverlayKit.d.ts +97 -0
  174. package/dist/OverlayKit.js +466 -0
  175. package/dist/OverlayMenu.d.ts +32 -0
  176. package/dist/OverlayMenu.js +154 -0
  177. package/dist/ParallaxCollage.d.ts +41 -0
  178. package/dist/ParallaxCollage.js +143 -0
  179. package/dist/PasswordMeter.d.ts +44 -0
  180. package/dist/PasswordMeter.js +165 -0
  181. package/dist/PegBoard.d.ts +26 -0
  182. package/dist/PegBoard.js +184 -0
  183. package/dist/PinCard.d.ts +21 -0
  184. package/dist/PinCard.js +84 -0
  185. package/dist/PixelAvatar.d.ts +33 -0
  186. package/dist/PixelAvatar.js +144 -0
  187. package/dist/PixelButton.d.ts +20 -0
  188. package/dist/PixelButton.js +128 -0
  189. package/dist/PixelExplode.d.ts +31 -0
  190. package/dist/PixelExplode.js +164 -0
  191. package/dist/PixelLoader.d.ts +32 -0
  192. package/dist/PixelLoader.js +142 -0
  193. package/dist/PixelParallax.d.ts +41 -0
  194. package/dist/PixelParallax.js +151 -0
  195. package/dist/PixelSpinners.d.ts +21 -0
  196. package/dist/PixelSpinners.js +110 -0
  197. package/dist/PixelType.d.ts +26 -0
  198. package/dist/PixelType.js +220 -0
  199. package/dist/PointerKit.d.ts +23 -0
  200. package/dist/PointerKit.js +222 -0
  201. package/dist/Polaroids.d.ts +41 -0
  202. package/dist/Polaroids.js +293 -0
  203. package/dist/PressStart.d.ts +28 -0
  204. package/dist/PressStart.js +99 -0
  205. package/dist/PricingFlip.d.ts +52 -0
  206. package/dist/PricingFlip.js +190 -0
  207. package/dist/ProximityType.d.ts +26 -0
  208. package/dist/ProximityType.js +135 -0
  209. package/dist/QuestDialog.d.ts +50 -0
  210. package/dist/QuestDialog.js +204 -0
  211. package/dist/QuestLog.d.ts +39 -0
  212. package/dist/QuestLog.js +214 -0
  213. package/dist/RangeDual.d.ts +34 -0
  214. package/dist/RangeDual.js +238 -0
  215. package/dist/RatingPips.d.ts +25 -0
  216. package/dist/RatingPips.js +129 -0
  217. package/dist/RetroHorizon.d.ts +27 -0
  218. package/dist/RetroHorizon.js +169 -0
  219. package/dist/Reveal.d.ts +30 -0
  220. package/dist/Reveal.js +92 -0
  221. package/dist/RingProgress.d.ts +45 -0
  222. package/dist/RingProgress.js +180 -0
  223. package/dist/RollingNumber.d.ts +28 -0
  224. package/dist/RollingNumber.js +108 -0
  225. package/dist/ScanScope.d.ts +24 -0
  226. package/dist/ScanScope.js +164 -0
  227. package/dist/ScoreTicker.d.ts +32 -0
  228. package/dist/ScoreTicker.js +176 -0
  229. package/dist/ScreenScroller.d.ts +24 -0
  230. package/dist/ScreenScroller.js +138 -0
  231. package/dist/Screensaver.d.ts +31 -0
  232. package/dist/Screensaver.js +221 -0
  233. package/dist/ScrollTilt.d.ts +27 -0
  234. package/dist/ScrollTilt.js +100 -0
  235. package/dist/ScrollTypography.d.ts +26 -0
  236. package/dist/ScrollTypography.js +124 -0
  237. package/dist/ScrollZoom.d.ts +31 -0
  238. package/dist/ScrollZoom.js +123 -0
  239. package/dist/ScrubNumber.d.ts +29 -0
  240. package/dist/ScrubNumber.js +152 -0
  241. package/dist/ShadowStack.d.ts +28 -0
  242. package/dist/ShadowStack.js +116 -0
  243. package/dist/SideRail.d.ts +43 -0
  244. package/dist/SideRail.js +253 -0
  245. package/dist/SignalText.d.ts +25 -0
  246. package/dist/SignalText.js +178 -0
  247. package/dist/SkeletonShimmer.d.ts +18 -0
  248. package/dist/SkeletonShimmer.js +111 -0
  249. package/dist/SketchHighlight.d.ts +27 -0
  250. package/dist/SketchHighlight.js +180 -0
  251. package/dist/SlideTabs.d.ts +40 -0
  252. package/dist/SlideTabs.js +190 -0
  253. package/dist/SmartNavbar.d.ts +48 -0
  254. package/dist/SmartNavbar.js +188 -0
  255. package/dist/SparkChart.d.ts +41 -0
  256. package/dist/SparkChart.js +188 -0
  257. package/dist/Spoiler.d.ts +22 -0
  258. package/dist/Spoiler.js +97 -0
  259. package/dist/SpotlightTour.d.ts +38 -0
  260. package/dist/SpotlightTour.js +231 -0
  261. package/dist/SpringDrawer.d.ts +39 -0
  262. package/dist/SpringDrawer.js +360 -0
  263. package/dist/SpriteAnimator.d.ts +41 -0
  264. package/dist/SpriteAnimator.js +124 -0
  265. package/dist/StatCard.d.ts +43 -0
  266. package/dist/StatCard.js +168 -0
  267. package/dist/StepLoader.d.ts +41 -0
  268. package/dist/StepLoader.js +191 -0
  269. package/dist/StepperForm.d.ts +41 -0
  270. package/dist/StepperForm.js +206 -0
  271. package/dist/StickerBoard.d.ts +39 -0
  272. package/dist/StickerBoard.js +209 -0
  273. package/dist/StickyReveal.d.ts +42 -0
  274. package/dist/StickyReveal.js +181 -0
  275. package/dist/StoryViewer.d.ts +36 -0
  276. package/dist/StoryViewer.js +175 -0
  277. package/dist/StreamingText.d.ts +29 -0
  278. package/dist/StreamingText.js +271 -0
  279. package/dist/SuggestionChips.d.ts +32 -0
  280. package/dist/SuggestionChips.js +96 -0
  281. package/dist/SwipeActions.d.ts +30 -0
  282. package/dist/SwipeActions.js +141 -0
  283. package/dist/TagInput.d.ts +30 -0
  284. package/dist/TagInput.js +284 -0
  285. package/dist/TallyUp.d.ts +38 -0
  286. package/dist/TallyUp.js +157 -0
  287. package/dist/TerminalDemo.d.ts +63 -0
  288. package/dist/TerminalDemo.js +214 -0
  289. package/dist/TestimonialWall.d.ts +35 -0
  290. package/dist/TestimonialWall.js +131 -0
  291. package/dist/TextOnPath.d.ts +36 -0
  292. package/dist/TextOnPath.js +130 -0
  293. package/dist/ThinkingShimmer.d.ts +36 -0
  294. package/dist/ThinkingShimmer.js +132 -0
  295. package/dist/ToastStack.d.ts +62 -0
  296. package/dist/ToastStack.js +289 -0
  297. package/dist/ToggleGroup.d.ts +39 -0
  298. package/dist/ToggleGroup.js +190 -0
  299. package/dist/ToggleKit.d.ts +70 -0
  300. package/dist/ToggleKit.js +229 -0
  301. package/dist/TracingLine.d.ts +24 -0
  302. package/dist/TracingLine.js +139 -0
  303. package/dist/TradingCard.d.ts +30 -0
  304. package/dist/TradingCard.js +147 -0
  305. package/dist/VanishInput.d.ts +34 -0
  306. package/dist/VanishInput.js +190 -0
  307. package/dist/VideoHero.d.ts +32 -0
  308. package/dist/VideoHero.js +207 -0
  309. package/dist/VoiceOrb.d.ts +23 -0
  310. package/dist/VoiceOrb.js +182 -0
  311. package/dist/VoxelTiles.d.ts +38 -0
  312. package/dist/VoxelTiles.js +201 -0
  313. package/dist/WarpField.d.ts +18 -0
  314. package/dist/WarpField.js +160 -0
  315. package/dist/WebcamPixels.d.ts +38 -0
  316. package/dist/WebcamPixels.js +292 -0
  317. package/dist/WheelPicker.d.ts +29 -0
  318. package/dist/WheelPicker.js +199 -0
  319. package/dist/WobbleCard.d.ts +23 -0
  320. package/dist/WobbleCard.js +112 -0
  321. package/dist/index.d.ts +158 -0
  322. package/dist/index.js +159 -0
  323. package/package.json +34 -4
@@ -0,0 +1,127 @@
1
+ 'use client';
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ function ElasticString({
5
+ strings = 1,
6
+ height = 200,
7
+ gap,
8
+ thickness = 3,
9
+ colors = ["#73eff7"],
10
+ grab = 26,
11
+ maxPull = 70,
12
+ stiffness = 420,
13
+ damping = 7,
14
+ onPluck,
15
+ className = "",
16
+ style
17
+ }) {
18
+ const svgRef = useRef(null);
19
+ const pathRefs = useRef([]);
20
+ const pluckRef = useRef(onPluck);
21
+ pluckRef.current = onPluck;
22
+ useEffect(() => {
23
+ const svg = svgRef.current;
24
+ const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
25
+ const spacing = gap ?? height / (strings + 1);
26
+ const restY = (i) => gap ? (height - gap * (strings - 1)) / 2 + i * gap : spacing * (i + 1);
27
+ const state = Array.from({ length: strings }, () => ({ x: 0.5, dy: 0, v: 0, held: false }));
28
+ let width = svg.clientWidth || 1;
29
+ let frame = 0;
30
+ let last = 0;
31
+ const draw = (i) => {
32
+ const s = state[i];
33
+ const y = restY(i);
34
+ const cx = s.x * width;
35
+ pathRefs.current[i]?.setAttribute("d", `M0 ${y} Q ${cx.toFixed(1)} ${(y + s.dy * 2).toFixed(1)} ${width} ${y}`);
36
+ };
37
+ const tick = (now) => {
38
+ const dt = Math.min(0.05, (now - last) / 1e3 || 0.016);
39
+ last = now;
40
+ let moving = false;
41
+ state.forEach((s, i) => {
42
+ if (s.held) return;
43
+ if (reduced) s.dy = 0;
44
+ else {
45
+ const k = stiffness * (1 + i * 0.18);
46
+ for (let t = 0; t < dt; t += 1 / 240) {
47
+ s.v += (-k * s.dy - damping * s.v) / 240;
48
+ s.dy += s.v / 240;
49
+ }
50
+ }
51
+ if (Math.abs(s.dy) > 0.05 || Math.abs(s.v) > 0.5) moving = true;
52
+ else {
53
+ s.dy = 0;
54
+ s.v = 0;
55
+ }
56
+ draw(i);
57
+ });
58
+ frame = moving ? requestAnimationFrame(tick) : 0;
59
+ };
60
+ const wake = () => {
61
+ if (!frame) {
62
+ last = performance.now();
63
+ frame = requestAnimationFrame(tick);
64
+ }
65
+ };
66
+ const release = (i, s) => {
67
+ s.held = false;
68
+ pluckRef.current?.(i, Math.min(1, Math.abs(s.dy) / maxPull));
69
+ wake();
70
+ };
71
+ const onMove = (event) => {
72
+ const rect = svg.getBoundingClientRect();
73
+ const px = event.clientX - rect.left;
74
+ const py = event.clientY - rect.top;
75
+ state.forEach((s, i) => {
76
+ const offset = py - restY(i);
77
+ if (s.held) {
78
+ if (Math.abs(offset) > maxPull || px < 0 || px > width) release(i, s);
79
+ else {
80
+ s.x = Math.max(0.05, Math.min(0.95, px / width));
81
+ s.dy = offset;
82
+ draw(i);
83
+ }
84
+ } else if (Math.abs(offset) < grab && Math.abs(s.dy) < 4) {
85
+ s.held = true;
86
+ s.v = 0;
87
+ s.x = Math.max(0.05, Math.min(0.95, px / width));
88
+ s.dy = offset;
89
+ draw(i);
90
+ }
91
+ });
92
+ };
93
+ const onLeave = () => state.forEach((s, i) => s.held && release(i, s));
94
+ const resize = new ResizeObserver(() => {
95
+ width = svg.clientWidth || 1;
96
+ state.forEach((_, i) => draw(i));
97
+ });
98
+ resize.observe(svg);
99
+ svg.addEventListener("pointermove", onMove);
100
+ svg.addEventListener("pointerleave", onLeave);
101
+ svg.addEventListener("pointercancel", onLeave);
102
+ state.forEach((_, i) => draw(i));
103
+ return () => {
104
+ cancelAnimationFrame(frame);
105
+ resize.disconnect();
106
+ svg.removeEventListener("pointermove", onMove);
107
+ svg.removeEventListener("pointerleave", onLeave);
108
+ svg.removeEventListener("pointercancel", onLeave);
109
+ };
110
+ }, [strings, height, gap, grab, maxPull, stiffness, damping]);
111
+ return /* @__PURE__ */ jsx("svg", { ref: svgRef, className, width: "100%", height, "aria-hidden": "true", style: { display: "block", touchAction: "pan-y", overflow: "visible", ...style }, children: Array.from({ length: strings }, (_, i) => /* @__PURE__ */ jsx(
112
+ "path",
113
+ {
114
+ ref: (node) => {
115
+ pathRefs.current[i] = node;
116
+ },
117
+ fill: "none",
118
+ stroke: colors[i % colors.length],
119
+ strokeWidth: Math.max(1, thickness - i * 0.3),
120
+ strokeLinecap: "round"
121
+ },
122
+ i
123
+ )) });
124
+ }
125
+ export {
126
+ ElasticString as default
127
+ };
@@ -0,0 +1,44 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ export interface ExpandCardProps {
3
+ /** Stable identity inside a grid (defaults to its position). */
4
+ id?: string;
5
+ /** Image or video at the top; it grows taller when open. */
6
+ media?: ReactNode;
7
+ eyebrow?: ReactNode;
8
+ title: ReactNode;
9
+ summary?: ReactNode;
10
+ /** The article, revealed in the page flow when open. */
11
+ children?: ReactNode;
12
+ /** Controlled open state when used outside a grid. */
13
+ open?: boolean;
14
+ onOpenChange?: (open: boolean) => void;
15
+ className?: string;
16
+ style?: CSSProperties;
17
+ }
18
+ export declare function ExpandCard({ id, media, eyebrow, title, summary, children, open: controlledOpen, onOpenChange, className, style }: ExpandCardProps): import("react").JSX.Element;
19
+ export interface ExpandCardGridProps {
20
+ /** ExpandCard elements. */
21
+ children?: ReactNode;
22
+ /** id of the card that starts open. */
23
+ defaultOpen?: string | null;
24
+ onOpenChange?: (id: string | null) => void;
25
+ /** Minimum card width before the grid wraps, in px. */
26
+ minWidth?: number;
27
+ gap?: number;
28
+ radius?: number;
29
+ mediaHeight?: number;
30
+ openMediaHeight?: number;
31
+ titleSize?: number;
32
+ /** Motion length, in ms. */
33
+ duration?: number;
34
+ backgroundColor?: string;
35
+ textColor?: string;
36
+ mutedColor?: string;
37
+ lineColor?: string;
38
+ accentColor?: string;
39
+ fontFamily?: string;
40
+ className?: string;
41
+ style?: CSSProperties;
42
+ }
43
+ export declare function ExpandCardGrid({ children, defaultOpen, onOpenChange, minWidth, gap, radius, mediaHeight, openMediaHeight, titleSize, duration, backgroundColor, textColor, mutedColor, lineColor, accentColor, fontFamily, className, style }: ExpandCardGridProps): import("react").JSX.Element;
44
+ export default ExpandCardGrid;
@@ -0,0 +1,182 @@
1
+ 'use client';
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { Children, cloneElement, createContext, isValidElement, useContext, useId, useInsertionEffect, useLayoutEffect, useRef, useState } from "react";
4
+ const STYLE_ID = "bl-expand-card";
5
+ const CSS = `
6
+ .bl-xgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(var(--bl-min), 100%), 1fr)); gap: var(--bl-gap); font-family: var(--bl-font); color: var(--bl-ink); }
7
+ .bl-xcard { position: relative; display: flex; flex-direction: column; min-width: 0; overflow: hidden; border-radius: var(--bl-radius); background: var(--bl-bg); box-shadow: inset 0 0 0 1px var(--bl-line); }
8
+ .bl-xcard[data-open] { grid-column: 1 / -1; box-shadow: inset 0 0 0 1px var(--bl-line), 0 24px 50px -30px rgba(0,0,0,0.7); }
9
+ .bl-xcard__trigger { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
10
+ .bl-xcard__trigger:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: -2px; border-radius: var(--bl-radius); }
11
+ .bl-xcard[data-open] .bl-xcard__trigger { cursor: default; }
12
+ .bl-xcard__media { overflow: hidden; height: var(--bl-media); transition: height var(--bl-dur) cubic-bezier(.2,.9,.25,1); }
13
+ .bl-xcard[data-open] .bl-xcard__media { height: var(--bl-media-open); }
14
+ .bl-xcard__media > img, .bl-xcard__media > video { display: block; width: 100%; height: 100%; object-fit: cover; }
15
+ .bl-xcard__head { padding: 16px 18px 18px; }
16
+ .bl-xcard__eyebrow { margin: 0 0 6px; color: var(--bl-accent); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }
17
+ .bl-xcard__title { margin: 0; font-size: var(--bl-title); font-weight: 700; line-height: 1.25; transition: font-size var(--bl-dur) cubic-bezier(.2,.9,.25,1); }
18
+ .bl-xcard[data-open] .bl-xcard__title { font-size: calc(var(--bl-title) * 1.45); }
19
+ .bl-xcard__summary { margin: 8px 0 0; color: var(--bl-muted); font-size: 14px; line-height: 1.55; }
20
+ .bl-xcard__body { padding: 0 18px 22px; color: var(--bl-ink); line-height: 1.7; animation: bl-xcard-in calc(var(--bl-dur) * 1.2) cubic-bezier(.2,.9,.25,1) both; animation-delay: calc(var(--bl-dur) * 0.35); }
21
+ .bl-xcard__body > :first-child { margin-top: 0; }
22
+ .bl-xcard__close { position: absolute; top: 12px; right: 12px; z-index: 2; display: grid; place-items: center; width: 34px; height: 34px; border: 0; border-radius: 50%; background: rgba(0,0,0,0.55); color: #fff; cursor: pointer; animation: bl-xcard-in 300ms ease both; }
23
+ .bl-xcard__close:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 2px; }
24
+ @keyframes bl-xcard-in { from { opacity: 0; transform: translateY(10px); } }
25
+ @media (prefers-reduced-motion: reduce) { .bl-xcard__media, .bl-xcard__title { transition: none; } .bl-xcard__body, .bl-xcard__close { animation: none; } }
26
+ `;
27
+ function useStyles() {
28
+ useInsertionEffect(() => {
29
+ if (typeof document === "undefined") return;
30
+ const style = document.getElementById(STYLE_ID) ?? Object.assign(document.createElement("style"), { id: STYLE_ID });
31
+ style.textContent = CSS;
32
+ if (!style.isConnected) document.head.appendChild(style);
33
+ }, []);
34
+ }
35
+ const GridContext = createContext(null);
36
+ function ExpandCard({ id, media, eyebrow, title, summary, children, open: controlledOpen, onOpenChange, className = "", style }) {
37
+ const grid = useContext(GridContext);
38
+ const uid = useId().replace(/[^a-zA-Z0-9_-]/g, "");
39
+ const key = id ?? uid;
40
+ const [innerOpen, setInnerOpen] = useState(false);
41
+ const open = grid ? grid.openId === key : controlledOpen ?? innerOpen;
42
+ const triggerRef = useRef(null);
43
+ const setOpen = (next) => {
44
+ if (grid) grid.toggle(next ? key : null);
45
+ else {
46
+ if (controlledOpen === void 0) setInnerOpen(next);
47
+ onOpenChange?.(next);
48
+ }
49
+ if (!next) setTimeout(() => triggerRef.current?.focus({ preventScroll: true }));
50
+ };
51
+ return /* @__PURE__ */ jsxs(
52
+ "article",
53
+ {
54
+ className: `bl-xcard ${className}`,
55
+ "data-open": open || void 0,
56
+ "data-expand-key": key,
57
+ style,
58
+ onKeyDown: (event) => {
59
+ if (open && event.key === "Escape") {
60
+ event.stopPropagation();
61
+ setOpen(false);
62
+ }
63
+ },
64
+ children: [
65
+ /* @__PURE__ */ jsxs(
66
+ "button",
67
+ {
68
+ ref: triggerRef,
69
+ type: "button",
70
+ className: "bl-xcard__trigger",
71
+ "aria-expanded": open,
72
+ "aria-controls": `${uid}-body`,
73
+ onClick: () => !open && setOpen(true),
74
+ children: [
75
+ media && /* @__PURE__ */ jsx("div", { className: "bl-xcard__media", "aria-hidden": "true", children: media }),
76
+ /* @__PURE__ */ jsxs("div", { className: "bl-xcard__head", children: [
77
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "bl-xcard__eyebrow", children: eyebrow }),
78
+ /* @__PURE__ */ jsx("h3", { className: "bl-xcard__title", children: title }),
79
+ summary && /* @__PURE__ */ jsx("p", { className: "bl-xcard__summary", children: summary })
80
+ ] })
81
+ ]
82
+ }
83
+ ),
84
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
85
+ /* @__PURE__ */ jsx("button", { type: "button", className: "bl-xcard__close", "aria-label": "Close article", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M2 2l10 10M12 2 2 12" }) }) }),
86
+ /* @__PURE__ */ jsx("div", { id: `${uid}-body`, className: "bl-xcard__body", role: "region", "aria-label": typeof title === "string" ? title : void 0, children })
87
+ ] })
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ function ExpandCardGrid({
93
+ children,
94
+ defaultOpen = null,
95
+ onOpenChange,
96
+ minWidth = 240,
97
+ gap = 16,
98
+ radius = 16,
99
+ mediaHeight = 150,
100
+ openMediaHeight = 300,
101
+ titleSize = 17,
102
+ duration = 480,
103
+ backgroundColor = "#1a1c2c",
104
+ textColor = "#f4f4f4",
105
+ mutedColor = "#94b0c2",
106
+ lineColor = "rgba(255,255,255,0.1)",
107
+ accentColor = "#73eff7",
108
+ fontFamily = "ui-sans-serif, system-ui, sans-serif",
109
+ className = "",
110
+ style
111
+ }) {
112
+ useStyles();
113
+ const ref = useRef(null);
114
+ const [openId, setOpenId] = useState(defaultOpen);
115
+ const before = useRef(null);
116
+ const toggle = (next) => {
117
+ const grid = ref.current;
118
+ if (grid) before.current = new Map([...grid.children].map((card) => [card.dataset.expandKey, card.getBoundingClientRect()]));
119
+ setOpenId(next);
120
+ onOpenChange?.(next);
121
+ };
122
+ useLayoutEffect(() => {
123
+ const grid = ref.current;
124
+ const old = before.current;
125
+ before.current = null;
126
+ if (!grid || !old || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
127
+ for (const card of grid.children) {
128
+ const from = old.get(card.dataset.expandKey);
129
+ if (!from) continue;
130
+ const to = card.getBoundingClientRect();
131
+ const dx = from.left - to.left;
132
+ const dy = from.top - to.top;
133
+ const easing = "cubic-bezier(.2,.9,.25,1)";
134
+ if (Math.abs(from.width - to.width) > 1 || Math.abs(from.height - to.height) > 1) {
135
+ card.animate(
136
+ [
137
+ { transform: `translate(${dx}px, ${dy}px)`, width: `${from.width}px`, height: `${from.height}px` },
138
+ { transform: "none", width: `${to.width}px`, height: `${to.height}px` }
139
+ ],
140
+ { duration, easing }
141
+ );
142
+ } else if (dx || dy) {
143
+ card.animate([{ transform: `translate(${dx}px, ${dy}px)` }, { transform: "none" }], { duration, easing });
144
+ }
145
+ }
146
+ const opened = grid.querySelector("[data-open]");
147
+ if (opened) {
148
+ const rect = opened.getBoundingClientRect();
149
+ if (rect.top < 0 || rect.top > window.innerHeight * 0.6) opened.scrollIntoView({ block: "start", behavior: "smooth" });
150
+ }
151
+ }, [openId, duration]);
152
+ return /* @__PURE__ */ jsx(GridContext.Provider, { value: { openId, toggle }, children: /* @__PURE__ */ jsx(
153
+ "div",
154
+ {
155
+ ref,
156
+ className: `bl-xgrid ${className}`,
157
+ style: {
158
+ "--bl-min": `${minWidth}px`,
159
+ "--bl-gap": `${gap}px`,
160
+ "--bl-radius": `${radius}px`,
161
+ "--bl-media": `${mediaHeight}px`,
162
+ "--bl-media-open": `${openMediaHeight}px`,
163
+ "--bl-title": `${titleSize}px`,
164
+ "--bl-dur": `${duration}ms`,
165
+ "--bl-bg": backgroundColor,
166
+ "--bl-ink": textColor,
167
+ "--bl-muted": mutedColor,
168
+ "--bl-line": lineColor,
169
+ "--bl-accent": accentColor,
170
+ "--bl-font": fontFamily,
171
+ ...style
172
+ },
173
+ children: Children.map(children, (child, i) => isValidElement(child) ? cloneElement(child, { id: child.props.id ?? `card-${i}` }) : child)
174
+ }
175
+ ) });
176
+ }
177
+ var stdin_default = ExpandCardGrid;
178
+ export {
179
+ ExpandCard,
180
+ ExpandCardGrid,
181
+ stdin_default as default
182
+ };
@@ -0,0 +1,34 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ export interface FeatureItem {
3
+ id?: string | number;
4
+ title: ReactNode;
5
+ description?: ReactNode;
6
+ /** Shown in the media panel while this tab is active. */
7
+ media?: ReactNode;
8
+ }
9
+ export interface FeatureTabsProps {
10
+ items?: FeatureItem[];
11
+ /** Time per tab, in ms. */
12
+ interval?: number;
13
+ /** Advance automatically (off under reduced motion). */
14
+ autoPlay?: boolean;
15
+ defaultIndex?: number;
16
+ onChange?: (index: number, item: FeatureItem) => void;
17
+ /** Media panel aspect ratio, e.g. "4 / 3". */
18
+ mediaAspect?: string;
19
+ gap?: number;
20
+ radius?: number;
21
+ textColor?: string;
22
+ mutedColor?: string;
23
+ accentColor?: string;
24
+ hoverColor?: string;
25
+ activeColor?: string;
26
+ trackColor?: string;
27
+ stageColor?: string;
28
+ lineColor?: string;
29
+ titleSize?: number;
30
+ fontFamily?: string;
31
+ className?: string;
32
+ style?: CSSProperties;
33
+ }
34
+ export default function FeatureTabs({ items, interval, autoPlay, defaultIndex, onChange, mediaAspect, gap, radius, textColor, mutedColor, accentColor, hoverColor, activeColor, trackColor, stageColor, lineColor, titleSize, fontFamily, className, style }: FeatureTabsProps): import("react").JSX.Element;
@@ -0,0 +1,169 @@
1
+ 'use client';
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useId, useInsertionEffect, useRef, useState } from "react";
4
+ const STYLE_ID = "bl-feature-tabs";
5
+ const CSS = `
6
+ .bl-ft-wrap { container-type: inline-size; width: 100%; }
7
+ .bl-ft { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--bl-gap); align-items: center; color: var(--bl-ink); font-family: var(--bl-font); }
8
+ .bl-ft__list { display: flex; flex-direction: column; gap: 6px; }
9
+ .bl-ft__tab { position: relative; display: block; width: 100%; padding: 16px 18px 18px; border: 0; border-radius: var(--bl-radius); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; overflow: hidden; transition: background-color 200ms; }
10
+ .bl-ft__tab:hover { background: var(--bl-hover); }
11
+ .bl-ft__tab[aria-selected="true"] { background: var(--bl-active); }
12
+ .bl-ft__tab:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 2px; }
13
+ .bl-ft__title { display: block; font-weight: 700; font-size: var(--bl-title-size); line-height: 1.25; opacity: 0.6; transition: opacity 200ms; }
14
+ .bl-ft__tab[aria-selected="true"] .bl-ft__title { opacity: 1; }
15
+ .bl-ft__desc { display: grid; grid-template-rows: 0fr; color: var(--bl-muted); font-size: 14px; line-height: 1.5; transition: grid-template-rows 320ms cubic-bezier(.2,.8,.2,1); }
16
+ .bl-ft__desc > span { overflow: hidden; }
17
+ .bl-ft__tab[aria-selected="true"] .bl-ft__desc { grid-template-rows: 1fr; }
18
+ .bl-ft__desc > span > span { display: block; padding-top: 6px; }
19
+ .bl-ft__track { position: absolute; left: 18px; right: 18px; bottom: 8px; height: 3px; border-radius: 2px; background: var(--bl-track); overflow: hidden; opacity: 0; }
20
+ .bl-ft__tab[aria-selected="true"] .bl-ft__track { opacity: 1; }
21
+ .bl-ft__fill { width: 100%; height: 100%; background: var(--bl-accent); transform-origin: left; transform: scaleX(0); }
22
+ .bl-ft__fill[data-run] { animation: bl-ft-fill var(--bl-interval) linear forwards; }
23
+ .bl-ft[data-paused] .bl-ft__fill[data-run] { animation-play-state: paused; }
24
+ @keyframes bl-ft-fill { to { transform: scaleX(1); } }
25
+ .bl-ft__stage { position: relative; aspect-ratio: var(--bl-ratio); border-radius: var(--bl-radius); overflow: hidden; background: var(--bl-stage); box-shadow: inset 0 0 0 1px var(--bl-line); }
26
+ .bl-ft__panel { position: absolute; inset: 0; opacity: 0; transform: scale(1.03); transition: opacity 500ms ease, transform 700ms cubic-bezier(.2,.8,.2,1); }
27
+ .bl-ft__panel[data-active] { opacity: 1; transform: none; }
28
+ .bl-ft__panel > img, .bl-ft__panel > video { width: 100%; height: 100%; object-fit: cover; display: block; }
29
+ .bl-ft__pause { position: absolute; right: 12px; bottom: 12px; z-index: 2; display: grid; place-items: center; width: 34px; height: 34px; border: 0; border-radius: 50%; background: rgba(0,0,0,0.55); color: #fff; cursor: pointer; }
30
+ .bl-ft__pause:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 2px; }
31
+ @container (max-width: 680px) {
32
+ .bl-ft { grid-template-columns: minmax(0, 1fr); }
33
+ .bl-ft__stage { order: -1; }
34
+ }
35
+ @media (prefers-reduced-motion: reduce) {
36
+ .bl-ft__panel, .bl-ft__desc, .bl-ft__title { transition: none; }
37
+ .bl-ft__panel { transform: none; }
38
+ }
39
+ `;
40
+ function useStyles() {
41
+ useInsertionEffect(() => {
42
+ if (typeof document === "undefined") return;
43
+ const style = document.getElementById(STYLE_ID) ?? Object.assign(document.createElement("style"), { id: STYLE_ID });
44
+ style.textContent = CSS;
45
+ if (!style.isConnected) document.head.appendChild(style);
46
+ }, []);
47
+ }
48
+ const PauseIcon = ({ paused }) => /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "currentColor", "aria-hidden": "true", children: paused ? /* @__PURE__ */ jsx("path", { d: "M3 1.5v11l9.5-5.5z" }) : /* @__PURE__ */ jsx("path", { d: "M2.5 1.5h3.2v11H2.5zm5.8 0h3.2v11H8.3z" }) });
49
+ function FeatureTabs({
50
+ items = [],
51
+ interval = 5e3,
52
+ autoPlay = true,
53
+ defaultIndex = 0,
54
+ onChange,
55
+ mediaAspect = "4 / 3",
56
+ gap = 32,
57
+ radius = 14,
58
+ textColor = "#f4f4f4",
59
+ mutedColor = "#94b0c2",
60
+ accentColor = "#73eff7",
61
+ hoverColor = "rgba(255,255,255,0.04)",
62
+ activeColor = "rgba(255,255,255,0.07)",
63
+ trackColor = "rgba(255,255,255,0.12)",
64
+ stageColor = "#1a1c2c",
65
+ lineColor = "rgba(255,255,255,0.08)",
66
+ titleSize = 17,
67
+ fontFamily = "ui-sans-serif, system-ui, sans-serif",
68
+ className = "",
69
+ style
70
+ }) {
71
+ useStyles();
72
+ const uid = useId().replace(/[^a-zA-Z0-9_-]/g, "");
73
+ const tabs = useRef([]);
74
+ const [index, setIndex] = useState(Math.min(defaultIndex, Math.max(0, items.length - 1)));
75
+ const [userPaused, setUserPaused] = useState(false);
76
+ const [hovering, setHovering] = useState(false);
77
+ const reduced = typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
78
+ const playing = autoPlay && !reduced && items.length > 1;
79
+ const select = (next, focus = false) => {
80
+ const wrapped = (next + items.length) % items.length;
81
+ setIndex(wrapped);
82
+ onChange?.(wrapped, items[wrapped]);
83
+ if (focus) tabs.current[wrapped]?.focus();
84
+ };
85
+ const onKeyDown = (event) => {
86
+ const moves = { ArrowDown: index + 1, ArrowRight: index + 1, ArrowUp: index - 1, ArrowLeft: index - 1, Home: 0, End: items.length - 1 };
87
+ if (!(event.key in moves)) return;
88
+ event.preventDefault();
89
+ select(moves[event.key], true);
90
+ };
91
+ const paused = userPaused || hovering;
92
+ return /* @__PURE__ */ jsx("div", { className: `bl-ft-wrap ${className}`, style, children: /* @__PURE__ */ jsxs(
93
+ "div",
94
+ {
95
+ className: "bl-ft",
96
+ "data-paused": paused || void 0,
97
+ onPointerEnter: (event) => event.pointerType === "mouse" && setHovering(true),
98
+ onPointerLeave: () => setHovering(false),
99
+ style: {
100
+ "--bl-interval": `${interval}ms`,
101
+ "--bl-ratio": mediaAspect,
102
+ "--bl-gap": `${gap}px`,
103
+ "--bl-radius": `${radius}px`,
104
+ "--bl-ink": textColor,
105
+ "--bl-muted": mutedColor,
106
+ "--bl-accent": accentColor,
107
+ "--bl-hover": hoverColor,
108
+ "--bl-active": activeColor,
109
+ "--bl-track": trackColor,
110
+ "--bl-stage": stageColor,
111
+ "--bl-line": lineColor,
112
+ "--bl-title-size": `${titleSize}px`,
113
+ "--bl-font": fontFamily
114
+ },
115
+ children: [
116
+ /* @__PURE__ */ jsx("div", { className: "bl-ft__list", role: "tablist", "aria-orientation": "vertical", onKeyDown, children: items.map((item, i) => /* @__PURE__ */ jsxs(
117
+ "button",
118
+ {
119
+ ref: (node) => {
120
+ tabs.current[i] = node;
121
+ },
122
+ id: `${uid}-tab-${i}`,
123
+ className: "bl-ft__tab",
124
+ role: "tab",
125
+ type: "button",
126
+ "aria-selected": i === index,
127
+ "aria-controls": `${uid}-panel-${i}`,
128
+ tabIndex: i === index ? 0 : -1,
129
+ onClick: () => select(i),
130
+ children: [
131
+ /* @__PURE__ */ jsx("span", { className: "bl-ft__title", children: item.title }),
132
+ item.description && /* @__PURE__ */ jsx("span", { className: "bl-ft__desc", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx("span", { children: item.description }) }) }),
133
+ playing && /* @__PURE__ */ jsx("span", { className: "bl-ft__track", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
134
+ "span",
135
+ {
136
+ className: "bl-ft__fill",
137
+ "data-run": i === index ? "" : void 0,
138
+ onAnimationEnd: () => i === index && select(index + 1)
139
+ },
140
+ `${index}-${i}`
141
+ ) })
142
+ ]
143
+ },
144
+ item.id ?? i
145
+ )) }),
146
+ /* @__PURE__ */ jsxs("div", { className: "bl-ft__stage", children: [
147
+ items.map((item, i) => /* @__PURE__ */ jsx(
148
+ "div",
149
+ {
150
+ id: `${uid}-panel-${i}`,
151
+ className: "bl-ft__panel",
152
+ role: "tabpanel",
153
+ "aria-labelledby": `${uid}-tab-${i}`,
154
+ "aria-hidden": i !== index,
155
+ inert: i !== index ? true : void 0,
156
+ "data-active": i === index ? "" : void 0,
157
+ children: item.media
158
+ },
159
+ item.id ?? i
160
+ )),
161
+ playing && /* @__PURE__ */ jsx("button", { className: "bl-ft__pause", type: "button", onClick: () => setUserPaused((p) => !p), "aria-label": userPaused ? "Play feature tour" : "Pause feature tour", children: /* @__PURE__ */ jsx(PauseIcon, { paused: userPaused }) })
162
+ ] })
163
+ ]
164
+ }
165
+ ) });
166
+ }
167
+ export {
168
+ FeatureTabs as default
169
+ };
@@ -0,0 +1,37 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ export interface FeedItem {
3
+ id: string | number;
4
+ title: string;
5
+ body?: ReactNode;
6
+ icon?: ReactNode;
7
+ /** When it happened; shown as a relative time. */
8
+ time?: Date | number | string;
9
+ /** Icon colour. */
10
+ tone?: string;
11
+ }
12
+ export interface FeedListProps {
13
+ /** Newest first. */
14
+ items?: FeedItem[];
15
+ /** Makes the feed a listbox you can move through and pick from. */
16
+ onSelect?: (item: FeedItem) => void;
17
+ max?: number;
18
+ label?: string;
19
+ emptyLabel?: string;
20
+ /** Relative-time language. */
21
+ locale?: string;
22
+ width?: number;
23
+ maxHeight?: number;
24
+ radius?: number;
25
+ backgroundColor?: string;
26
+ textColor?: string;
27
+ mutedColor?: string;
28
+ hoverColor?: string;
29
+ chipColor?: string;
30
+ lineColor?: string;
31
+ accentColor?: string;
32
+ flashColor?: string;
33
+ fontFamily?: string;
34
+ className?: string;
35
+ style?: CSSProperties;
36
+ }
37
+ export default function FeedList({ items, onSelect, max, label, emptyLabel, locale, width, maxHeight, radius, backgroundColor, textColor, mutedColor, hoverColor, chipColor, lineColor, accentColor, flashColor, fontFamily, className, style }: FeedListProps): import("react").JSX.Element;