fancy-ui-react 0.2.1 → 0.4.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 (93) hide show
  1. package/README.md +56 -20
  2. package/dist/components/animated-beam/AnimatedBeam.d.ts +47 -11
  3. package/dist/components/animated-beam/AnimatedBeam.js +293 -118
  4. package/dist/components/animated-tooltip/AnimatedTooltip.d.ts +10 -1
  5. package/dist/components/animated-tooltip/AnimatedTooltip.js +170 -101
  6. package/dist/components/bento-grid/BentoFrame.d.ts +16 -0
  7. package/dist/components/bento-grid/BentoFrame.js +28 -0
  8. package/dist/components/bento-grid/BentoGrid.d.ts +5 -1
  9. package/dist/components/bento-grid/BentoGrid.js +71 -2
  10. package/dist/components/bento-grid/BentoGridCard.js +34 -26
  11. package/dist/components/bento-grid/BentoGridItem.js +10 -10
  12. package/dist/components/border-beam/BorderBeam.d.ts +55 -10
  13. package/dist/components/border-beam/BorderBeam.js +93 -16
  14. package/dist/components/button/Button.js +5 -1
  15. package/dist/components/compare/Compare.d.ts +32 -8
  16. package/dist/components/compare/Compare.js +213 -95
  17. package/dist/components/container-scroll/ContainerScroll.d.ts +26 -4
  18. package/dist/components/container-scroll/ContainerScroll.js +88 -49
  19. package/dist/components/datamosh-transition/DatamoshTransition.d.ts +76 -0
  20. package/dist/components/datamosh-transition/DatamoshTransition.js +368 -0
  21. package/dist/components/datamosh-transition/datamosh-transition-core.d.ts +180 -0
  22. package/dist/components/datamosh-transition/datamosh-transition-core.js +370 -0
  23. package/dist/components/datamosh-transition/index.d.ts +3 -0
  24. package/dist/components/dock/Dock.d.ts +10 -7
  25. package/dist/components/dock/Dock.js +76 -31
  26. package/dist/components/dock/DockIcon.d.ts +14 -3
  27. package/dist/components/dock/DockIcon.js +23 -19
  28. package/dist/components/dock/DockSeparator.d.ts +4 -1
  29. package/dist/components/dock/DockSeparator.js +5 -2
  30. package/dist/components/dock/types.d.ts +13 -6
  31. package/dist/components/dropdown-menu/menu-shared.d.ts +11 -8
  32. package/dist/components/editorial-engine/engine.js +1 -14
  33. package/dist/components/fireworks-hdr/webgl2-renderer.js +0 -19
  34. package/dist/components/fireworks-hdr/webgpu-renderer.js +3 -22
  35. package/dist/components/flip-card/FlipCard.d.ts +42 -1
  36. package/dist/components/flip-card/FlipCard.js +178 -25
  37. package/dist/components/flip-card/index.d.ts +1 -1
  38. package/dist/components/fluid-cursor/FluidCursor.js +5 -4
  39. package/dist/components/fluid-cursor/dev.d.ts +1 -0
  40. package/dist/components/fluid-cursor/dev.js +8 -0
  41. package/dist/components/fluid-cursor/fluid-shared.d.ts +0 -2
  42. package/dist/components/fluid-cursor/fluid-shared.js +0 -2
  43. package/dist/components/fluid-cursor/webgpu-engine.js +10 -24
  44. package/dist/components/glow-border/GlowBorder.d.ts +41 -1
  45. package/dist/components/glow-border/GlowBorder.js +96 -16
  46. package/dist/components/glow-border/index.d.ts +2 -2
  47. package/dist/components/gradient-button/GradientButton.d.ts +10 -5
  48. package/dist/components/gradient-button/GradientButton.js +25 -18
  49. package/dist/components/image-trail-cursor/ImageTrailCursor.js +1 -0
  50. package/dist/components/image-trail-cursor/trail-variants.d.ts +37 -1
  51. package/dist/components/image-trail-cursor/trail-variants.js +331 -8
  52. package/dist/components/interactive-hover-button/InteractiveHoverButton.js +30 -35
  53. package/dist/components/marquee/Marquee.d.ts +7 -3
  54. package/dist/components/marquee/Marquee.js +134 -2
  55. package/dist/components/marquee/ReviewCard.d.ts +2 -1
  56. package/dist/components/marquee/ReviewCard.js +20 -9
  57. package/dist/components/meteors/Meteors.d.ts +32 -10
  58. package/dist/components/meteors/Meteors.js +53 -20
  59. package/dist/components/mosaic-glow/mosaic-glow-core.d.ts +98 -10
  60. package/dist/components/neon-border/NeonBorder.d.ts +24 -5
  61. package/dist/components/neon-border/NeonBorder.js +37 -7
  62. package/dist/components/pagination/Pagination.js +220 -82
  63. package/dist/components/rainbow-button/RainbowButton.js +13 -5
  64. package/dist/components/ripple-button/RippleButton.d.ts +20 -1
  65. package/dist/components/ripple-button/RippleButton.js +44 -21
  66. package/dist/components/shimmer-button/ShimmerButton.d.ts +5 -5
  67. package/dist/components/shimmer-button/ShimmerButton.js +17 -19
  68. package/dist/components/smooth-cursor/SmoothCursor.d.ts +13 -9
  69. package/dist/components/smooth-cursor/SmoothCursor.js +114 -163
  70. package/dist/components/smooth-cursor/smooth-cursor-core.d.ts +85 -0
  71. package/dist/components/smooth-cursor/smooth-cursor-core.js +327 -0
  72. package/dist/components/stepper/Step.js +32 -19
  73. package/dist/components/stepper/Stepper.js +18 -2
  74. package/dist/components/stepper/types.d.ts +13 -0
  75. package/dist/components/timeline/Timeline.d.ts +8 -1
  76. package/dist/components/timeline/Timeline.js +165 -76
  77. package/dist/index.d.ts +1 -0
  78. package/dist/index.js +6 -1
  79. package/dist/internals/markdown.d.ts +5 -0
  80. package/dist/internals/motion/haptics.d.ts +0 -4
  81. package/dist/internals/motion/presence-core.d.ts +59 -0
  82. package/dist/internals/motion/presence-core.js +162 -0
  83. package/dist/internals/motion/presence.d.ts +2 -4
  84. package/dist/internals/motion/presence.js +1 -156
  85. package/dist/internals/motion/raf.d.ts +1 -1
  86. package/dist/internals/motion/stagger.d.ts +3 -4
  87. package/dist/internals/motion/tokens.js +4 -0
  88. package/dist/internals/motion/transitions.d.ts +17 -17
  89. package/dist/internals/motion/types.d.ts +6 -7
  90. package/dist/internals/relative-time.d.ts +1 -1
  91. package/dist/styles.css +3545 -204
  92. package/package.json +18 -2
  93. package/dist/components/fireworks-hdr/webgpu-types.d.ts +0 -159
