@playfast/reform-better-hub-ui-primitives 0.2.1 → 0.3.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/README.md +9 -9
- package/package.json +23 -23
- package/src/components/agent-icon.tsx +16 -19
- package/src/components/autocomplete.tsx +193 -0
- package/src/components/badge.tsx +46 -47
- package/src/components/button.tsx +56 -65
- package/src/components/combobox.tsx +233 -231
- package/src/components/command.tsx +135 -142
- package/src/components/dialog.tsx +106 -101
- package/src/components/dropdown-menu.tsx +118 -118
- package/src/components/github-background.tsx +224 -239
- package/src/components/halftone-background.tsx +164 -176
- package/src/components/halftone-config.ts +14 -0
- package/src/components/input-group.tsx +152 -159
- package/src/components/input.tsx +17 -20
- package/src/components/live-duration.tsx +71 -72
- package/src/components/logo.tsx +9 -15
- package/src/components/popover.tsx +60 -65
- package/src/components/resize-handle.tsx +73 -87
- package/src/components/sheet.tsx +120 -115
- package/src/components/textarea.tsx +15 -17
- package/src/components/time-ago.tsx +64 -66
- package/src/components/tooltip.tsx +48 -45
- package/src/foundation/cn.ts +0 -4
- package/src/foundation/styles.css +6 -4
- package/src/index.ts +21 -24
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import type * as React from 'react'
|
|
2
|
+
import { useEffect, useRef } from 'react'
|
|
3
|
+
import {
|
|
4
|
+
CLICK_DECAY,
|
|
5
|
+
FULLSCREEN_VERTEX_COUNT,
|
|
6
|
+
MOUSE_LERP,
|
|
7
|
+
MOUSE_LERP_IDLE,
|
|
8
|
+
MS_PER_SECOND,
|
|
9
|
+
RENDER_SCALE,
|
|
10
|
+
type ShaderSpec,
|
|
11
|
+
VERTEX_SHADER,
|
|
12
|
+
} from './halftone-config'
|
|
12
13
|
|
|
13
14
|
const FRAGMENT_SHADER = `
|
|
14
15
|
precision highp float;
|
|
@@ -77,7 +78,6 @@ void main() {
|
|
|
77
78
|
|
|
78
79
|
vec2 ap = vec2(uv.x * aspect, uv.y);
|
|
79
80
|
|
|
80
|
-
// ═══ SHARED MOUSE WARP ═══
|
|
81
81
|
vec2 scaledP = ap * 2.5;
|
|
82
82
|
vec2 mUV = u_mouse;
|
|
83
83
|
mUV.x *= aspect;
|
|
@@ -97,7 +97,6 @@ void main() {
|
|
|
97
97
|
warp += normalize(cD + 0.001) * sin(cDist * 12.0 - time * 8.0) * u_click * 0.4 * exp(-cDist * 2.0);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
// ═══ NOISE LAYER ═══
|
|
101
100
|
vec2 np = scaledP + warp;
|
|
102
101
|
vec2 q = vec2(fbm(np + t * 0.3), fbm(np + vec2(5.2, 1.3) + t * 0.2));
|
|
103
102
|
vec2 r = vec2(
|
|
@@ -107,7 +106,6 @@ void main() {
|
|
|
107
106
|
float f = fbm(np + 4.0 * r);
|
|
108
107
|
float noise = clamp(f*f*f + 0.6*f*f + 0.5*f, 0.0, 1.0) * 0.15;
|
|
109
108
|
|
|
110
|
-
// ═══ CONTRIBUTION GRID ═══
|
|
111
109
|
vec2 gp = ap;
|
|
112
110
|
gp += vec2(snoise(ap * 3.0 + t), snoise(ap * 3.0 + t + 50.0)) * 0.004;
|
|
113
111
|
gp += warp * 0.04;
|
|
@@ -135,173 +133,163 @@ void main() {
|
|
|
135
133
|
float gridReveal = smoothstep(0.5, 3.0, time);
|
|
136
134
|
float grid = inSquare * level * gFade * gridReveal * 0.10;
|
|
137
135
|
|
|
138
|
-
// ═══ COMPOSE ═══
|
|
139
136
|
vec2 vc = uv - 0.5;
|
|
140
137
|
float vignette = 1.0 - dot(vc, vc) * 0.3;
|
|
141
138
|
|
|
142
139
|
float col = noise * vignette + grid;
|
|
143
140
|
gl_FragColor = vec4(vec3(col), 1.0);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const RENDER_SCALE = 0.5;
|
|
147
|
-
const MS_PER_SECOND = 1000;
|
|
148
|
-
const MOUSE_LERP = 0.08;
|
|
149
|
-
const MOUSE_LERP_IDLE = 0.02;
|
|
150
|
-
const CLICK_DECAY = 0.96;
|
|
151
|
-
const FULLSCREEN_VERTEX_COUNT = 6;
|
|
152
|
-
|
|
153
|
-
type ShaderSpec = { readonly type: number; readonly source: string };
|
|
141
|
+
}`
|
|
154
142
|
|
|
155
143
|
export function HalftoneBackground(): React.JSX.Element {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
144
|
+
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
145
|
+
const wrapperRef = useRef<HTMLDivElement>(null)
|
|
146
|
+
const frameRef = useRef<number>(0)
|
|
147
|
+
const mouseRef = useRef({ x: -1, y: -1 })
|
|
148
|
+
const smoothMouseRef = useRef({ x: -1, y: -1 })
|
|
149
|
+
const clickRef = useRef({ strength: 0, x: 0, y: 0 })
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
const canvas = canvasRef.current
|
|
153
|
+
const wrapper = wrapperRef.current
|
|
154
|
+
if (!canvas || !wrapper) {
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const glContext = canvas.getContext('webgl', {
|
|
159
|
+
alpha: false,
|
|
160
|
+
antialias: false,
|
|
161
|
+
preserveDrawingBuffer: false,
|
|
162
|
+
})
|
|
163
|
+
if (!glContext) {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const createShader = ({ type, source }: ShaderSpec) => {
|
|
168
|
+
const shader = glContext!.createShader(type)!
|
|
169
|
+
glContext!.shaderSource(shader, source)
|
|
170
|
+
glContext!.compileShader(shader)
|
|
171
|
+
return shader
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const vertexShader = createShader({
|
|
175
|
+
type: glContext.VERTEX_SHADER,
|
|
176
|
+
source: VERTEX_SHADER,
|
|
177
|
+
})
|
|
178
|
+
const fragmentShader = createShader({
|
|
179
|
+
type: glContext.FRAGMENT_SHADER,
|
|
180
|
+
source: FRAGMENT_SHADER,
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
const program = glContext.createProgram()!
|
|
184
|
+
glContext.attachShader(program, vertexShader)
|
|
185
|
+
glContext.attachShader(program, fragmentShader)
|
|
186
|
+
glContext.linkProgram(program)
|
|
187
|
+
glContext.useProgram(program)
|
|
188
|
+
|
|
189
|
+
const buffer = glContext.createBuffer()
|
|
190
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, buffer)
|
|
191
|
+
glContext.bufferData(
|
|
192
|
+
glContext.ARRAY_BUFFER,
|
|
193
|
+
new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),
|
|
194
|
+
glContext.STATIC_DRAW,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
const aPosition = glContext.getAttribLocation(program, 'a_position')
|
|
198
|
+
glContext.enableVertexAttribArray(aPosition)
|
|
199
|
+
glContext.vertexAttribPointer(aPosition, 2, glContext.FLOAT, false, 0, 0)
|
|
200
|
+
|
|
201
|
+
const uTime = glContext.getUniformLocation(program, 'u_time')
|
|
202
|
+
const uResolution = glContext.getUniformLocation(program, 'u_resolution')
|
|
203
|
+
const uMouse = glContext.getUniformLocation(program, 'u_mouse')
|
|
204
|
+
const uClick = glContext.getUniformLocation(program, 'u_click')
|
|
205
|
+
const uClickPos = glContext.getUniformLocation(program, 'u_clickPos')
|
|
206
|
+
|
|
207
|
+
const startTime = performance.now()
|
|
208
|
+
|
|
209
|
+
const resize = () => {
|
|
210
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2)
|
|
211
|
+
const scale = RENDER_SCALE * dpr
|
|
212
|
+
canvas.width = canvas.offsetWidth * scale
|
|
213
|
+
canvas.height = canvas.offsetHeight * scale
|
|
214
|
+
glContext.viewport(0, 0, canvas.width, canvas.height)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
resize()
|
|
218
|
+
window.addEventListener('resize', resize)
|
|
219
|
+
|
|
220
|
+
const onMouseMove = (event: MouseEvent) => {
|
|
221
|
+
const rect = wrapper.getBoundingClientRect()
|
|
222
|
+
mouseRef.current.x = (event.clientX - rect.left) / rect.width
|
|
223
|
+
mouseRef.current.y = 1.0 - (event.clientY - rect.top) / rect.height
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const onMouseLeave = () => {
|
|
227
|
+
mouseRef.current.x = -1
|
|
228
|
+
mouseRef.current.y = -1
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const onClick = (event: MouseEvent) => {
|
|
232
|
+
const rect = wrapper.getBoundingClientRect()
|
|
233
|
+
clickRef.current.x = (event.clientX - rect.left) / rect.width
|
|
234
|
+
clickRef.current.y = 1.0 - (event.clientY - rect.top) / rect.height
|
|
235
|
+
clickRef.current.strength = 1.0
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
window.addEventListener('mousemove', onMouseMove, { passive: true })
|
|
239
|
+
wrapper.addEventListener('mouseleave', onMouseLeave)
|
|
240
|
+
wrapper.addEventListener('click', onClick)
|
|
241
|
+
|
|
242
|
+
const draw = () => {
|
|
243
|
+
const elapsed = (performance.now() - startTime) / MS_PER_SECOND
|
|
244
|
+
|
|
245
|
+
const target = mouseRef.current
|
|
246
|
+
const smooth = smoothMouseRef.current
|
|
247
|
+
if (target.x < 0) {
|
|
248
|
+
smooth.x += (target.x - smooth.x) * MOUSE_LERP_IDLE
|
|
249
|
+
smooth.y += (target.y - smooth.y) * MOUSE_LERP_IDLE
|
|
250
|
+
} else {
|
|
251
|
+
smooth.x += (target.x - smooth.x) * MOUSE_LERP
|
|
252
|
+
smooth.y += (target.y - smooth.y) * MOUSE_LERP
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
clickRef.current.strength *= CLICK_DECAY
|
|
256
|
+
|
|
257
|
+
glContext.uniform1f(uTime, elapsed)
|
|
258
|
+
glContext.uniform2f(uResolution, canvas.width, canvas.height)
|
|
259
|
+
glContext.uniform2f(uMouse, smooth.x, smooth.y)
|
|
260
|
+
glContext.uniform1f(uClick, clickRef.current.strength)
|
|
261
|
+
glContext.uniform2f(uClickPos, clickRef.current.x, clickRef.current.y)
|
|
262
|
+
glContext.drawArrays(glContext.TRIANGLES, 0, FULLSCREEN_VERTEX_COUNT)
|
|
263
|
+
frameRef.current = requestAnimationFrame(draw)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
frameRef.current = requestAnimationFrame(draw)
|
|
267
|
+
|
|
268
|
+
return () => {
|
|
269
|
+
cancelAnimationFrame(frameRef.current)
|
|
270
|
+
window.removeEventListener('resize', resize)
|
|
271
|
+
window.removeEventListener('mousemove', onMouseMove)
|
|
272
|
+
wrapper.removeEventListener('mouseleave', onMouseLeave)
|
|
273
|
+
wrapper.removeEventListener('click', onClick)
|
|
274
|
+
glContext.deleteProgram(program)
|
|
275
|
+
glContext.deleteShader(vertexShader)
|
|
276
|
+
glContext.deleteShader(fragmentShader)
|
|
277
|
+
glContext.deleteBuffer(buffer)
|
|
278
|
+
}
|
|
279
|
+
}, [])
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div
|
|
283
|
+
ref={wrapperRef}
|
|
284
|
+
className="absolute inset-0 overflow-hidden"
|
|
285
|
+
style={{ background: 'var(--shader-bg)' }}
|
|
286
|
+
aria-hidden="true"
|
|
287
|
+
>
|
|
288
|
+
<canvas
|
|
289
|
+
ref={canvasRef}
|
|
290
|
+
className="w-full h-full"
|
|
291
|
+
style={{ filter: 'var(--shader-filter)' }}
|
|
292
|
+
/>
|
|
293
|
+
</div>
|
|
294
|
+
)
|
|
307
295
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const VERTEX_SHADER = `
|
|
2
|
+
attribute vec2 a_position;
|
|
3
|
+
void main() {
|
|
4
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
5
|
+
}`
|
|
6
|
+
|
|
7
|
+
export const RENDER_SCALE = 0.5
|
|
8
|
+
export const MS_PER_SECOND = 1000
|
|
9
|
+
export const MOUSE_LERP = 0.08
|
|
10
|
+
export const MOUSE_LERP_IDLE = 0.02
|
|
11
|
+
export const CLICK_DECAY = 0.96
|
|
12
|
+
export const FULLSCREEN_VERTEX_COUNT = 6
|
|
13
|
+
|
|
14
|
+
export type ShaderSpec = { readonly type: number; readonly source: string }
|