@shipfox/react-ui 0.6.0 → 0.8.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.
- package/.storybook/main.ts +12 -5
- package/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-check.log +2 -2
- package/.turbo/turbo-type.log +1 -1
- package/CHANGELOG.md +13 -0
- package/dist/components/button/button.d.ts +2 -1
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +17 -2
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/button.stories.js +25 -0
- package/dist/components/button/button.stories.js.map +1 -1
- package/dist/components/button/icon-button.d.ts +2 -1
- package/dist/components/button/icon-button.d.ts.map +1 -1
- package/dist/components/button/icon-button.js +17 -2
- package/dist/components/button/icon-button.js.map +1 -1
- package/dist/components/button/icon-button.stories.js +90 -0
- package/dist/components/button/icon-button.stories.js.map +1 -1
- package/dist/components/dot-grid/dot-grid.d.ts +18 -0
- package/dist/components/dot-grid/dot-grid.d.ts.map +1 -0
- package/dist/components/dot-grid/dot-grid.js +295 -0
- package/dist/components/dot-grid/dot-grid.js.map +1 -0
- package/dist/components/dot-grid/index.d.ts +2 -0
- package/dist/components/dot-grid/index.d.ts.map +1 -0
- package/dist/components/dot-grid/index.js +3 -0
- package/dist/components/dot-grid/index.js.map +1 -0
- package/dist/components/form/form.d.ts +11 -0
- package/dist/components/form/form.d.ts.map +1 -0
- package/dist/components/form/form.js +106 -0
- package/dist/components/form/form.js.map +1 -0
- package/dist/components/form/form.stories.js +582 -0
- package/dist/components/form/form.stories.js.map +1 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.d.ts.map +1 -0
- package/dist/components/form/index.js +3 -0
- package/dist/components/form/index.js.map +1 -0
- package/dist/components/icon/custom/spinner.d.ts +1 -1
- package/dist/components/icon/custom/spinner.d.ts.map +1 -1
- package/dist/components/icon/custom/spinner.js +84 -30
- package/dist/components/icon/custom/spinner.js.map +1 -1
- package/dist/components/icon/icon.d.ts +19 -18
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/icon/icon.js +17 -17
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -0
- package/dist/components/index.js.map +1 -1
- package/dist/onboarding/sign-in.stories.js +16 -8
- package/dist/onboarding/sign-in.stories.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +13 -10
- package/src/components/button/button.stories.tsx +18 -0
- package/src/components/button/button.tsx +27 -2
- package/src/components/button/icon-button.stories.tsx +46 -0
- package/src/components/button/icon-button.tsx +26 -1
- package/src/components/dot-grid/dot-grid.tsx +325 -0
- package/src/components/dot-grid/index.ts +1 -0
- package/src/components/form/form.stories.tsx +500 -0
- package/src/components/form/form.tsx +154 -0
- package/src/components/form/index.ts +1 -0
- package/src/components/icon/custom/spinner.tsx +64 -18
- package/src/components/icon/icon.tsx +18 -18
- package/src/components/index.ts +3 -0
- package/src/onboarding/sign-in.stories.tsx +20 -8
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { gsap } from 'gsap';
|
|
3
|
+
import { InertiaPlugin } from 'gsap/InertiaPlugin';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
5
|
+
import { cn } from '../../utils/index.js';
|
|
6
|
+
gsap.registerPlugin(InertiaPlugin);
|
|
7
|
+
const HEX_COLOR_REGEX = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
|
|
8
|
+
const throttle = (func, limit)=>{
|
|
9
|
+
let lastCall = 0;
|
|
10
|
+
return (...args)=>{
|
|
11
|
+
const now = performance.now();
|
|
12
|
+
if (now - lastCall >= limit) {
|
|
13
|
+
lastCall = now;
|
|
14
|
+
func(...args);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
function hexToRgb(hex) {
|
|
19
|
+
const m = hex.match(HEX_COLOR_REGEX);
|
|
20
|
+
if (!m) return {
|
|
21
|
+
r: 0,
|
|
22
|
+
g: 0,
|
|
23
|
+
b: 0
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
r: parseInt(m[1], 16),
|
|
27
|
+
g: parseInt(m[2], 16),
|
|
28
|
+
b: parseInt(m[3], 16)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function DotGrid({ dotSize = 16, gap = 32, baseColor = '#5227FF', activeColor = '#5227FF', proximity = 150, speedTrigger = 100, shockRadius = 250, shockStrength = 5, maxSpeed = 5000, resistance = 750, returnDuration = 1.5, className = '', style }) {
|
|
32
|
+
const wrapperRef = useRef(null);
|
|
33
|
+
const canvasRef = useRef(null);
|
|
34
|
+
const dotsRef = useRef([]);
|
|
35
|
+
const pointerRef = useRef({
|
|
36
|
+
x: 0,
|
|
37
|
+
y: 0,
|
|
38
|
+
vx: 0,
|
|
39
|
+
vy: 0,
|
|
40
|
+
speed: 0,
|
|
41
|
+
lastTime: 0,
|
|
42
|
+
lastX: 0,
|
|
43
|
+
lastY: 0
|
|
44
|
+
});
|
|
45
|
+
const baseRgb = useMemo(()=>hexToRgb(baseColor), [
|
|
46
|
+
baseColor
|
|
47
|
+
]);
|
|
48
|
+
const activeRgb = useMemo(()=>hexToRgb(activeColor), [
|
|
49
|
+
activeColor
|
|
50
|
+
]);
|
|
51
|
+
const colorGradient = useMemo(()=>{
|
|
52
|
+
const gradient = new Array(256);
|
|
53
|
+
for(let i = 0; i < 256; i++){
|
|
54
|
+
const normalizedSqDist = i / 255;
|
|
55
|
+
const normalizedDist = Math.sqrt(normalizedSqDist);
|
|
56
|
+
const t = 1 - normalizedDist;
|
|
57
|
+
const r = Math.round(baseRgb.r + (activeRgb.r - baseRgb.r) * t);
|
|
58
|
+
const g = Math.round(baseRgb.g + (activeRgb.g - baseRgb.g) * t);
|
|
59
|
+
const b = Math.round(baseRgb.b + (activeRgb.b - baseRgb.b) * t);
|
|
60
|
+
gradient[i] = `rgb(${r},${g},${b})`;
|
|
61
|
+
}
|
|
62
|
+
return gradient;
|
|
63
|
+
}, [
|
|
64
|
+
baseRgb,
|
|
65
|
+
activeRgb
|
|
66
|
+
]);
|
|
67
|
+
const circlePath = useMemo(()=>{
|
|
68
|
+
if (typeof window === 'undefined' || !window.Path2D) return null;
|
|
69
|
+
const p = new Path2D();
|
|
70
|
+
p.arc(0, 0, dotSize / 2, 0, Math.PI * 2);
|
|
71
|
+
return p;
|
|
72
|
+
}, [
|
|
73
|
+
dotSize
|
|
74
|
+
]);
|
|
75
|
+
const buildGrid = useCallback(()=>{
|
|
76
|
+
const wrap = wrapperRef.current;
|
|
77
|
+
const canvas = canvasRef.current;
|
|
78
|
+
if (!wrap || !canvas) return;
|
|
79
|
+
const { width, height } = wrap.getBoundingClientRect();
|
|
80
|
+
const dpr = window.devicePixelRatio || 1;
|
|
81
|
+
canvas.width = width * dpr;
|
|
82
|
+
canvas.height = height * dpr;
|
|
83
|
+
canvas.style.width = `${width}px`;
|
|
84
|
+
canvas.style.height = `${height}px`;
|
|
85
|
+
const ctx = canvas.getContext('2d');
|
|
86
|
+
if (ctx) ctx.scale(dpr, dpr);
|
|
87
|
+
const cols = Math.floor((width + gap) / (dotSize + gap));
|
|
88
|
+
const rows = Math.floor((height + gap) / (dotSize + gap));
|
|
89
|
+
const cell = dotSize + gap;
|
|
90
|
+
const gridW = cell * cols - gap;
|
|
91
|
+
const gridH = cell * rows - gap;
|
|
92
|
+
const extraX = width - gridW;
|
|
93
|
+
const extraY = height - gridH;
|
|
94
|
+
const startX = extraX / 2 + dotSize / 2;
|
|
95
|
+
const startY = extraY / 2 + dotSize / 2;
|
|
96
|
+
const dots = [];
|
|
97
|
+
for(let y = 0; y < rows; y++){
|
|
98
|
+
for(let x = 0; x < cols; x++){
|
|
99
|
+
const cx = startX + x * cell;
|
|
100
|
+
const cy = startY + y * cell;
|
|
101
|
+
dots.push({
|
|
102
|
+
cx,
|
|
103
|
+
cy,
|
|
104
|
+
xOffset: 0,
|
|
105
|
+
yOffset: 0,
|
|
106
|
+
_inertiaApplied: false
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
dotsRef.current = dots;
|
|
111
|
+
}, [
|
|
112
|
+
dotSize,
|
|
113
|
+
gap
|
|
114
|
+
]);
|
|
115
|
+
useEffect(()=>{
|
|
116
|
+
if (!circlePath) return;
|
|
117
|
+
let rafId;
|
|
118
|
+
const proxSq = proximity * proximity;
|
|
119
|
+
const draw = ()=>{
|
|
120
|
+
const canvas = canvasRef.current;
|
|
121
|
+
if (!canvas) return;
|
|
122
|
+
const ctx = canvas.getContext('2d');
|
|
123
|
+
if (!ctx) return;
|
|
124
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
125
|
+
const { x: px, y: py } = pointerRef.current;
|
|
126
|
+
for (const dot of dotsRef.current){
|
|
127
|
+
const ox = dot.cx + dot.xOffset;
|
|
128
|
+
const oy = dot.cy + dot.yOffset;
|
|
129
|
+
const dx = dot.cx - px;
|
|
130
|
+
const dy = dot.cy - py;
|
|
131
|
+
const dsq = dx * dx + dy * dy;
|
|
132
|
+
let fillColor = baseColor;
|
|
133
|
+
if (dsq <= proxSq) {
|
|
134
|
+
const normalizedSqDist = dsq / proxSq;
|
|
135
|
+
const index = Math.min(255, Math.max(0, Math.round(normalizedSqDist * 255)));
|
|
136
|
+
fillColor = colorGradient[index];
|
|
137
|
+
}
|
|
138
|
+
ctx.save();
|
|
139
|
+
ctx.translate(ox, oy);
|
|
140
|
+
ctx.fillStyle = fillColor;
|
|
141
|
+
ctx.fill(circlePath);
|
|
142
|
+
ctx.restore();
|
|
143
|
+
}
|
|
144
|
+
rafId = requestAnimationFrame(draw);
|
|
145
|
+
};
|
|
146
|
+
draw();
|
|
147
|
+
return ()=>cancelAnimationFrame(rafId);
|
|
148
|
+
}, [
|
|
149
|
+
proximity,
|
|
150
|
+
baseColor,
|
|
151
|
+
colorGradient,
|
|
152
|
+
circlePath
|
|
153
|
+
]);
|
|
154
|
+
useEffect(()=>{
|
|
155
|
+
buildGrid();
|
|
156
|
+
let ro = null;
|
|
157
|
+
if ('ResizeObserver' in window) {
|
|
158
|
+
ro = new ResizeObserver(buildGrid);
|
|
159
|
+
wrapperRef.current && ro.observe(wrapperRef.current);
|
|
160
|
+
} else {
|
|
161
|
+
window.addEventListener('resize', buildGrid);
|
|
162
|
+
}
|
|
163
|
+
return ()=>{
|
|
164
|
+
if (ro) ro.disconnect();
|
|
165
|
+
else window.removeEventListener('resize', buildGrid);
|
|
166
|
+
};
|
|
167
|
+
}, [
|
|
168
|
+
buildGrid
|
|
169
|
+
]);
|
|
170
|
+
useEffect(()=>{
|
|
171
|
+
const onMove = (e)=>{
|
|
172
|
+
const now = performance.now();
|
|
173
|
+
const pr = pointerRef.current;
|
|
174
|
+
const dt = pr.lastTime ? now - pr.lastTime : 16;
|
|
175
|
+
const dx = e.clientX - pr.lastX;
|
|
176
|
+
const dy = e.clientY - pr.lastY;
|
|
177
|
+
let vx = dx / dt * 1000;
|
|
178
|
+
let vy = dy / dt * 1000;
|
|
179
|
+
let speed = Math.hypot(vx, vy);
|
|
180
|
+
if (speed > maxSpeed) {
|
|
181
|
+
const scale = maxSpeed / speed;
|
|
182
|
+
vx *= scale;
|
|
183
|
+
vy *= scale;
|
|
184
|
+
speed = maxSpeed;
|
|
185
|
+
}
|
|
186
|
+
pr.lastTime = now;
|
|
187
|
+
pr.lastX = e.clientX;
|
|
188
|
+
pr.lastY = e.clientY;
|
|
189
|
+
pr.vx = vx;
|
|
190
|
+
pr.vy = vy;
|
|
191
|
+
pr.speed = speed;
|
|
192
|
+
const canvas = canvasRef.current;
|
|
193
|
+
if (!canvas) return;
|
|
194
|
+
const rect = canvas.getBoundingClientRect();
|
|
195
|
+
pr.x = e.clientX - rect.left;
|
|
196
|
+
pr.y = e.clientY - rect.top;
|
|
197
|
+
for (const dot of dotsRef.current){
|
|
198
|
+
const dist = Math.hypot(dot.cx - pr.x, dot.cy - pr.y);
|
|
199
|
+
if (speed > speedTrigger && dist < proximity && !dot._inertiaApplied) {
|
|
200
|
+
dot._inertiaApplied = true;
|
|
201
|
+
gsap.killTweensOf(dot);
|
|
202
|
+
const pushX = dot.cx - pr.x + vx * 0.005;
|
|
203
|
+
const pushY = dot.cy - pr.y + vy * 0.005;
|
|
204
|
+
gsap.to(dot, {
|
|
205
|
+
inertia: {
|
|
206
|
+
xOffset: pushX,
|
|
207
|
+
yOffset: pushY,
|
|
208
|
+
resistance
|
|
209
|
+
},
|
|
210
|
+
onComplete: ()=>{
|
|
211
|
+
gsap.to(dot, {
|
|
212
|
+
xOffset: 0,
|
|
213
|
+
yOffset: 0,
|
|
214
|
+
duration: returnDuration,
|
|
215
|
+
ease: 'elastic.out(1,0.75)'
|
|
216
|
+
});
|
|
217
|
+
dot._inertiaApplied = false;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const onClick = (e)=>{
|
|
224
|
+
const canvas = canvasRef.current;
|
|
225
|
+
if (!canvas) return;
|
|
226
|
+
const rect = canvas.getBoundingClientRect();
|
|
227
|
+
const cx = e.clientX - rect.left;
|
|
228
|
+
const cy = e.clientY - rect.top;
|
|
229
|
+
for (const dot of dotsRef.current){
|
|
230
|
+
const dist = Math.hypot(dot.cx - cx, dot.cy - cy);
|
|
231
|
+
if (dist < shockRadius && !dot._inertiaApplied) {
|
|
232
|
+
dot._inertiaApplied = true;
|
|
233
|
+
gsap.killTweensOf(dot);
|
|
234
|
+
const falloff = Math.max(0, 1 - dist / shockRadius);
|
|
235
|
+
const pushX = (dot.cx - cx) * shockStrength * falloff;
|
|
236
|
+
const pushY = (dot.cy - cy) * shockStrength * falloff;
|
|
237
|
+
gsap.to(dot, {
|
|
238
|
+
inertia: {
|
|
239
|
+
xOffset: pushX,
|
|
240
|
+
yOffset: pushY,
|
|
241
|
+
resistance
|
|
242
|
+
},
|
|
243
|
+
onComplete: ()=>{
|
|
244
|
+
gsap.to(dot, {
|
|
245
|
+
xOffset: 0,
|
|
246
|
+
yOffset: 0,
|
|
247
|
+
duration: returnDuration,
|
|
248
|
+
ease: 'elastic.out(1,0.75)'
|
|
249
|
+
});
|
|
250
|
+
dot._inertiaApplied = false;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
const throttledMove = throttle(onMove, 50);
|
|
257
|
+
const wrapper = wrapperRef.current;
|
|
258
|
+
if (wrapper) {
|
|
259
|
+
wrapper.addEventListener('mousemove', throttledMove, {
|
|
260
|
+
passive: true
|
|
261
|
+
});
|
|
262
|
+
wrapper.addEventListener('click', onClick);
|
|
263
|
+
}
|
|
264
|
+
return ()=>{
|
|
265
|
+
if (wrapper) {
|
|
266
|
+
wrapper.removeEventListener('mousemove', throttledMove);
|
|
267
|
+
wrapper.removeEventListener('click', onClick);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}, [
|
|
271
|
+
maxSpeed,
|
|
272
|
+
speedTrigger,
|
|
273
|
+
proximity,
|
|
274
|
+
resistance,
|
|
275
|
+
returnDuration,
|
|
276
|
+
shockRadius,
|
|
277
|
+
shockStrength
|
|
278
|
+
]);
|
|
279
|
+
return /*#__PURE__*/ _jsx("section", {
|
|
280
|
+
className: cn('p-4 flex items-center justify-center h-full w-full relative', className),
|
|
281
|
+
style: style,
|
|
282
|
+
role: "presentation",
|
|
283
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
284
|
+
ref: wrapperRef,
|
|
285
|
+
className: "w-full h-full relative",
|
|
286
|
+
children: /*#__PURE__*/ _jsx("canvas", {
|
|
287
|
+
ref: canvasRef,
|
|
288
|
+
className: "absolute inset-0 w-full h-full pointer-events-none",
|
|
289
|
+
"aria-hidden": "true"
|
|
290
|
+
})
|
|
291
|
+
})
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//# sourceMappingURL=dot-grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/dot-grid/dot-grid.tsx"],"sourcesContent":["import {gsap} from 'gsap';\nimport {InertiaPlugin} from 'gsap/InertiaPlugin';\nimport type React from 'react';\nimport {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {cn} from 'utils';\n\ngsap.registerPlugin(InertiaPlugin);\n\nconst HEX_COLOR_REGEX = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i;\n\nconst throttle = <T extends (...args: never[]) => void>(func: T, limit: number): T => {\n let lastCall = 0;\n return ((...args: Parameters<T>) => {\n const now = performance.now();\n if (now - lastCall >= limit) {\n lastCall = now;\n func(...args);\n }\n }) as T;\n};\n\ninterface Dot {\n cx: number;\n cy: number;\n xOffset: number;\n yOffset: number;\n _inertiaApplied: boolean;\n}\n\nexport interface DotGridProps {\n dotSize?: number;\n gap?: number;\n baseColor?: string;\n activeColor?: string;\n proximity?: number;\n speedTrigger?: number;\n shockRadius?: number;\n shockStrength?: number;\n maxSpeed?: number;\n resistance?: number;\n returnDuration?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\ntype RgbColor = {\n r: number;\n g: number;\n b: number;\n};\n\nfunction hexToRgb(hex: string): RgbColor {\n const m = hex.match(HEX_COLOR_REGEX);\n if (!m) return {r: 0, g: 0, b: 0};\n return {\n r: parseInt(m[1], 16),\n g: parseInt(m[2], 16),\n b: parseInt(m[3], 16),\n };\n}\n\nexport function DotGrid({\n dotSize = 16,\n gap = 32,\n baseColor = '#5227FF',\n activeColor = '#5227FF',\n proximity = 150,\n speedTrigger = 100,\n shockRadius = 250,\n shockStrength = 5,\n maxSpeed = 5000,\n resistance = 750,\n returnDuration = 1.5,\n className = '',\n style,\n}: DotGridProps): React.JSX.Element {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const dotsRef = useRef<Dot[]>([]);\n const pointerRef = useRef({\n x: 0,\n y: 0,\n vx: 0,\n vy: 0,\n speed: 0,\n lastTime: 0,\n lastX: 0,\n lastY: 0,\n });\n\n const baseRgb = useMemo(() => hexToRgb(baseColor), [baseColor]);\n const activeRgb = useMemo(() => hexToRgb(activeColor), [activeColor]);\n\n const colorGradient = useMemo(() => {\n const gradient: string[] = new Array(256);\n for (let i = 0; i < 256; i++) {\n const normalizedSqDist = i / 255;\n const normalizedDist = Math.sqrt(normalizedSqDist);\n const t = 1 - normalizedDist;\n const r = Math.round(baseRgb.r + (activeRgb.r - baseRgb.r) * t);\n const g = Math.round(baseRgb.g + (activeRgb.g - baseRgb.g) * t);\n const b = Math.round(baseRgb.b + (activeRgb.b - baseRgb.b) * t);\n gradient[i] = `rgb(${r},${g},${b})`;\n }\n return gradient;\n }, [baseRgb, activeRgb]);\n\n const circlePath = useMemo(() => {\n if (typeof window === 'undefined' || !window.Path2D) return null;\n\n const p = new Path2D();\n p.arc(0, 0, dotSize / 2, 0, Math.PI * 2);\n return p;\n }, [dotSize]);\n\n const buildGrid = useCallback(() => {\n const wrap = wrapperRef.current;\n const canvas = canvasRef.current;\n if (!wrap || !canvas) return;\n\n const {width, height} = wrap.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.scale(dpr, dpr);\n\n const cols = Math.floor((width + gap) / (dotSize + gap));\n const rows = Math.floor((height + gap) / (dotSize + gap));\n const cell = dotSize + gap;\n\n const gridW = cell * cols - gap;\n const gridH = cell * rows - gap;\n\n const extraX = width - gridW;\n const extraY = height - gridH;\n\n const startX = extraX / 2 + dotSize / 2;\n const startY = extraY / 2 + dotSize / 2;\n\n const dots: Dot[] = [];\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const cx = startX + x * cell;\n const cy = startY + y * cell;\n dots.push({cx, cy, xOffset: 0, yOffset: 0, _inertiaApplied: false});\n }\n }\n dotsRef.current = dots;\n }, [dotSize, gap]);\n\n useEffect(() => {\n if (!circlePath) return;\n\n let rafId: number;\n const proxSq = proximity * proximity;\n\n const draw = () => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n const {x: px, y: py} = pointerRef.current;\n\n for (const dot of dotsRef.current) {\n const ox = dot.cx + dot.xOffset;\n const oy = dot.cy + dot.yOffset;\n const dx = dot.cx - px;\n const dy = dot.cy - py;\n const dsq = dx * dx + dy * dy;\n\n let fillColor = baseColor;\n if (dsq <= proxSq) {\n const normalizedSqDist = dsq / proxSq;\n const index = Math.min(255, Math.max(0, Math.round(normalizedSqDist * 255)));\n fillColor = colorGradient[index];\n }\n\n ctx.save();\n ctx.translate(ox, oy);\n ctx.fillStyle = fillColor;\n ctx.fill(circlePath);\n ctx.restore();\n }\n\n rafId = requestAnimationFrame(draw);\n };\n\n draw();\n return () => cancelAnimationFrame(rafId);\n }, [proximity, baseColor, colorGradient, circlePath]);\n\n useEffect(() => {\n buildGrid();\n let ro: ResizeObserver | null = null;\n if ('ResizeObserver' in window) {\n ro = new ResizeObserver(buildGrid);\n wrapperRef.current && ro.observe(wrapperRef.current);\n } else {\n (window as Window).addEventListener('resize', buildGrid);\n }\n return () => {\n if (ro) ro.disconnect();\n else window.removeEventListener('resize', buildGrid);\n };\n }, [buildGrid]);\n\n useEffect(() => {\n const onMove = (e: MouseEvent) => {\n const now = performance.now();\n const pr = pointerRef.current;\n const dt = pr.lastTime ? now - pr.lastTime : 16;\n const dx = e.clientX - pr.lastX;\n const dy = e.clientY - pr.lastY;\n let vx = (dx / dt) * 1000;\n let vy = (dy / dt) * 1000;\n let speed = Math.hypot(vx, vy);\n if (speed > maxSpeed) {\n const scale = maxSpeed / speed;\n vx *= scale;\n vy *= scale;\n speed = maxSpeed;\n }\n pr.lastTime = now;\n pr.lastX = e.clientX;\n pr.lastY = e.clientY;\n pr.vx = vx;\n pr.vy = vy;\n pr.speed = speed;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n pr.x = e.clientX - rect.left;\n pr.y = e.clientY - rect.top;\n\n for (const dot of dotsRef.current) {\n const dist = Math.hypot(dot.cx - pr.x, dot.cy - pr.y);\n if (speed > speedTrigger && dist < proximity && !dot._inertiaApplied) {\n dot._inertiaApplied = true;\n gsap.killTweensOf(dot);\n const pushX = dot.cx - pr.x + vx * 0.005;\n const pushY = dot.cy - pr.y + vy * 0.005;\n gsap.to(dot, {\n inertia: {xOffset: pushX, yOffset: pushY, resistance},\n onComplete: () => {\n gsap.to(dot, {\n xOffset: 0,\n yOffset: 0,\n duration: returnDuration,\n ease: 'elastic.out(1,0.75)',\n });\n dot._inertiaApplied = false;\n },\n });\n }\n }\n };\n\n const onClick = (e: MouseEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const cx = e.clientX - rect.left;\n const cy = e.clientY - rect.top;\n for (const dot of dotsRef.current) {\n const dist = Math.hypot(dot.cx - cx, dot.cy - cy);\n if (dist < shockRadius && !dot._inertiaApplied) {\n dot._inertiaApplied = true;\n gsap.killTweensOf(dot);\n const falloff = Math.max(0, 1 - dist / shockRadius);\n const pushX = (dot.cx - cx) * shockStrength * falloff;\n const pushY = (dot.cy - cy) * shockStrength * falloff;\n gsap.to(dot, {\n inertia: {xOffset: pushX, yOffset: pushY, resistance},\n onComplete: () => {\n gsap.to(dot, {\n xOffset: 0,\n yOffset: 0,\n duration: returnDuration,\n ease: 'elastic.out(1,0.75)',\n });\n dot._inertiaApplied = false;\n },\n });\n }\n }\n };\n\n const throttledMove = throttle(onMove, 50) as (e: MouseEvent) => void;\n const wrapper = wrapperRef.current;\n if (wrapper) {\n wrapper.addEventListener('mousemove', throttledMove, {passive: true});\n wrapper.addEventListener('click', onClick);\n }\n return () => {\n if (wrapper) {\n wrapper.removeEventListener('mousemove', throttledMove);\n wrapper.removeEventListener('click', onClick);\n }\n };\n }, [maxSpeed, speedTrigger, proximity, resistance, returnDuration, shockRadius, shockStrength]);\n\n return (\n <section\n className={cn('p-4 flex items-center justify-center h-full w-full relative', className)}\n style={style}\n role=\"presentation\"\n >\n <div ref={wrapperRef} className=\"w-full h-full relative\">\n {/** biome-ignore lint/a11y/noAriaHiddenOnFocusable: <canvas is not focusable> */}\n <canvas\n ref={canvasRef}\n className=\"absolute inset-0 w-full h-full pointer-events-none\"\n aria-hidden=\"true\"\n />\n </div>\n </section>\n );\n}\n"],"names":["gsap","InertiaPlugin","useCallback","useEffect","useMemo","useRef","cn","registerPlugin","HEX_COLOR_REGEX","throttle","func","limit","lastCall","args","now","performance","hexToRgb","hex","m","match","r","g","b","parseInt","DotGrid","dotSize","gap","baseColor","activeColor","proximity","speedTrigger","shockRadius","shockStrength","maxSpeed","resistance","returnDuration","className","style","wrapperRef","canvasRef","dotsRef","pointerRef","x","y","vx","vy","speed","lastTime","lastX","lastY","baseRgb","activeRgb","colorGradient","gradient","Array","i","normalizedSqDist","normalizedDist","Math","sqrt","t","round","circlePath","window","Path2D","p","arc","PI","buildGrid","wrap","current","canvas","width","height","getBoundingClientRect","dpr","devicePixelRatio","ctx","getContext","scale","cols","floor","rows","cell","gridW","gridH","extraX","extraY","startX","startY","dots","cx","cy","push","xOffset","yOffset","_inertiaApplied","rafId","proxSq","draw","clearRect","px","py","dot","ox","oy","dx","dy","dsq","fillColor","index","min","max","save","translate","fillStyle","fill","restore","requestAnimationFrame","cancelAnimationFrame","ro","ResizeObserver","observe","addEventListener","disconnect","removeEventListener","onMove","e","pr","dt","clientX","clientY","hypot","rect","left","top","dist","killTweensOf","pushX","pushY","to","inertia","onComplete","duration","ease","onClick","falloff","throttledMove","wrapper","passive","section","role","div","ref","aria-hidden"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/dot-grid/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/dot-grid/index.ts"],"sourcesContent":["export * from './dot-grid';\n"],"names":[],"mappings":"AAAA,cAAc,aAAa"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ControllerProps, FieldPath, FieldValues } from 'react-hook-form';
|
|
3
|
+
declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>(props: import("react-hook-form").FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
|
|
4
|
+
declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare const FormItem: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
|
+
declare const FormLabel: React.ForwardRefExoticComponent<Omit<import("@radix-ui/react-label").LabelProps & React.RefAttributes<HTMLLabelElement> & import("class-variance-authority").VariantProps<(props?: import("class-variance-authority/types").ClassProp | undefined) => string>, "ref"> & React.RefAttributes<HTMLLabelElement>>;
|
|
7
|
+
declare const FormControl: React.ForwardRefExoticComponent<Omit<import("@radix-ui/react-slot").SlotProps & React.RefAttributes<HTMLElement>, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
8
|
+
declare const FormDescription: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
9
|
+
declare const FormMessage: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
10
|
+
export { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage };
|
|
11
|
+
//# sourceMappingURL=form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/components/form/form.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,eAAe,EAAE,SAAS,EAAE,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAI7E,QAAA,MAAM,IAAI,4MAAe,CAAC;AAiB1B,QAAA,MAAM,SAAS,GACb,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,cAEC,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,4CAMtC,CAAC;AA4BF,QAAA,MAAM,QAAQ,mKAUb,CAAC;AAGF,QAAA,MAAM,SAAS,gTAad,CAAC;AAGF,QAAA,MAAM,WAAW,8JAchB,CAAC;AAGF,QAAA,MAAM,eAAe,qLAiBpB,CAAC;AAGF,QAAA,MAAM,WAAW,qLAoBhB,CAAC;AAGF,OAAO,EAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { Label } from '../../components/label/index.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { Controller, FormProvider, useFormContext } from 'react-hook-form';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
const Form = FormProvider;
|
|
8
|
+
const FormFieldContext = /*#__PURE__*/ React.createContext(null);
|
|
9
|
+
const FormItemContext = /*#__PURE__*/ React.createContext(null);
|
|
10
|
+
const FormField = ({ ...props })=>{
|
|
11
|
+
return /*#__PURE__*/ _jsx(FormFieldContext.Provider, {
|
|
12
|
+
value: {
|
|
13
|
+
name: props.name
|
|
14
|
+
},
|
|
15
|
+
children: /*#__PURE__*/ _jsx(Controller, {
|
|
16
|
+
...props
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
const useFormField = ()=>{
|
|
21
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
22
|
+
const itemContext = React.useContext(FormItemContext);
|
|
23
|
+
const { getFieldState, formState } = useFormContext();
|
|
24
|
+
if (!fieldContext) {
|
|
25
|
+
throw new Error('useFormField should be used within <FormField>');
|
|
26
|
+
}
|
|
27
|
+
if (!itemContext) {
|
|
28
|
+
throw new Error('useFormField should be used within <FormItem>');
|
|
29
|
+
}
|
|
30
|
+
const fieldState = getFieldState(fieldContext.name, formState);
|
|
31
|
+
const { id } = itemContext;
|
|
32
|
+
return {
|
|
33
|
+
id,
|
|
34
|
+
name: fieldContext.name,
|
|
35
|
+
formItemId: `${id}-form-item`,
|
|
36
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
37
|
+
formMessageId: `${id}-form-item-message`,
|
|
38
|
+
...fieldState
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const FormItem = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>{
|
|
42
|
+
const id = React.useId();
|
|
43
|
+
return /*#__PURE__*/ _jsx(FormItemContext.Provider, {
|
|
44
|
+
value: {
|
|
45
|
+
id
|
|
46
|
+
},
|
|
47
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
48
|
+
ref: ref,
|
|
49
|
+
className: className,
|
|
50
|
+
...props
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
FormItem.displayName = 'FormItem';
|
|
55
|
+
const FormLabel = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>{
|
|
56
|
+
const { error, formItemId } = useFormField();
|
|
57
|
+
return /*#__PURE__*/ _jsx(Label, {
|
|
58
|
+
ref: ref,
|
|
59
|
+
className: cn(error && 'text-foreground-error', className),
|
|
60
|
+
htmlFor: formItemId,
|
|
61
|
+
...props
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
FormLabel.displayName = 'FormLabel';
|
|
65
|
+
const FormControl = /*#__PURE__*/ React.forwardRef(({ ...props }, ref)=>{
|
|
66
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
67
|
+
return /*#__PURE__*/ _jsx(Slot, {
|
|
68
|
+
ref: ref,
|
|
69
|
+
id: formItemId,
|
|
70
|
+
"aria-describedby": error ? formMessageId : formDescriptionId,
|
|
71
|
+
"aria-invalid": !!error,
|
|
72
|
+
...props
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
FormControl.displayName = 'FormControl';
|
|
76
|
+
const FormDescription = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>{
|
|
77
|
+
const { error, formDescriptionId } = useFormField();
|
|
78
|
+
if (error) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return /*#__PURE__*/ _jsx("p", {
|
|
82
|
+
ref: ref,
|
|
83
|
+
id: formDescriptionId,
|
|
84
|
+
className: cn('text-sm text-foreground-neutral-muted', className),
|
|
85
|
+
...props
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
FormDescription.displayName = 'FormDescription';
|
|
89
|
+
const FormMessage = /*#__PURE__*/ React.forwardRef(({ className, children, ...props }, ref)=>{
|
|
90
|
+
const { error, formMessageId } = useFormField();
|
|
91
|
+
const body = error ? String(error?.message ?? '') : children;
|
|
92
|
+
if (!body) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return /*#__PURE__*/ _jsx("p", {
|
|
96
|
+
ref: ref,
|
|
97
|
+
id: formMessageId,
|
|
98
|
+
className: cn('text-sm font-medium text-foreground-highlight-error', className),
|
|
99
|
+
...props,
|
|
100
|
+
children: body
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
FormMessage.displayName = 'FormMessage';
|
|
104
|
+
export { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage };
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/form/form.tsx"],"sourcesContent":["import {Slot} from '@radix-ui/react-slot';\nimport {Label} from 'components/label';\nimport type {ComponentProps} from 'react';\nimport * as React from 'react';\nimport type {ControllerProps, FieldPath, FieldValues} from 'react-hook-form';\nimport {Controller, FormProvider, useFormContext} from 'react-hook-form';\nimport {cn} from 'utils/cn';\n\nconst Form = FormProvider;\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName;\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue | null>(null);\n\nconst FormItemContext = React.createContext<FormItemContextValue | null>(null);\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{name: props.name}}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n};\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const {getFieldState, formState} = useFormContext();\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within <FormField>');\n }\n\n if (!itemContext) {\n throw new Error('useFormField should be used within <FormItem>');\n }\n\n const fieldState = getFieldState(fieldContext.name, formState);\n const {id} = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\nconst FormItem = React.forwardRef<HTMLDivElement, ComponentProps<'div'>>(\n ({className, ...props}, ref) => {\n const id = React.useId();\n\n return (\n <FormItemContext.Provider value={{id}}>\n <div ref={ref} className={className} {...props} />\n </FormItemContext.Provider>\n );\n },\n);\nFormItem.displayName = 'FormItem';\n\nconst FormLabel = React.forwardRef<React.ElementRef<typeof Label>, ComponentProps<typeof Label>>(\n ({className, ...props}, ref) => {\n const {error, formItemId} = useFormField();\n\n return (\n <Label\n ref={ref}\n className={cn(error && 'text-foreground-error', className)}\n htmlFor={formItemId}\n {...props}\n />\n );\n },\n);\nFormLabel.displayName = 'FormLabel';\n\nconst FormControl = React.forwardRef<React.ElementRef<typeof Slot>, ComponentProps<typeof Slot>>(\n ({...props}, ref) => {\n const {error, formItemId, formDescriptionId, formMessageId} = useFormField();\n\n return (\n <Slot\n ref={ref}\n id={formItemId}\n aria-describedby={error ? formMessageId : formDescriptionId}\n aria-invalid={!!error}\n {...props}\n />\n );\n },\n);\nFormControl.displayName = 'FormControl';\n\nconst FormDescription = React.forwardRef<HTMLParagraphElement, ComponentProps<'p'>>(\n ({className, ...props}, ref) => {\n const {error, formDescriptionId} = useFormField();\n\n if (error) {\n return null;\n }\n\n return (\n <p\n ref={ref}\n id={formDescriptionId}\n className={cn('text-sm text-foreground-neutral-muted', className)}\n {...props}\n />\n );\n },\n);\nFormDescription.displayName = 'FormDescription';\n\nconst FormMessage = React.forwardRef<HTMLParagraphElement, ComponentProps<'p'>>(\n ({className, children, ...props}, ref) => {\n const {error, formMessageId} = useFormField();\n const body = error ? String(error?.message ?? '') : children;\n\n if (!body) {\n return null;\n }\n\n return (\n <p\n ref={ref}\n id={formMessageId}\n className={cn('text-sm font-medium text-foreground-highlight-error', className)}\n {...props}\n >\n {body}\n </p>\n );\n },\n);\nFormMessage.displayName = 'FormMessage';\n\nexport {Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage};\n"],"names":["Slot","Label","React","Controller","FormProvider","useFormContext","cn","Form","FormFieldContext","createContext","FormItemContext","FormField","props","Provider","value","name","useFormField","fieldContext","useContext","itemContext","getFieldState","formState","Error","fieldState","id","formItemId","formDescriptionId","formMessageId","FormItem","forwardRef","className","ref","useId","div","displayName","FormLabel","error","htmlFor","FormControl","aria-describedby","aria-invalid","FormDescription","p","FormMessage","children","body","String","message"],"mappings":"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"}
|