@@ -0,0 +1,180 @@
1
+ /**
2
+ * DatamoshTransition core — pure math, no DOM.
3
+ *
4
+ * The look: flat blocks of saturated colour in a FIXED column grid, each column
5
+ * a stack of tiles falling along one sigmoid curve — slivers at the top and
6
+ * bottom, one fat tile snapping open through the middle. Nothing ever moves
7
+ * horizontally; only the vertical tiling animates.
8
+ *
9
+ * On top of that sits the transition itself: every column owns a covered band
10
+ * [top, bot] (0..1 of the height). Cover drops the band's bottom edge like a
11
+ * curtain, reveal lets its top edge fall away, columns staggered right to left.
12
+ */
13
+ export declare const DEFAULT_COLORS: readonly ["#ffffff", "#3566ff", "#ffcf00", "#192aff", "#d62036", "#282142", "#ec4978", "#ff9900", "#14101f", "#00dd33", "#00ef82"];
14
+ /** Column edges sit at W·(i/N)^power: narrow left, wide right — reads as receding perspective. */
15
+ export declare const DEFAULT_COLUMNS = 11;
16
+ export declare const DEFAULT_POWER = 1.65;
17
+ /** Odd so exactly one tile sits dead centre and takes the whole bulge. */
18
+ export declare const DEFAULT_TILES = 15;
19
+ /** Seconds per tile step at speed 1. */
20
+ export declare const CYCLE = 0.2;
21
+ /** Seconds between neighbouring columns starting to fall (right column first). */
22
+ export declare const FALL_STAGGER = 0.006;
23
+ /** Sigmoid exponent — steepness at the centre is tile height. */
24
+ export declare const STRETCH = 8.5;
25
+ /** Exponential arrival rate inside a tile step (the "spring"). */
26
+ export declare const SPRING_K = 1.6;
27
+ /** Each tile overhangs the one below by this fraction of the height. */
28
+ export declare const BLEED = 0.012;
29
+ /** Phase offset per column, in tiles — the zig-zag. Negative: stacks ride higher to the right. */
30
+ export declare const COL_PHASE = -0.4;
31
+ /** Slope of the curve past both ends; clamping would pile off-screen tiles onto y = 0. */
32
+ export declare const TAIL_SLOPE = 0.05;
33
+ /** Length of the cyclic colour strip every column reads. */
34
+ export declare const STRIP_LENGTH = 61;
35
+ /** Small, fast, seedable PRNG (32-bit state). Same seed → same sequence. */
36
+ export declare function mulberry32(seed: number): () => number;
37
+ /** Relative luminance of a hex (#rgb / #rrggbb) or rgb() colour; null when unparseable. */
38
+ export declare function luminance(color: string): number | null;
39
+ export interface PaletteRoles {
40
+ /** The lightest colour — recurs most often (~a quarter of the strip). */
41
+ light: number;
42
+ /** The darkest one or two colours — the other contrast anchor. */
43
+ darks: number[];
44
+ /** Everything else. */
45
+ hues: number[];
46
+ }
47
+ /** Split a palette into contrast anchors and mid-tone hues by luminance. */
48
+ export declare function paletteRoles(colors: readonly string[]): PaletteRoles;
49
+ /**
50
+ * The cyclic colour strip, as palette indices. Light and dark anchors recur
51
+ * often on purpose: a fixed palette stride walks past them and leaves flat
52
+ * mid-tone corduroy. No two neighbours repeat, including across the wrap.
53
+ */
54
+ export declare function buildStrip(seed: number, colors: readonly string[], len?: number): number[];
55
+ /** Colour for a tile, keyed by its IDENTITY (never its on-screen slot) — colours stay put. */
56
+ export declare function stripIndex(strip: readonly number[], id: number, column: number): number;
57
+ /** Column edges in device px: W·(i/N)^power, rounded. Length = columns + 1. */
58
+ export declare function columnEdges(width: number, columns: number, power: number): number[];
59
+ /** Force a usable odd tile count (≥ 3). */
60
+ export declare function oddTiles(tiles: number): number;
61
+ /**
62
+ * Where tile boundary `k` sits, 0..1 of the height. Sigmoid across [0, tiles],
63
+ * extended LINEARLY (shallow slope) past both ends rather than clamped.
64
+ */
65
+ export declare function tileEdge(k: number, tiles: number, stretch?: number): number;
66
+ /**
67
+ * Re-time the fraction of one tile step: exponential arrival mirrored at the
68
+ * halfway point. Rushes in, hangs at the centre (fattest), releases. Monotonic,
69
+ * exact at 0 and 1, so the stack never drifts off schedule.
70
+ */
71
+ export declare function springStep(p: number): number;
72
+ /**
73
+ * Unbounded phase of column `i` at `elapsed` seconds. Never wrapped: tile
74
+ * identity is derived from it, so a wrap would teleport every boundary.
75
+ */
76
+ export declare function columnFlow(elapsed: number, column: number, columns: number, speed?: number): number;
77
+ export interface TileRect {
78
+ id: number;
79
+ /** Device px, unclamped. */
80
+ top: number;
81
+ /** Device px, bleed included, unclamped. */
82
+ bot: number;
83
+ }
84
+ /**
85
+ * The tiles of one column at `flow`, ordered BOTTOM-UP (paint order): each
86
+ * tile overhangs the one below it by `bleed` px, so painting upward laps the
87
+ * overhang over the lower tile instead of hiding it under it.
88
+ */
89
+ export declare function columnTiles(flow: number, tiles: number, height: number, bleed: number): TileRect[];
90
+ export type Direction = "cover" | "reveal";
91
+ export interface Coverage {
92
+ /** Covered band per column, linear 0..1 (eased only when drawn). */
93
+ top: Float32Array;
94
+ bot: Float32Array;
95
+ }
96
+ export declare function createCoverage(columns: number, covered?: boolean): Coverage;
97
+ /** Order in which the columns move. */
98
+ export type DatamoshSweep = "right" | "left" | "center" | "edges" | "random";
99
+ /**
100
+ * Delay before each column moves, in seconds. `right` starts at the rightmost
101
+ * column, `center` fans out from the middle, `edges` closes in from both
102
+ * sides, `random` is a seeded shuffle.
103
+ */
104
+ export declare function columnDelays(columns: number, sweep: DatamoshSweep, stagger: number, seed?: number): number[];
105
+ /**
106
+ * Advance every column one step toward `direction`. Cover drops the band's
107
+ * bottom edge to 1 (and pulls a half-fallen top back up); reveal lets the top
108
+ * edge fall onto the bottom one. Monotonic per column, so an interruption just
109
+ * reverses from wherever each column is. Returns true once every column is done.
110
+ */
111
+ export declare function stepCoverage(cov: Coverage, direction: Direction, phaseTime: number, dt: number, duration: number, delays: ArrayLike<number>): boolean;
112
+ /** Snap every column to the end of `direction`. */
113
+ export declare function settleCoverage(cov: Coverage, direction: Direction): void;
114
+ /** Ease for a band edge: cubic in-out, exact at 0 and 1. */
115
+ export declare function easeEdge(a: number): number;
116
+ /**
117
+ * Shape of the covered band. `curtain` drops from the top and falls away,
118
+ * `rise` climbs from the bottom and lifts off, `split` opens from the centre
119
+ * line and squeezes shut onto it, `interlace` alternates curtain and rise
120
+ * column by column. Everything stays vertical.
121
+ */
122
+ export type DatamoshEffect = "curtain" | "rise" | "split" | "interlace";
123
+ export interface Band {
124
+ /** 0..1 of the height. */
125
+ y0: number;
126
+ y1: number;
127
+ /** Draw the tile stack upside down (tiles rise instead of fall). */
128
+ mirror: boolean;
129
+ }
130
+ /**
131
+ * Map a column's curtain-space band `[top, bot]` (already eased) onto the
132
+ * screen for `effect`. Curtain space is what `stepCoverage` animates; every
133
+ * effect is a pure re-mapping of it, so interruptions behave the same.
134
+ */
135
+ export declare function columnBand(effect: DatamoshEffect, column: number, top: number, bot: number): Band;
136
+ /** Ready-made palettes. Each keeps one light anchor and a couple of near-blacks. */
137
+ export declare const DATAMOSH_PALETTES: {
138
+ readonly broadcast: readonly ["#ffffff", "#3566ff", "#ffcf00", "#192aff", "#d62036", "#282142", "#ec4978", "#ff9900", "#14101f", "#00dd33", "#00ef82"];
139
+ readonly thermal: readonly ["#fff4d6", "#ffd23f", "#ff9f1c", "#ff5a1f", "#e0282e", "#b0125b", "#6a0f63", "#2a0a3d", "#0d0614"];
140
+ readonly sunset: readonly ["#fff6d8", "#fbc56b", "#f59a3a", "#e97a1d", "#c85a14", "#8a4a22", "#5a3b25", "#2d1c16", "#140b08"];
141
+ readonly mono: readonly ["#ffffff", "#e5e5e5", "#b5b5b5", "#8a8a8a", "#5c5c5c", "#2e2e2e", "#141414", "#050505"];
142
+ readonly acid: readonly ["#f4ffe8", "#e4ff1a", "#00ff9c", "#00e0ff", "#3d5afe", "#8c3dff", "#ff2bd6", "#1b0b36", "#070707"];
143
+ };
144
+ export type DatamoshPaletteName = keyof typeof DATAMOSH_PALETTES;
145
+ /** Resolve a palette name or colour list; falls back to the default for anything unusable. */
146
+ export declare function resolvePalette(colors: readonly string[] | DatamoshPaletteName | undefined): string[];
147
+ /** Largest brightness gain the `boost` auto-levels may apply. */
148
+ export declare const MAX_GAIN = 1.6;
149
+ /** Share of the picture's height the slots sample from, centred. */
150
+ export declare const SOURCE_SPAN = 0.6;
151
+ /**
152
+ * Height (0..1) a slot samples the picture at: spread linearly over the middle
153
+ * `SOURCE_SPAN` of the picture. Not along the fall's sigmoid, which packs
154
+ * almost every slot against the edges, and not over the full height, where
155
+ * frames and borders (the darkest, dullest parts of most pictures) sit.
156
+ */
157
+ export declare function sourceSlotY(slot: number, tiles: number): number;
158
+ /**
159
+ * Which rest slot a tile's colour is sampled from. Keyed by IDENTITY, like the
160
+ * colour strip: a tile keeps its piece of the picture as it falls, so the
161
+ * image gets dragged down in chunks instead of sliding under the grid.
162
+ */
163
+ export declare function sourceSlot(id: number, column: number, tiles: number): number;
164
+ /** Source rect that fits an image over a box like `object-fit: cover`. */
165
+ export declare function coverFit(imgW: number, imgH: number, boxW: number, boxH: number): {
166
+ sx: number;
167
+ sy: number;
168
+ sw: number;
169
+ sh: number;
170
+ };
171
+ /**
172
+ * Colour table `[column][slot]` sampled from an RGBA buffer that already maps
173
+ * onto the overlay box. Each cell averages a 3×3 neighbourhood at the column's
174
+ * centre and the slot's height. `edges` are column edges normalised to 0..1.
175
+ *
176
+ * With `boost` (default), the table is auto-levelled (darkest cell → black,
177
+ * brightest → white) and saturated, so a moody picture still decodes into the
178
+ * flat, saturated blocks the effect is about.
179
+ */
180
+ export declare function sampleSource(pixels: ArrayLike<number>, pw: number, ph: number, edges: readonly number[], tiles: number, boost?: boolean): string[][];
@@ -0,0 +1,370 @@
1
+ "use client";
2
+ const DEFAULT_COLORS = [
3
+ "#ffffff",
4
+ "#3566ff",
5
+ "#ffcf00",
6
+ "#192aff",
7
+ "#d62036",
8
+ "#282142",
9
+ "#ec4978",
10
+ "#ff9900",
11
+ "#14101f",
12
+ "#00dd33",
13
+ "#00ef82"
14
+ ];
15
+ const DEFAULT_COLUMNS = 11;
16
+ const DEFAULT_POWER = 1.65;
17
+ const DEFAULT_TILES = 15;
18
+ const CYCLE = 0.2;
19
+ const FALL_STAGGER = 6e-3;
20
+ const STRETCH = 8.5;
21
+ const BLEED = 0.012;
22
+ const COL_PHASE = -0.4;
23
+ const TAIL_SLOPE = 0.05;
24
+ const STRIP_LENGTH = 61;
25
+ function mulberry32(seed) {
26
+ let a = seed >>> 0;
27
+ return () => {
28
+ a = a + 1831565813 >>> 0;
29
+ let t = a;
30
+ t = Math.imul(t ^ t >>> 15, t | 1);
31
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
32
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
33
+ };
34
+ }
35
+ function luminance(color) {
36
+ const s = color.trim().toLowerCase();
37
+ let rgb = null;
38
+ const hex = s.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/);
39
+ if (hex) {
40
+ const h = hex[1];
41
+ const full = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
42
+ rgb = [0, 2, 4].map((i) => parseInt(full.slice(i, i + 2), 16));
43
+ } else {
44
+ const m = s.match(/^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/);
45
+ if (m) rgb = [Number(m[1]), Number(m[2]), Number(m[3])];
46
+ }
47
+ if (!rgb) return null;
48
+ const [r, g, b] = rgb.map((v) => {
49
+ const c = Math.min(255, v) / 255;
50
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
51
+ });
52
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
53
+ }
54
+ function paletteRoles(colors) {
55
+ const ranked = colors.map((c, i) => ({ i, l: luminance(c) ?? 0.5 })).sort((a, b) => a.l - b.l || a.i - b.i);
56
+ const light = ranked[ranked.length - 1].i;
57
+ const darkCount = colors.length >= 5 ? 2 : 1;
58
+ const darks = ranked.slice(0, darkCount).map((r) => r.i);
59
+ const hues = ranked.slice(darkCount, -1).map((r) => r.i);
60
+ return { light, darks, hues };
61
+ }
62
+ function pickDifferent(from, avoid, len) {
63
+ for (let i = 1; i <= len; i++) {
64
+ const c = (from + i) % len;
65
+ if (!avoid.includes(c)) return c;
66
+ }
67
+ return from;
68
+ }
69
+ function buildStrip(seed, colors, len = STRIP_LENGTH) {
70
+ const n = colors.length;
71
+ if (n < 2) return Array.from({ length: len }, () => 0);
72
+ const { light, darks, hues } = paletteRoles(colors);
73
+ const pool = hues.length ? hues : darks;
74
+ const rand = mulberry32(seed);
75
+ const strip = [];
76
+ let lastHue = -1;
77
+ for (let k = 0; k < len; k++) {
78
+ const r = rand();
79
+ let next;
80
+ if (r < 0.26) {
81
+ next = light;
82
+ } else if (r < 0.42) {
83
+ next = darks[Math.floor(rand() * darks.length)];
84
+ } else {
85
+ let h = pool[Math.floor(rand() * pool.length)];
86
+ if (h === lastHue && pool.length > 1) h = pool[(pool.indexOf(h) + 1) % pool.length];
87
+ lastHue = h;
88
+ next = h;
89
+ }
90
+ if (k > 0 && next === strip[k - 1]) next = pickDifferent(next, [strip[k - 1]], n);
91
+ strip.push(next);
92
+ }
93
+ if (len > 2 && strip[len - 1] === strip[0]) {
94
+ strip[len - 1] = pickDifferent(strip[len - 1], [strip[len - 2], strip[0]], n);
95
+ }
96
+ return strip;
97
+ }
98
+ function stripIndex(strip, id, column) {
99
+ const len = strip.length;
100
+ const s = id - column;
101
+ return strip[(s % len + len) % len];
102
+ }
103
+ function columnEdges(width, columns, power) {
104
+ const edges = [];
105
+ for (let i = 0; i <= columns; i++) {
106
+ edges.push(Math.round(width * Math.pow(i / columns, power)));
107
+ }
108
+ return edges;
109
+ }
110
+ function oddTiles(tiles) {
111
+ const t = Math.max(3, Math.round(Number.isFinite(tiles) ? tiles : DEFAULT_TILES));
112
+ return t % 2 === 0 ? t + 1 : t;
113
+ }
114
+ function tileEdge(k, tiles, stretch = STRETCH) {
115
+ const u = k / tiles;
116
+ if (u < 0) return u * TAIL_SLOPE;
117
+ if (u > 1) return 1 + (u - 1) * TAIL_SLOPE;
118
+ const a = Math.pow(u, stretch);
119
+ return a / (a + Math.pow(1 - u, stretch));
120
+ }
121
+ const SPRING_NORM = 1 - Math.exp(-1.6);
122
+ function springStep(p) {
123
+ const half = (t) => (1 - Math.exp(-1.6 * t)) / SPRING_NORM;
124
+ return p < 0.5 ? 0.5 * half(2 * p) : 1 - 0.5 * half(2 * (1 - p));
125
+ }
126
+ function columnFlow(elapsed, column, columns, speed = 1) {
127
+ const delay = (columns - 1 - column) * FALL_STAGGER;
128
+ const t = elapsed - delay;
129
+ const raw = t <= 0 ? 0 : t * speed / CYCLE;
130
+ const linear = raw + column * COL_PHASE;
131
+ const step = Math.floor(linear);
132
+ return step + springStep(linear - step);
133
+ }
134
+ function columnTiles(flow, tiles, height, bleed) {
135
+ const out = [];
136
+ const base = -Math.floor(flow);
137
+ for (let n = tiles + 2; n >= -2; n--) {
138
+ const id = base + n;
139
+ const k = id + flow;
140
+ const top = Math.round(tileEdge(k, tiles) * height);
141
+ const bot = Math.round(tileEdge(k + 1, tiles) * height) + bleed;
142
+ if (bot <= top) continue;
143
+ out.push({ id, top, bot });
144
+ }
145
+ return out;
146
+ }
147
+ function createCoverage(columns, covered = false) {
148
+ const top = new Float32Array(columns);
149
+ const bot = new Float32Array(columns);
150
+ if (covered) bot.fill(1);
151
+ return { top, bot };
152
+ }
153
+ function columnDelays(columns, sweep, stagger, seed = 1) {
154
+ const mid = (columns - 1) / 2;
155
+ const rank = (i) => {
156
+ switch (sweep) {
157
+ case "left":
158
+ return i;
159
+ case "center":
160
+ return Math.abs(i - mid);
161
+ case "edges":
162
+ return mid - Math.abs(i - mid);
163
+ case "random":
164
+ return 0;
165
+ default:
166
+ return columns - 1 - i;
167
+ }
168
+ };
169
+ if (sweep === "random") {
170
+ const order = Array.from({ length: columns }, (_, i) => i);
171
+ const rand = mulberry32(seed ^ 24301);
172
+ for (let i = order.length - 1; i > 0; i--) {
173
+ const j = Math.floor(rand() * (i + 1));
174
+ [order[i], order[j]] = [order[j], order[i]];
175
+ }
176
+ const delays = new Array(columns);
177
+ order.forEach((col, k) => delays[col] = k * stagger);
178
+ return delays;
179
+ }
180
+ return Array.from({ length: columns }, (_, i) => rank(i) * stagger);
181
+ }
182
+ function stepCoverage(cov, direction, phaseTime, dt, duration, delays) {
183
+ const n = cov.top.length;
184
+ const rate = duration > 0 ? dt / duration : Infinity;
185
+ let done = true;
186
+ for (let i = 0; i < n; i++) {
187
+ const started = phaseTime >= (delays[i] ?? 0);
188
+ if (direction === "cover") {
189
+ if (cov.bot[i] - cov.top[i] <= 1e-6 && cov.bot[i] < 1) {
190
+ cov.top[i] = 0;
191
+ cov.bot[i] = 0;
192
+ }
193
+ if (started) {
194
+ cov.bot[i] = Math.min(1, cov.bot[i] + rate);
195
+ cov.top[i] = Math.max(0, cov.top[i] - rate);
196
+ }
197
+ if (cov.bot[i] < 1 || cov.top[i] > 0) done = false;
198
+ } else {
199
+ if (started) cov.top[i] = Math.min(cov.bot[i], cov.top[i] + rate);
200
+ if (cov.top[i] < cov.bot[i]) done = false;
201
+ }
202
+ }
203
+ return done;
204
+ }
205
+ function settleCoverage(cov, direction) {
206
+ if (direction === "cover") {
207
+ cov.top.fill(0);
208
+ cov.bot.fill(1);
209
+ } else {
210
+ cov.top.fill(0);
211
+ cov.bot.fill(0);
212
+ }
213
+ }
214
+ function easeEdge(a) {
215
+ const x = Math.min(1, Math.max(0, a));
216
+ return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
217
+ }
218
+ function columnBand(effect, column, top, bot) {
219
+ const rise = effect === "rise" || effect === "interlace" && column % 2 === 1;
220
+ if (effect === "split") {
221
+ const half = Math.max(0, bot - top) / 2;
222
+ return { y0: 0.5 - half, y1: 0.5 + half, mirror: false };
223
+ }
224
+ if (rise) return { y0: 1 - bot, y1: 1 - top, mirror: true };
225
+ return { y0: top, y1: bot, mirror: false };
226
+ }
227
+ const DATAMOSH_PALETTES = {
228
+ broadcast: DEFAULT_COLORS,
229
+ thermal: [
230
+ "#fff4d6",
231
+ "#ffd23f",
232
+ "#ff9f1c",
233
+ "#ff5a1f",
234
+ "#e0282e",
235
+ "#b0125b",
236
+ "#6a0f63",
237
+ "#2a0a3d",
238
+ "#0d0614"
239
+ ],
240
+ sunset: [
241
+ "#fff6d8",
242
+ "#fbc56b",
243
+ "#f59a3a",
244
+ "#e97a1d",
245
+ "#c85a14",
246
+ "#8a4a22",
247
+ "#5a3b25",
248
+ "#2d1c16",
249
+ "#140b08"
250
+ ],
251
+ mono: ["#ffffff", "#e5e5e5", "#b5b5b5", "#8a8a8a", "#5c5c5c", "#2e2e2e", "#141414", "#050505"],
252
+ acid: [
253
+ "#f4ffe8",
254
+ "#e4ff1a",
255
+ "#00ff9c",
256
+ "#00e0ff",
257
+ "#3d5afe",
258
+ "#8c3dff",
259
+ "#ff2bd6",
260
+ "#1b0b36",
261
+ "#070707"
262
+ ]
263
+ };
264
+ function resolvePalette(colors) {
265
+ if (typeof colors === "string") return [...DATAMOSH_PALETTES[colors] ?? DEFAULT_COLORS];
266
+ return colors && colors.length >= 2 ? [...colors] : [...DEFAULT_COLORS];
267
+ }
268
+ const MAX_GAIN = 1.6;
269
+ const SOURCE_SPAN = 0.6;
270
+ function sourceSlotY(slot, tiles) {
271
+ return 0.5 + ((slot + 0.5) / tiles - 0.5) * SOURCE_SPAN;
272
+ }
273
+ function sourceSlot(id, column, tiles) {
274
+ const s = id - column;
275
+ return (s % tiles + tiles) % tiles;
276
+ }
277
+ function coverFit(imgW, imgH, boxW, boxH) {
278
+ if (imgW <= 0 || imgH <= 0 || boxW <= 0 || boxH <= 0) return { sx: 0, sy: 0, sw: imgW, sh: imgH };
279
+ const scale = Math.max(boxW / imgW, boxH / imgH);
280
+ const sw = boxW / scale;
281
+ const sh = boxH / scale;
282
+ return { sx: (imgW - sw) / 2, sy: (imgH - sh) / 2, sw, sh };
283
+ }
284
+ function sampleSource(pixels, pw, ph, edges, tiles, boost = true) {
285
+ const at = (x, y) => {
286
+ const cx = Math.min(pw - 1, Math.max(0, x));
287
+ const cy = Math.min(ph - 1, Math.max(0, y));
288
+ return (cy * pw + cx) * 4;
289
+ };
290
+ const cells = [];
291
+ let lo = Infinity;
292
+ let hi = -Infinity;
293
+ for (let i = 0; i + 1 < edges.length; i++) {
294
+ const x = Math.round((edges[i] + edges[i + 1]) / 2 * (pw - 1));
295
+ const row = [];
296
+ for (let s = 0; s < tiles; s++) {
297
+ const y = Math.round(sourceSlotY(s, tiles) * (ph - 1));
298
+ let r = 0;
299
+ let g = 0;
300
+ let b = 0;
301
+ for (let dy = -1; dy <= 1; dy++) {
302
+ for (let dx = -1; dx <= 1; dx++) {
303
+ const k = at(x + dx, y + dy);
304
+ r += pixels[k];
305
+ g += pixels[k + 1];
306
+ b += pixels[k + 2];
307
+ }
308
+ }
309
+ const cell = [r / 9, g / 9, b / 9];
310
+ const l = 0.2126 * cell[0] + 0.7152 * cell[1] + 0.0722 * cell[2];
311
+ lo = Math.min(lo, l);
312
+ hi = Math.max(hi, l);
313
+ row.push(cell);
314
+ }
315
+ cells.push(row);
316
+ }
317
+ const span = hi - lo;
318
+ const level = boost && span > 8 ? Math.min(MAX_GAIN, 255 / (hi - lo * 0.5)) : 1;
319
+ const offset = boost && span > 8 ? lo * 0.5 : 0;
320
+ const saturation = boost ? 1.35 : 1;
321
+ const clamp = (v) => Math.round(Math.min(255, Math.max(0, v)));
322
+ return cells.map(
323
+ (row) => row.map(([r, g, b]) => {
324
+ let [nr, ng, nb] = [(r - offset) * level, (g - offset) * level, (b - offset) * level];
325
+ const l = 0.2126 * nr + 0.7152 * ng + 0.0722 * nb;
326
+ nr = l + (nr - l) * saturation;
327
+ ng = l + (ng - l) * saturation;
328
+ nb = l + (nb - l) * saturation;
329
+ return `rgb(${clamp(nr)}, ${clamp(ng)}, ${clamp(nb)})`;
330
+ })
331
+ );
332
+ }
333
+ export {
334
+ BLEED,
335
+ COL_PHASE,
336
+ CYCLE,
337
+ DATAMOSH_PALETTES,
338
+ DEFAULT_COLORS,
339
+ DEFAULT_COLUMNS,
340
+ DEFAULT_POWER,
341
+ DEFAULT_TILES,
342
+ FALL_STAGGER,
343
+ MAX_GAIN,
344
+ SOURCE_SPAN,
345
+ STRETCH,
346
+ STRIP_LENGTH,
347
+ TAIL_SLOPE,
348
+ buildStrip,
349
+ columnBand,
350
+ columnDelays,
351
+ columnEdges,
352
+ columnFlow,
353
+ columnTiles,
354
+ coverFit,
355
+ createCoverage,
356
+ easeEdge,
357
+ luminance,
358
+ mulberry32,
359
+ oddTiles,
360
+ paletteRoles,
361
+ resolvePalette,
362
+ sampleSource,
363
+ settleCoverage,
364
+ sourceSlot,
365
+ sourceSlotY,
366
+ springStep,
367
+ stepCoverage,
368
+ stripIndex,
369
+ tileEdge
370
+ };
@@ -0,0 +1,3 @@
1
+ export { DatamoshTransition } from "./DatamoshTransition.js";
2
+ export type { DatamoshTransitionProps, DatamoshTransitionPhase, DatamoshTransitionHandle, } from "./DatamoshTransition.js";
3
+ export { DATAMOSH_PALETTES, type DatamoshEffect, type DatamoshSweep, type DatamoshPaletteName, } from "./datamosh-transition-core.js";
@@ -7,22 +7,25 @@ export interface DockProps {
7
7
  magnification?: number;
8
8
  /** Pointer distance over which the magnification falls off. */
9
9
  distance?: number;
10
- /** Vertical alignment of the icons. */
10
+ /** Cross-axis alignment of the icons. */
11
11
  direction?: Direction;
12
12
  /** Dock orientation. */
13
13
  orientation?: DataOrientation;
14
- /**
15
- * Accessible name for the toolbar. The dock spreads no rest props, so this
16
- * is the only way to name one whose icons carry no label of their own.
17
- */
14
+ /** A soft pool of accent light inside the shelf that follows the pointer. */
15
+ spotlight?: boolean;
16
+ /** A soft contact shadow / glow ellipse under each icon that grows with it. */
17
+ reflection?: boolean;
18
+ /** Accessible name for the toolbar. */
18
19
  ariaLabel?: string;
19
20
  /** The `DockIcon`s and `DockSeparator`s. */
20
21
  children?: ReactNode;
21
22
  }
22
23
  /**
23
- * An icon dock whose items magnify smoothly as the pointer approaches.
24
+ * An icon dock on a lit glass shelf: icons swell on a cosine curve as the
25
+ * pointer approaches, a pool of light follows it across the shelf, and the
26
+ * shelf edge brightens near it.
24
27
  *
25
28
  * No `ref` prop: the source exposes no bindable ref, and no rest props either —
26
29
  * it reads only these props and spreads nothing.
27
30
  */
28
- export declare function Dock({ className, magnification, distance, direction, orientation, ariaLabel, children, }: DockProps): import("react").JSX.Element;
31
+ export declare function Dock({ className, magnification, distance, direction, orientation, spotlight, reflection, ariaLabel, children, }: DockProps): import("react").JSX.Element;