@flikk/ui 1.0.0-beta.12 → 1.0.0-beta.13
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/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +7 -7
- package/dist/components/core/Accordion/Accordion.types.d.ts +1 -7
- package/dist/components/core/Accordion/AccordionTrigger.js +4 -6
- package/dist/components/core/Alert/Alert.types.d.ts +1 -1
- package/dist/components/core/Avatar/Avatar.js +22 -18
- package/dist/components/core/Avatar/Avatar.theme.js +1 -1
- package/dist/components/core/Avatar/Avatar.types.d.ts +9 -8
- package/dist/components/core/AvatarGroup/AvatarGroup.js +2 -2
- package/dist/components/core/Badge/Badge.js +7 -5
- package/dist/components/core/Badge/Badge.theme.js +11 -4
- package/dist/components/core/Badge/Badge.types.d.ts +2 -2
- package/dist/components/core/Button/Button.theme.js +2 -2
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +5 -6
- package/dist/components/core/FileTypeIcon/FileTypeIcon.d.ts +3 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.js +33 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.d.ts +2 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.js +12 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.types.d.ts +19 -0
- package/dist/components/core/FileTypeIcon/fileTypes.d.ts +7 -0
- package/dist/components/core/FileTypeIcon/fileTypes.js +30 -0
- package/dist/components/core/FileTypeIcon/index.d.ts +2 -0
- package/dist/components/core/MenuItem/MenuItem.theme.js +1 -1
- package/dist/components/core/Message/Message.js +1 -1
- package/dist/components/core/Message/Message.theme.js +2 -2
- package/dist/components/core/Message/Message.types.d.ts +6 -6
- package/dist/components/core/Message/MessageAvatar.d.ts +2 -2
- package/dist/components/core/Message/MessageAvatar.js +3 -3
- package/dist/components/core/Popover/PopoverBody.js +19 -8
- package/dist/components/core/Tag/Tag.d.ts +1 -1
- package/dist/components/core/Tag/Tag.js +2 -2
- package/dist/components/core/Tag/Tag.types.d.ts +1 -1
- package/dist/components/core/index.d.ts +1 -1
- package/dist/components/core/index.js +1 -1
- package/dist/components/data-display/Feed/Feed.animations.d.ts +40 -0
- package/dist/components/data-display/Feed/Feed.animations.js +26 -0
- package/dist/components/data-display/Feed/Feed.d.ts +5 -1
- package/dist/components/data-display/Feed/Feed.js +87 -60
- package/dist/components/data-display/Feed/Feed.theme.js +11 -13
- package/dist/components/data-display/Feed/Feed.types.d.ts +35 -34
- package/dist/components/data-display/Feed/index.d.ts +1 -1
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +11 -9
- package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
- package/dist/components/effects/3d/index.d.ts +1 -1
- package/dist/components/effects/AIOrb/AIOrb.d.ts +1 -0
- package/dist/components/effects/AIOrb/AIOrb.js +3 -2
- package/dist/components/effects/AIOrb/AIOrb.types.d.ts +1 -0
- package/dist/components/effects/AIOrb/hooks/index.d.ts +2 -0
- package/dist/components/effects/AIOrb/hooks/useOrbState.d.ts +20 -0
- package/dist/components/effects/AIOrb/hooks/useOrbState.js +27 -0
- package/dist/components/effects/AIOrb/index.d.ts +2 -2
- package/dist/components/effects/AIOrb/variants/Aura/Aura.d.ts +3 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.js +75 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.d.ts +28 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.js +191 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.types.d.ts +53 -0
- package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.d.ts +17 -0
- package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.js +149 -0
- package/dist/components/effects/AIOrb/variants/Aura/index.d.ts +2 -0
- package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.js +38 -7
- package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.types.d.ts +6 -0
- package/dist/components/effects/AIOrb/variants/Liquid/Liquid.js +34 -8
- package/dist/components/effects/AIOrb/variants/Liquid/Liquid.types.d.ts +6 -0
- package/dist/components/effects/AIOrb/variants/index.d.ts +2 -0
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.js +50 -47
- package/dist/components/effects/GlassSurface/GlassSurface.js +24 -12
- package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +8 -0
- package/dist/components/forms/Mention/Mention.js +2 -2
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/paletteGenerator.d.ts +46 -0
- package/package.json +1 -1
- package/src/styles/theme.css +2 -6
- package/dist/components/core/Loader/Loader.d.ts +0 -24
- package/dist/components/core/Loader/Loader.js +0 -57
- package/dist/components/core/Loader/Loader.theme.d.ts +0 -27
- package/dist/components/core/Loader/Loader.theme.js +0 -60
- package/dist/components/core/Loader/Loader.types.d.ts +0 -71
- package/dist/components/core/Loader/index.d.ts +0 -2
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useRef, useMemo, useEffect } from 'react';
|
|
3
3
|
import { Canvas, useFrame } from '@react-three/fiber';
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, OneFactor, ZeroFactor, AddEquation, CustomBlending, BackSide } from 'three';
|
|
5
5
|
import { waveFragment, waveVertex, dotSphereFragment, dotSphereVertex, glowFragment, glowVertex } from './DotSphere.shaders.js';
|
|
6
|
+
import { useOrbState } from '../../hooks/useOrbState.js';
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
+
const STATE_CONFIG = {
|
|
9
|
+
idle: { speed: 0.3, glowIntensity: 0.6, rimIntensity: 1.0 },
|
|
10
|
+
listening: { speed: 0.6, glowIntensity: 1.0, rimIntensity: 1.5 },
|
|
11
|
+
thinking: { speed: 1.2, glowIntensity: 1.4, rimIntensity: 2.0 },
|
|
12
|
+
speaking: { speed: 0.8, glowIntensity: 1.2, rimIntensity: 1.8 },
|
|
13
|
+
};
|
|
14
|
+
const OrbScene = ({ colors, speed, gridDensity, dotSize, rimIntensity, glowIntensity, glowSize, state, }) => {
|
|
8
15
|
const groupRef = useRef(null);
|
|
9
16
|
const dotMatRef = useRef(null);
|
|
10
17
|
const innerGlowRef = useRef(null);
|
|
@@ -74,6 +81,9 @@ const OrbScene = ({ colors, speed, gridDensity, dotSize, rimIntensity, glowInten
|
|
|
74
81
|
}),
|
|
75
82
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
83
|
[]);
|
|
84
|
+
// ── State-driven interpolation ─────────────────────────────────────────
|
|
85
|
+
const stateProps = useMemo(() => ({ speed, glowIntensity, rimIntensity }), [speed, glowIntensity, rimIntensity]);
|
|
86
|
+
const { valuesRef: stateRef, tick: stateTick } = useOrbState(state, STATE_CONFIG, stateProps);
|
|
77
87
|
// ── Sync prop changes → uniforms ──────────────────────────────────────
|
|
78
88
|
useEffect(() => {
|
|
79
89
|
// Dot sphere
|
|
@@ -108,8 +118,21 @@ const OrbScene = ({ colors, speed, gridDensity, dotSize, rimIntensity, glowInten
|
|
|
108
118
|
}
|
|
109
119
|
}, [colorObjs, dotSize, gridDensity, rimIntensity, glowIntensity]);
|
|
110
120
|
// ── Animation loop ────────────────────────────────────────────────────
|
|
111
|
-
useFrame(({ clock }) => {
|
|
112
|
-
|
|
121
|
+
useFrame(({ clock }, delta) => {
|
|
122
|
+
// Tick state interpolation
|
|
123
|
+
stateTick(delta);
|
|
124
|
+
const sv = stateRef.current;
|
|
125
|
+
const t = clock.getElapsedTime() * sv.speed;
|
|
126
|
+
// Sync interpolated rimIntensity / glowIntensity into uniforms
|
|
127
|
+
if (dotMatRef.current) {
|
|
128
|
+
dotMatRef.current.uniforms.u_rimIntensity.value = sv.rimIntensity;
|
|
129
|
+
}
|
|
130
|
+
if (innerGlowRef.current) {
|
|
131
|
+
innerGlowRef.current.uniforms.u_intensity.value = sv.glowIntensity * 0.8;
|
|
132
|
+
}
|
|
133
|
+
if (outerGlowRef.current) {
|
|
134
|
+
outerGlowRef.current.uniforms.u_intensity.value = sv.glowIntensity * 0.55;
|
|
135
|
+
}
|
|
113
136
|
// Update time uniform on every material
|
|
114
137
|
for (const ref of [
|
|
115
138
|
dotMatRef,
|
|
@@ -125,12 +148,20 @@ const OrbScene = ({ colors, speed, gridDensity, dotSize, rimIntensity, glowInten
|
|
|
125
148
|
groupRef.current.rotation.y = clock.getElapsedTime() * 0.12;
|
|
126
149
|
}
|
|
127
150
|
});
|
|
128
|
-
return (jsxs("group", { ref: groupRef, children: [jsxs("mesh", { scale: 0.85, children: [jsx("sphereGeometry", { args: [1, 48, 48] }), jsx("shaderMaterial", { ref: waveDeepRef, vertexShader: waveVertex, fragmentShader: waveFragment, uniforms: waveDeepUniforms, transparent: true,
|
|
151
|
+
return (jsxs("group", { ref: groupRef, children: [jsxs("mesh", { scale: 0.85, children: [jsx("sphereGeometry", { args: [1, 48, 48] }), jsx("shaderMaterial", { ref: waveDeepRef, vertexShader: waveVertex, fragmentShader: waveFragment, uniforms: waveDeepUniforms, transparent: true, depthWrite: false })] }), jsxs("mesh", { scale: 0.96, children: [jsx("sphereGeometry", { args: [1, 48, 48] }), jsx("shaderMaterial", { ref: waveSurfaceRef, vertexShader: waveVertex, fragmentShader: waveFragment, uniforms: waveSurfaceUniforms, transparent: true, depthWrite: false })] }), jsxs("mesh", { children: [jsx("sphereGeometry", { args: [1, 64, 64] }), jsx("shaderMaterial", { ref: dotMatRef, vertexShader: dotSphereVertex, fragmentShader: dotSphereFragment, uniforms: dotUniforms, transparent: true, depthWrite: false })] }), jsxs("mesh", { scale: 1.12, children: [jsx("sphereGeometry", { args: [1, 32, 32] }), jsx("shaderMaterial", { ref: innerGlowRef, vertexShader: glowVertex, fragmentShader: glowFragment, uniforms: innerGlowUniforms, transparent: true, side: BackSide, blending: CustomBlending, blendEquation: AddEquation, blendSrc: OneFactor, blendDst: OneFactor, blendSrcAlpha: ZeroFactor, blendDstAlpha: OneFactor, depthWrite: false })] }), jsxs("mesh", { scale: glowSize, children: [jsx("sphereGeometry", { args: [1, 32, 32] }), jsx("shaderMaterial", { ref: outerGlowRef, vertexShader: glowVertex, fragmentShader: glowFragment, uniforms: outerGlowUniforms, transparent: true, side: BackSide, blending: CustomBlending, blendEquation: AddEquation, blendSrc: OneFactor, blendDst: OneFactor, blendSrcAlpha: ZeroFactor, blendDstAlpha: OneFactor, depthWrite: false })] })] }));
|
|
129
152
|
};
|
|
130
153
|
// ── Public DotSphere variant ─────────────────────────────────────────────────
|
|
131
154
|
const DEFAULT_COLORS = ["#00d2ff", "#a855f7", "#f97316"];
|
|
132
|
-
const DotSphere = ({ colors = DEFAULT_COLORS, speed = 0.6, gridDensity = 40, dotSize = 0.055, rimIntensity = 1.5, glowIntensity = 1.0, glowSize = 1.5, }) => {
|
|
133
|
-
return (jsx(Canvas, { className: "!absolute inset-0 w-full h-full",
|
|
155
|
+
const DotSphere = ({ colors = DEFAULT_COLORS, speed = 0.6, gridDensity = 40, dotSize = 0.055, rimIntensity = 1.5, glowIntensity = 1.0, glowSize = 1.5, state, }) => {
|
|
156
|
+
return (jsx(Canvas, { className: "!absolute inset-0 w-full h-full", style: {
|
|
157
|
+
filter: [
|
|
158
|
+
'drop-shadow(0 0 10px rgba(168, 85, 247, 0.7))',
|
|
159
|
+
'drop-shadow(0 0 25px rgba(147, 51, 234, 0.35))',
|
|
160
|
+
'drop-shadow(0 0 50px rgba(124, 58, 237, 0.15))',
|
|
161
|
+
].join(' '),
|
|
162
|
+
}, dpr: [1, 2], camera: { position: [0, 0, 3], fov: 50 }, gl: { antialias: true, alpha: true, premultipliedAlpha: false }, onCreated: ({ gl }) => {
|
|
163
|
+
gl.setClearColor(0x000000, 0);
|
|
164
|
+
}, children: jsx(OrbScene, { colors: colors, speed: speed, gridDensity: gridDensity, dotSize: dotSize, rimIntensity: rimIntensity, glowIntensity: glowIntensity, glowSize: glowSize, state: state }) }));
|
|
134
165
|
};
|
|
135
166
|
|
|
136
167
|
export { DotSphere };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OrbState } from "../../AIOrb.types";
|
|
1
2
|
export interface DotSphereProps {
|
|
2
3
|
/**
|
|
3
4
|
* Three gradient colours [top, middle, bottom] as hex strings.
|
|
@@ -34,4 +35,9 @@ export interface DotSphereProps {
|
|
|
34
35
|
* @default 1.5
|
|
35
36
|
*/
|
|
36
37
|
glowSize?: number;
|
|
38
|
+
/**
|
|
39
|
+
* State-driven animation. When set, smoothly interpolates speed,
|
|
40
|
+
* glowIntensity, and rimIntensity towards state targets.
|
|
41
|
+
*/
|
|
42
|
+
state?: OrbState;
|
|
37
43
|
}
|
|
@@ -2,11 +2,18 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useRef, useMemo, useEffect } from 'react';
|
|
3
3
|
import { Canvas, useFrame } from '@react-three/fiber';
|
|
4
4
|
import { Environment } from '@react-three/drei';
|
|
5
|
-
import { ACESFilmicToneMapping, Color,
|
|
5
|
+
import { ACESFilmicToneMapping, Color, OneFactor, ZeroFactor, AddEquation, CustomBlending, BackSide } from 'three';
|
|
6
6
|
import { simplex3 } from './Liquid.noise.js';
|
|
7
7
|
import { atmosphereFragment, glowVertex } from './Liquid.shaders.js';
|
|
8
|
+
import { useOrbState } from '../../hooks/useOrbState.js';
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
+
const STATE_CONFIG = {
|
|
11
|
+
idle: { speed: 0.5, noiseAmplitude: 0.06, glowIntensity: 0.6 },
|
|
12
|
+
listening: { speed: 1.0, noiseAmplitude: 0.1, glowIntensity: 1.0 },
|
|
13
|
+
thinking: { speed: 1.8, noiseAmplitude: 0.15, glowIntensity: 1.4 },
|
|
14
|
+
speaking: { speed: 1.2, noiseAmplitude: 0.12, glowIntensity: 1.2 },
|
|
15
|
+
};
|
|
16
|
+
const LiquidScene = ({ colors, meshColor, speed, roughness, metalness, noiseScale, noiseAmplitude, glowIntensity, glowSize, state, }) => {
|
|
10
17
|
const groupRef = useRef(null);
|
|
11
18
|
const meshRef = useRef(null);
|
|
12
19
|
const atmosphereRef = useRef(null);
|
|
@@ -15,6 +22,9 @@ const LiquidScene = ({ colors, meshColor, speed, roughness, metalness, noiseScal
|
|
|
15
22
|
// Keep latest props in a ref so useFrame always reads current values
|
|
16
23
|
const propsRef = useRef({ speed, noiseScale, noiseAmplitude });
|
|
17
24
|
propsRef.current = { speed, noiseScale, noiseAmplitude };
|
|
25
|
+
// ── State-driven interpolation ─────────────────────────────────────────
|
|
26
|
+
const stateProps = useMemo(() => ({ speed, noiseAmplitude, glowIntensity }), [speed, noiseAmplitude, glowIntensity]);
|
|
27
|
+
const { valuesRef: stateRef, tick: stateTick } = useOrbState(state, STATE_CONFIG, stateProps);
|
|
18
28
|
// Colour objects (rebuilt only when hex strings change)
|
|
19
29
|
const [c1, c2, c3] = colors;
|
|
20
30
|
const colorObjs = useMemo(() => ({
|
|
@@ -59,9 +69,18 @@ const LiquidScene = ({ colors, meshColor, speed, roughness, metalness, noiseScal
|
|
|
59
69
|
}
|
|
60
70
|
}, [colorObjs, meshColor, roughness, metalness, glowIntensity]);
|
|
61
71
|
// ── Animation loop ──────────────────────────────────────────────────────
|
|
62
|
-
useFrame(({ clock }) => {
|
|
72
|
+
useFrame(({ clock }, delta) => {
|
|
73
|
+
// Tick state interpolation
|
|
74
|
+
stateTick(delta);
|
|
75
|
+
const sv = stateRef.current;
|
|
63
76
|
const t = clock.getElapsedTime();
|
|
64
|
-
const
|
|
77
|
+
const spd = sv.speed;
|
|
78
|
+
const na = sv.noiseAmplitude;
|
|
79
|
+
const ns = propsRef.current.noiseScale;
|
|
80
|
+
// Sync interpolated glowIntensity into atmosphere uniform
|
|
81
|
+
if (atmosphereRef.current) {
|
|
82
|
+
atmosphereRef.current.uniforms.u_intensity.value = sv.glowIntensity * 0.65;
|
|
83
|
+
}
|
|
65
84
|
// Vertex deformation
|
|
66
85
|
if (meshRef.current && origData.current) {
|
|
67
86
|
const geo = meshRef.current.geometry;
|
|
@@ -92,14 +111,21 @@ const LiquidScene = ({ colors, meshColor, speed, roughness, metalness, noiseScal
|
|
|
92
111
|
atmosphereRef.current.uniforms.u_time.value = t * spd;
|
|
93
112
|
}
|
|
94
113
|
});
|
|
95
|
-
return (jsxs("group", { ref: groupRef, children: [jsx(Environment, { preset: "sunset" }), jsx("ambientLight", { intensity: 2 }), jsx("pointLight", { color: colors[0], intensity: 18, distance: 50, position: [-3, 1, 2] }), jsx("pointLight", { color: colors[1], intensity: 18, distance: 50, position: [3, -1, 2] }), jsx("pointLight", { color: colors[2], intensity: 10, distance: 50, position: [0, 0, 4] }), jsx("pointLight", { color: "#6428b4", intensity: 12, distance: 50, position: [0, -3, 2] }), jsxs("mesh", { ref: meshRef, children: [jsx("sphereGeometry", { args: [1, 64, 64] }), jsx("meshStandardMaterial", { color: meshColor, roughness: roughness, metalness: metalness, envMapIntensity: 2.5, emissive: "#5A1878", emissiveIntensity: 0.8 })] }), jsxs("mesh", { scale: glowSize, children: [jsx("sphereGeometry", { args: [1, 32, 32] }), jsx("shaderMaterial", { ref: atmosphereRef, vertexShader: glowVertex, fragmentShader: atmosphereFragment, uniforms: atmosphereUniforms, transparent: true, side: BackSide, blending:
|
|
114
|
+
return (jsxs("group", { ref: groupRef, children: [jsx(Environment, { preset: "sunset" }), jsx("ambientLight", { intensity: 2 }), jsx("pointLight", { color: colors[0], intensity: 18, distance: 50, position: [-3, 1, 2] }), jsx("pointLight", { color: colors[1], intensity: 18, distance: 50, position: [3, -1, 2] }), jsx("pointLight", { color: colors[2], intensity: 10, distance: 50, position: [0, 0, 4] }), jsx("pointLight", { color: "#6428b4", intensity: 12, distance: 50, position: [0, -3, 2] }), jsxs("mesh", { ref: meshRef, children: [jsx("sphereGeometry", { args: [1, 64, 64] }), jsx("meshStandardMaterial", { color: meshColor, roughness: roughness, metalness: metalness, envMapIntensity: 2.5, emissive: "#5A1878", emissiveIntensity: 0.8 })] }), jsxs("mesh", { scale: glowSize, children: [jsx("sphereGeometry", { args: [1, 32, 32] }), jsx("shaderMaterial", { ref: atmosphereRef, vertexShader: glowVertex, fragmentShader: atmosphereFragment, uniforms: atmosphereUniforms, transparent: true, side: BackSide, blending: CustomBlending, blendEquation: AddEquation, blendSrc: OneFactor, blendDst: OneFactor, blendSrcAlpha: ZeroFactor, blendDstAlpha: OneFactor, depthWrite: false })] })] }));
|
|
96
115
|
};
|
|
97
116
|
// ── Public Liquid variant ────────────────────────────────────────────────────
|
|
98
117
|
const DEFAULT_COLORS = ["#2C35B7", "#C9242F", "#9DD9EB"];
|
|
99
|
-
const Liquid = ({ colors = DEFAULT_COLORS, meshColor = "#350F3F", speed = 1.0, roughness = 0.15, metalness = 0.95, noiseScale = 0.8, noiseAmplitude = 0.1, glowIntensity = 1.0, glowSize = 1.8, }) => {
|
|
100
|
-
return (jsxs(Fragment, { children: [jsx(Canvas, { className: "!absolute inset-0 w-full h-full",
|
|
118
|
+
const Liquid = ({ colors = DEFAULT_COLORS, meshColor = "#350F3F", speed = 1.0, roughness = 0.15, metalness = 0.95, noiseScale = 0.8, noiseAmplitude = 0.1, glowIntensity = 1.0, glowSize = 1.8, state, }) => {
|
|
119
|
+
return (jsxs(Fragment, { children: [jsx(Canvas, { className: "!absolute inset-0 w-full h-full", style: {
|
|
120
|
+
filter: [
|
|
121
|
+
'drop-shadow(0 0 10px rgba(192, 132, 252, 0.7))',
|
|
122
|
+
'drop-shadow(0 0 25px rgba(147, 51, 234, 0.35))',
|
|
123
|
+
'drop-shadow(0 0 50px rgba(124, 58, 237, 0.15))',
|
|
124
|
+
].join(' '),
|
|
125
|
+
}, dpr: [1, 2], camera: { position: [0, 0, 3.2], fov: 50 }, gl: { antialias: true, alpha: true, premultipliedAlpha: false, toneMapping: ACESFilmicToneMapping }, onCreated: ({ gl }) => {
|
|
101
126
|
gl.toneMappingExposure = 1.8;
|
|
102
|
-
|
|
127
|
+
gl.setClearColor(0x000000, 0);
|
|
128
|
+
}, children: jsx(LiquidScene, { colors: colors, meshColor: meshColor, speed: speed, roughness: roughness, metalness: metalness, noiseScale: noiseScale, noiseAmplitude: noiseAmplitude, glowIntensity: glowIntensity, glowSize: glowSize, state: state }) }), jsx("div", { className: "absolute inset-0 pointer-events-none", style: {
|
|
103
129
|
background: "radial-gradient(circle at center, rgba(255,255,255,0.35) 0%, rgba(180,120,255,0.2) 15%, rgba(100,40,180,0.08) 35%, transparent 55%)",
|
|
104
130
|
mixBlendMode: "screen",
|
|
105
131
|
} })] }));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OrbState } from "../../AIOrb.types";
|
|
1
2
|
export interface LiquidProps {
|
|
2
3
|
/**
|
|
3
4
|
* Three light colours as hex strings.
|
|
@@ -44,4 +45,9 @@ export interface LiquidProps {
|
|
|
44
45
|
* @default 1.8
|
|
45
46
|
*/
|
|
46
47
|
glowSize?: number;
|
|
48
|
+
/**
|
|
49
|
+
* State-driven animation. When set, smoothly interpolates speed,
|
|
50
|
+
* noiseAmplitude, and glowIntensity towards state targets.
|
|
51
|
+
*/
|
|
52
|
+
state?: OrbState;
|
|
47
53
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import type { CustomCursorContextType, CustomCursorProviderProps, CustomCursorProps, CustomCursorFollowProps } from
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { CustomCursorContextType, CustomCursorProviderProps, CustomCursorProps, CustomCursorFollowProps } from "./CustomCursor.types";
|
|
3
3
|
/**
|
|
4
4
|
* Hook to access CustomCursor context
|
|
5
5
|
* @throws Error if used outside CustomCursorProvider
|
|
@@ -18,7 +18,7 @@ const CustomCursorContext = React.createContext(undefined);
|
|
|
18
18
|
const useCustomCursor = () => {
|
|
19
19
|
const context = React.useContext(CustomCursorContext);
|
|
20
20
|
if (!context) {
|
|
21
|
-
throw new Error(
|
|
21
|
+
throw new Error("useCustomCursor must be used within a CustomCursorProvider");
|
|
22
22
|
}
|
|
23
23
|
return context;
|
|
24
24
|
};
|
|
@@ -36,7 +36,7 @@ const useCustomCursor = () => {
|
|
|
36
36
|
* </CustomCursorProvider>
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
|
-
const CustomCursorProvider = React.forwardRef(({ children, className, allowedPointerTypes = [
|
|
39
|
+
const CustomCursorProvider = React.forwardRef(({ children, className, allowedPointerTypes = ["mouse"], ...props }, ref) => {
|
|
40
40
|
const [cursorPos, setCursorPos] = React.useState({ x: 0, y: 0 });
|
|
41
41
|
const [isActive, setIsActive] = React.useState(false);
|
|
42
42
|
const containerRef = React.useRef(null);
|
|
@@ -52,12 +52,13 @@ const CustomCursorProvider = React.forwardRef(({ children, className, allowedPoi
|
|
|
52
52
|
// Ensure parent has positioning context for absolute children
|
|
53
53
|
const computedPosition = getComputedStyle(parent).position;
|
|
54
54
|
const previousInlinePosition = parent.style.position;
|
|
55
|
-
const shouldOverridePosition = computedPosition ===
|
|
55
|
+
const shouldOverridePosition = computedPosition === "static";
|
|
56
56
|
if (shouldOverridePosition) {
|
|
57
|
-
parent.style.position =
|
|
57
|
+
parent.style.position = "relative";
|
|
58
58
|
}
|
|
59
59
|
const handlePointerMove = (event) => {
|
|
60
|
-
const pointerType = (event.pointerType ||
|
|
60
|
+
const pointerType = (event.pointerType ||
|
|
61
|
+
"mouse");
|
|
61
62
|
if (!allowedPointerTypesSet.has(pointerType))
|
|
62
63
|
return;
|
|
63
64
|
const rect = parent.getBoundingClientRect();
|
|
@@ -69,7 +70,8 @@ const CustomCursorProvider = React.forwardRef(({ children, className, allowedPoi
|
|
|
69
70
|
setIsActive(true);
|
|
70
71
|
};
|
|
71
72
|
const handlePointerLeave = (event) => {
|
|
72
|
-
const pointerType = (event.pointerType ||
|
|
73
|
+
const pointerType = (event.pointerType ||
|
|
74
|
+
"mouse");
|
|
73
75
|
if (!allowedPointerTypesSet.has(pointerType))
|
|
74
76
|
return;
|
|
75
77
|
setIsActive(false);
|
|
@@ -85,23 +87,23 @@ const CustomCursorProvider = React.forwardRef(({ children, className, allowedPoi
|
|
|
85
87
|
const handleMouseLeave = () => {
|
|
86
88
|
setIsActive(false);
|
|
87
89
|
};
|
|
88
|
-
const supportsPointerEvents = typeof window !==
|
|
90
|
+
const supportsPointerEvents = typeof window !== "undefined" && "PointerEvent" in window;
|
|
89
91
|
if (supportsPointerEvents) {
|
|
90
|
-
parent.addEventListener(
|
|
91
|
-
parent.addEventListener(
|
|
92
|
+
parent.addEventListener("pointermove", handlePointerMove);
|
|
93
|
+
parent.addEventListener("pointerleave", handlePointerLeave);
|
|
92
94
|
}
|
|
93
95
|
else {
|
|
94
|
-
parent.addEventListener(
|
|
95
|
-
parent.addEventListener(
|
|
96
|
+
parent.addEventListener("mousemove", handleMouseMove);
|
|
97
|
+
parent.addEventListener("mouseleave", handleMouseLeave);
|
|
96
98
|
}
|
|
97
99
|
return () => {
|
|
98
100
|
if (supportsPointerEvents) {
|
|
99
|
-
parent.removeEventListener(
|
|
100
|
-
parent.removeEventListener(
|
|
101
|
+
parent.removeEventListener("pointermove", handlePointerMove);
|
|
102
|
+
parent.removeEventListener("pointerleave", handlePointerLeave);
|
|
101
103
|
}
|
|
102
104
|
else {
|
|
103
|
-
parent.removeEventListener(
|
|
104
|
-
parent.removeEventListener(
|
|
105
|
+
parent.removeEventListener("mousemove", handleMouseMove);
|
|
106
|
+
parent.removeEventListener("mouseleave", handleMouseLeave);
|
|
105
107
|
}
|
|
106
108
|
if (shouldOverridePosition) {
|
|
107
109
|
parent.style.position = previousInlinePosition;
|
|
@@ -111,7 +113,7 @@ const CustomCursorProvider = React.forwardRef(({ children, className, allowedPoi
|
|
|
111
113
|
const contextValue = React.useMemo(() => ({ cursorPos, isActive, containerRef, cursorRef }), [cursorPos, isActive]);
|
|
112
114
|
return (jsx(CustomCursorContext.Provider, { value: contextValue, children: jsx("div", { ref: containerRef, "data-slot": "custom-cursor-provider", className: className, ...props, children: children }) }));
|
|
113
115
|
});
|
|
114
|
-
CustomCursorProvider.displayName =
|
|
116
|
+
CustomCursorProvider.displayName = "CustomCursorProvider";
|
|
115
117
|
/**
|
|
116
118
|
* CustomCursor - Main cursor element component
|
|
117
119
|
* Follows mouse position exactly with instant movement
|
|
@@ -123,7 +125,7 @@ CustomCursorProvider.displayName = 'CustomCursorProvider';
|
|
|
123
125
|
* </CustomCursor>
|
|
124
126
|
* ```
|
|
125
127
|
*/
|
|
126
|
-
const CustomCursor = React.forwardRef(({ children, size =
|
|
128
|
+
const CustomCursor = React.forwardRef(({ children, size = "md", color = "primary", variant = "default", shape = "arrow", className, style, ...props }, ref) => {
|
|
127
129
|
const { cursorPos, isActive, containerRef, cursorRef } = useCustomCursor();
|
|
128
130
|
React.useImperativeHandle(ref, () => cursorRef.current);
|
|
129
131
|
const x = useMotionValue(0);
|
|
@@ -136,7 +138,7 @@ const CustomCursor = React.forwardRef(({ children, size = 'md', color = 'primary
|
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
138
140
|
const previousInlineCursor = parentElement.style.cursor;
|
|
139
|
-
parentElement.style.cursor =
|
|
141
|
+
parentElement.style.cursor = "none";
|
|
140
142
|
return () => {
|
|
141
143
|
parentElement.style.cursor = previousInlineCursor;
|
|
142
144
|
};
|
|
@@ -147,32 +149,32 @@ const CustomCursor = React.forwardRef(({ children, size = 'md', color = 'primary
|
|
|
147
149
|
y.set(cursorPos.y);
|
|
148
150
|
}, [cursorPos, x, y]);
|
|
149
151
|
// Default content based on shape
|
|
150
|
-
const defaultContent = shape ===
|
|
152
|
+
const defaultContent = shape === "arrow" ? (jsx(PaperAirplaneIcon, { className: "w-full h-full rotate-180" })) : (jsx("div", { className: "w-full h-full" }));
|
|
151
153
|
return (jsx(AnimatePresence, { children: isActive && (jsx(motion.div, { ref: cursorRef, "data-slot": "custom-cursor", className: cn(customCursorTheme.baseStyle, customCursorTheme.cursorStyle, customCursorTheme.sizes[size], customCursorTheme.colors[color], customCursorTheme.variants[variant], customCursorTheme.shapes[shape], className), style: { top: y, left: x, ...style }, variants: customCursorVariants, initial: "initial", animate: "animate", exit: "exit", role: "presentation", "aria-hidden": "true", ...props, children: children || defaultContent })) }));
|
|
152
154
|
});
|
|
153
|
-
CustomCursor.displayName =
|
|
155
|
+
CustomCursor.displayName = "CustomCursor";
|
|
154
156
|
/**
|
|
155
157
|
* Calculate offset based on alignment and element dimensions
|
|
156
158
|
*/
|
|
157
159
|
const calculateOffset = (align, sideOffset, width, height) => {
|
|
158
160
|
switch (align) {
|
|
159
|
-
case
|
|
161
|
+
case "center":
|
|
160
162
|
return { x: width / 2, y: height / 2 };
|
|
161
|
-
case
|
|
163
|
+
case "top":
|
|
162
164
|
return { x: width / 2, y: height + sideOffset };
|
|
163
|
-
case
|
|
165
|
+
case "top-left":
|
|
164
166
|
return { x: width + sideOffset, y: height + sideOffset };
|
|
165
|
-
case
|
|
167
|
+
case "top-right":
|
|
166
168
|
return { x: -sideOffset, y: height + sideOffset };
|
|
167
|
-
case
|
|
169
|
+
case "bottom":
|
|
168
170
|
return { x: width / 2, y: -sideOffset };
|
|
169
|
-
case
|
|
171
|
+
case "bottom-left":
|
|
170
172
|
return { x: width + sideOffset, y: -sideOffset };
|
|
171
|
-
case
|
|
173
|
+
case "bottom-right":
|
|
172
174
|
return { x: -sideOffset, y: -sideOffset };
|
|
173
|
-
case
|
|
175
|
+
case "left":
|
|
174
176
|
return { x: width + sideOffset, y: height / 2 };
|
|
175
|
-
case
|
|
177
|
+
case "right":
|
|
176
178
|
return { x: -sideOffset, y: height / 2 };
|
|
177
179
|
default:
|
|
178
180
|
return { x: 0, y: 0 };
|
|
@@ -193,12 +195,12 @@ const calculateOffset = (align, sideOffset, width, height) => {
|
|
|
193
195
|
*/
|
|
194
196
|
/** Available colors for random selection in user variant */
|
|
195
197
|
const userVariantColors = [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
"primary",
|
|
199
|
+
"success",
|
|
200
|
+
"warning",
|
|
201
|
+
"danger",
|
|
200
202
|
];
|
|
201
|
-
const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align =
|
|
203
|
+
const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align = "bottom-right", transition, variant = "default", avatar, name, color, className, style, ...props }, ref) => {
|
|
202
204
|
const { cursorPos, isActive, cursorRef } = useCustomCursor();
|
|
203
205
|
const cursorFollowRef = React.useRef(null);
|
|
204
206
|
const shouldReduceMotion = useReducedMotion();
|
|
@@ -223,7 +225,7 @@ const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align
|
|
|
223
225
|
// Apply spring physics for smooth following
|
|
224
226
|
const springConfig = shouldReduceMotion
|
|
225
227
|
? reducedMotionSpringConfig
|
|
226
|
-
: transition !== null && transition !== void 0 ? transition : defaultSpringConfig;
|
|
228
|
+
: (transition !== null && transition !== void 0 ? transition : defaultSpringConfig);
|
|
227
229
|
const springX = useSpring(x, springConfig);
|
|
228
230
|
const springY = useSpring(y, springConfig);
|
|
229
231
|
// Track size changes on the follow element
|
|
@@ -244,14 +246,14 @@ const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align
|
|
|
244
246
|
};
|
|
245
247
|
updateDimensions();
|
|
246
248
|
const cleanupFns = [];
|
|
247
|
-
if (typeof ResizeObserver !==
|
|
249
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
248
250
|
const observer = new ResizeObserver(updateDimensions);
|
|
249
251
|
observer.observe(followElement);
|
|
250
252
|
cleanupFns.push(() => observer.disconnect());
|
|
251
253
|
}
|
|
252
|
-
if (typeof window !==
|
|
253
|
-
window.addEventListener(
|
|
254
|
-
cleanupFns.push(() => window.removeEventListener(
|
|
254
|
+
if (typeof window !== "undefined") {
|
|
255
|
+
window.addEventListener("resize", updateDimensions);
|
|
256
|
+
cleanupFns.push(() => window.removeEventListener("resize", updateDimensions));
|
|
255
257
|
}
|
|
256
258
|
return () => {
|
|
257
259
|
cleanupFns.forEach((cleanup) => cleanup());
|
|
@@ -275,14 +277,14 @@ const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align
|
|
|
275
277
|
};
|
|
276
278
|
updateCursorDimensions();
|
|
277
279
|
const cleanupFns = [];
|
|
278
|
-
if (typeof ResizeObserver !==
|
|
280
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
279
281
|
const observer = new ResizeObserver(updateCursorDimensions);
|
|
280
282
|
observer.observe(cursorElement);
|
|
281
283
|
cleanupFns.push(() => observer.disconnect());
|
|
282
284
|
}
|
|
283
|
-
if (typeof window !==
|
|
284
|
-
window.addEventListener(
|
|
285
|
-
cleanupFns.push(() => window.removeEventListener(
|
|
285
|
+
if (typeof window !== "undefined") {
|
|
286
|
+
window.addEventListener("resize", updateCursorDimensions);
|
|
287
|
+
cleanupFns.push(() => window.removeEventListener("resize", updateCursorDimensions));
|
|
286
288
|
}
|
|
287
289
|
return () => {
|
|
288
290
|
cleanupFns.forEach((cleanup) => cleanup());
|
|
@@ -311,13 +313,14 @@ const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align
|
|
|
311
313
|
]);
|
|
312
314
|
// Determine content based on variant
|
|
313
315
|
const renderContent = () => {
|
|
314
|
-
if (variant ===
|
|
315
|
-
return (jsxs(Fragment, { children: [avatar && jsx(Avatar, { src: avatar,
|
|
316
|
+
if (variant === "user") {
|
|
317
|
+
return (jsxs(Fragment, { children: [avatar && jsx(Avatar, { src: avatar, name: name || "User", size: "xs" }), name && (jsx("span", { className: "text-white text-sm font-medium whitespace-nowrap", children: name }))] }));
|
|
316
318
|
}
|
|
317
319
|
return children;
|
|
318
320
|
};
|
|
319
|
-
return (jsx(AnimatePresence, { children: isActive && (jsx(motion.div, { ref: cursorFollowRef, "data-slot": "custom-cursor-follow", className: cn(customCursorTheme.baseStyle, customCursorTheme.cursorFollowVariants[variant], variant ===
|
|
321
|
+
return (jsx(AnimatePresence, { children: isActive && (jsx(motion.div, { ref: cursorFollowRef, "data-slot": "custom-cursor-follow", className: cn(customCursorTheme.baseStyle, customCursorTheme.cursorFollowVariants[variant], variant === "user" &&
|
|
322
|
+
customCursorTheme.cursorFollowColors[resolvedColor], className), style: { top: springY, left: springX, ...style }, variants: customCursorVariants, initial: "initial", animate: "animate", exit: "exit", role: "presentation", "aria-hidden": "true", ...props, children: renderContent() })) }));
|
|
320
323
|
});
|
|
321
|
-
CustomCursorFollow.displayName =
|
|
324
|
+
CustomCursorFollow.displayName = "CustomCursorFollow";
|
|
322
325
|
|
|
323
326
|
export { CustomCursor, CustomCursorFollow, CustomCursorProvider, useCustomCursor };
|
|
@@ -23,7 +23,7 @@ const useDarkMode = () => {
|
|
|
23
23
|
* Creates a realistic chromatic aberration glass effect using SVG filters.
|
|
24
24
|
* Works as a wrapper for any content.
|
|
25
25
|
*/
|
|
26
|
-
const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness
|
|
26
|
+
const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", frosted = false, className = "", style = {}, }) => {
|
|
27
27
|
const uniqueId = useId().replace(/:/g, "-");
|
|
28
28
|
const filterId = `glass-filter-${uniqueId}`;
|
|
29
29
|
const redGradId = `red-grad-${uniqueId}`;
|
|
@@ -37,6 +37,19 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
|
|
|
37
37
|
const blueChannelRef = useRef(null);
|
|
38
38
|
const gaussianBlurRef = useRef(null);
|
|
39
39
|
const isDarkMode = useDarkMode();
|
|
40
|
+
const resolvedDark = colorScheme === "auto" ? isDarkMode : colorScheme === "dark";
|
|
41
|
+
// Theme-aware defaults: user-provided props always win
|
|
42
|
+
// Note: brightness/opacity control the displacement map center fill, NOT visual brightness.
|
|
43
|
+
// brightness=50 + opacity=1 = neutral center (no displacement), only edges refract.
|
|
44
|
+
// On light backgrounds, high displacement pulls in black out-of-bounds pixels → gray artifacts.
|
|
45
|
+
const brightness = brightnessProp !== null && brightnessProp !== void 0 ? brightnessProp : 50;
|
|
46
|
+
const opacity = opacityProp !== null && opacityProp !== void 0 ? opacityProp : (resolvedDark ? 0.93 : 1);
|
|
47
|
+
const blur = blurProp !== null && blurProp !== void 0 ? blurProp : 11;
|
|
48
|
+
const displace = displaceProp !== null && displaceProp !== void 0 ? displaceProp : 0.7;
|
|
49
|
+
const backgroundOpacity = backgroundOpacityProp !== null && backgroundOpacityProp !== void 0 ? backgroundOpacityProp : (resolvedDark ? 0.1 : 0);
|
|
50
|
+
const saturation = saturationProp !== null && saturationProp !== void 0 ? saturationProp : (resolvedDark ? 1.8 : 1.4);
|
|
51
|
+
const distortionScale = distortionScaleProp !== null && distortionScaleProp !== void 0 ? distortionScaleProp : (resolvedDark ? -180 : -40);
|
|
52
|
+
const mixBlendMode = mixBlendModeProp !== null && mixBlendModeProp !== void 0 ? mixBlendModeProp : (resolvedDark ? "difference" : "multiply");
|
|
40
53
|
/**
|
|
41
54
|
* Generates the SVG displacement map as a Data URI
|
|
42
55
|
*/
|
|
@@ -157,7 +170,7 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
|
|
|
157
170
|
const frostedBlur = frosted ? "blur(12px)" : "";
|
|
158
171
|
if (svgSupported) {
|
|
159
172
|
// Determine background color: use prop if provided, otherwise auto-detect based on theme
|
|
160
|
-
const bgColor = backgroundColor || (
|
|
173
|
+
const bgColor = backgroundColor || (resolvedDark ? "hsl(0 0% 0%)" : "hsl(0 0% 100%)");
|
|
161
174
|
// Convert color to rgba if needed to apply opacity
|
|
162
175
|
const getBackgroundWithOpacity = () => {
|
|
163
176
|
// If backgroundOpacity is 0, return transparent
|
|
@@ -175,19 +188,18 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
|
|
|
175
188
|
background: getBackgroundWithOpacity(),
|
|
176
189
|
backdropFilter: `url(#${filterId}) ${frostedBlur} saturate(${saturation})`,
|
|
177
190
|
WebkitBackdropFilter: `url(#${filterId}) ${frostedBlur} saturate(${saturation})`,
|
|
191
|
+
...(!resolvedDark && { border: "1px solid rgba(0, 0, 0, 0.06)" }),
|
|
178
192
|
...(hasCustomShadow
|
|
179
193
|
? {}
|
|
180
194
|
: {
|
|
181
|
-
boxShadow:
|
|
195
|
+
boxShadow: resolvedDark
|
|
182
196
|
? `0 0 2px 1px color-mix(in oklch, white, transparent 65%) inset,
|
|
183
197
|
0 0 10px 4px color-mix(in oklch, white, transparent 85%) inset,
|
|
184
198
|
0px 4px 16px rgba(17, 17, 26, 0.05),
|
|
185
199
|
0px 8px 24px rgba(17, 17, 26, 0.05),
|
|
186
200
|
0px 16px 56px rgba(17, 17, 26, 0.05)`
|
|
187
|
-
: `0
|
|
188
|
-
0
|
|
189
|
-
0 8px 24px -12px rgba(0, 0, 0, 0.08),
|
|
190
|
-
0 4px 12px -4px rgba(0, 0, 0, 0.03)`,
|
|
201
|
+
: `0 8px 24px -12px rgba(0, 0, 0, 0.08),
|
|
202
|
+
0 4px 12px -4px rgba(0, 0, 0, 0.04)`,
|
|
191
203
|
}),
|
|
192
204
|
};
|
|
193
205
|
}
|
|
@@ -197,9 +209,9 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
|
|
|
197
209
|
// Increase blur significantly for frosted mode in fallback
|
|
198
210
|
const effectiveBlur = frosted ? "20px" : baseBlur;
|
|
199
211
|
const fallbackSaturate = "1.8";
|
|
200
|
-
const fallbackBrightness =
|
|
212
|
+
const fallbackBrightness = resolvedDark ? "1.2" : "1.1";
|
|
201
213
|
const filterStr = `blur(${effectiveBlur}) saturate(${fallbackSaturate}) brightness(${fallbackBrightness})`;
|
|
202
|
-
if (
|
|
214
|
+
if (resolvedDark) {
|
|
203
215
|
return {
|
|
204
216
|
...baseStyles,
|
|
205
217
|
background: supportsBackdrop
|
|
@@ -234,11 +246,11 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
|
|
|
234
246
|
};
|
|
235
247
|
}
|
|
236
248
|
}
|
|
237
|
-
}, [style, width, height, borderRadius, frosted, svgSupported, backgroundColor,
|
|
238
|
-
const focusVisibleClasses =
|
|
249
|
+
}, [style, width, height, borderRadius, frosted, svgSupported, backgroundColor, resolvedDark, backgroundOpacity, filterId, saturation, hasCustomShadow, supportsBackdrop]);
|
|
250
|
+
const focusVisibleClasses = resolvedDark
|
|
239
251
|
? "focus-visible:outline-2 focus-visible:outline-[#0A84FF] focus-visible:outline-offset-2"
|
|
240
252
|
: "focus-visible:outline-2 focus-visible:outline-[#007AFF] focus-visible:outline-offset-2";
|
|
241
|
-
return (jsxs("div", { ref: containerRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", id: "redchannel", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", id: "greenchannel", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", id: "bluechannel", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
|
|
253
|
+
return (jsxs("div", { ref: containerRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", id: "redchannel", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", id: "greenchannel", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", id: "bluechannel", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
|
|
242
254
|
};
|
|
243
255
|
|
|
244
256
|
export { GlassSurface };
|
|
@@ -40,6 +40,14 @@ export interface GlassSurfaceProps {
|
|
|
40
40
|
yChannel?: GlassChannel;
|
|
41
41
|
/** Blend mode for the internal gradient layers */
|
|
42
42
|
mixBlendMode?: GlassMixBlendMode;
|
|
43
|
+
/**
|
|
44
|
+
* Color scheme for the glass effect. Controls theme-aware defaults.
|
|
45
|
+
* - 'auto': detects system preference (default)
|
|
46
|
+
* - 'dark': force dark mode defaults
|
|
47
|
+
* - 'light': force light mode defaults
|
|
48
|
+
* @default 'auto'
|
|
49
|
+
*/
|
|
50
|
+
colorScheme?: "auto" | "dark" | "light";
|
|
43
51
|
/**
|
|
44
52
|
* Enable frosted glass effect with noise texture
|
|
45
53
|
* @default false
|
|
@@ -551,7 +551,7 @@ const Mention = React__default.forwardRef(({ triggers: triggersProp, suggestions
|
|
|
551
551
|
return (jsx("span", { "data-segment": "text", children: seg.text || (i === 0 ? "" : "") }, `text-${i}`));
|
|
552
552
|
}
|
|
553
553
|
return (jsx(Tag, { size: mentionTagSize, removable: false, avatar: seg.data.avatar
|
|
554
|
-
? { src: seg.data.avatar,
|
|
554
|
+
? { src: seg.data.avatar, name: seg.data.label }
|
|
555
555
|
: undefined, contentEditable: false, className: cn(theme.mentionTagStyle, i === selectedMentionIndex &&
|
|
556
556
|
"ring-2 ring-[var(--color-primary)] ring-offset-1", mentionTagClassName), [MENTION_ATTR]: seg.data.id,
|
|
557
557
|
"data-mention-label": seg.data.label,
|
|
@@ -579,7 +579,7 @@ const Mention = React__default.forwardRef(({ triggers: triggersProp, suggestions
|
|
|
579
579
|
return (jsxs("div", { role: "option", "aria-selected": isHighlighted, "data-suggestion-index": index, className: cn(theme.suggestionStyle, isHighlighted && theme.suggestionHighlightedStyle), onMouseEnter: () => setHighlightedIndex(index), onMouseDown: (e) => {
|
|
580
580
|
e.preventDefault();
|
|
581
581
|
insertMention(suggestion);
|
|
582
|
-
}, children: [jsx(Avatar, { src: suggestion.avatar,
|
|
582
|
+
}, children: [jsx(Avatar, { src: suggestion.avatar, name: suggestion.label, size: "xs", className: "ring-0 border-0" }), jsxs("div", { className: "flex flex-col min-w-0", children: [jsx("span", { className: theme.suggestionLabelStyle, children: suggestion.label }), suggestion.description && (jsx("span", { className: theme.suggestionDescriptionStyle, children: suggestion.description }))] })] }, suggestion.id));
|
|
583
583
|
};
|
|
584
584
|
// -----------------------------------------------------------------------
|
|
585
585
|
// Dropdown portal content
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,7 @@ export { DropdownSeparator } from './components/core/Dropdown/DropdownSeparator.
|
|
|
84
84
|
export { DropdownTrigger } from './components/core/Dropdown/DropdownTrigger.js';
|
|
85
85
|
export { Empty } from './components/core/Empty/Empty.js';
|
|
86
86
|
export { Feed } from './components/data-display/Feed/Feed.js';
|
|
87
|
+
export { FileTypeIcon } from './components/core/FileTypeIcon/FileTypeIcon.js';
|
|
87
88
|
export { FileUpload } from './components/forms/FileUpload/FileUpload.js';
|
|
88
89
|
export { FormLabel } from './components/forms/FormLabel/FormLabel.js';
|
|
89
90
|
export { FunnelChart } from './components/charts/FunnelChart/FunnelChart.js';
|
|
@@ -105,7 +106,6 @@ export { Kbd } from './components/core/Kbd/Kbd.js';
|
|
|
105
106
|
export { LINE_CHART_DEFAULTS } from './components/charts/LineChart/LineChart.types.js';
|
|
106
107
|
export { LineChart } from './components/charts/LineChart/LineChart.js';
|
|
107
108
|
export { Link } from './components/core/Link/Link.js';
|
|
108
|
-
export { Loader } from './components/core/Loader/Loader.js';
|
|
109
109
|
export { MagneticElement } from './components/effects/MagneticElement/MagneticElement.js';
|
|
110
110
|
export { Masonry } from './components/core/Masonry/Masonry.js';
|
|
111
111
|
export { Mention } from './components/forms/Mention/Mention.js';
|