react-glass-ui
Version:
A customizable React component library for creating elegant glassmorphism interfaces. It provides flexible, interactive UI elements, such as cards, buttons, and inputs, with effects including blur, saturation, distortion, light glow, and hover.
833 lines (825 loc) • 34.9 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
// src/ui-elements/glass-card/index.tsx
import { useEffect, useMemo, useRef, useState } from "react";
// src/models/index.ts
var glassDefaultProps = {
blur: 2,
distortion: 20,
chromaticAberration: 0,
borderRadius: 10,
borderSize: 1,
borderOpacity: 1,
color: "white",
backgroundColor: "white",
backgroundOpacity: 0,
flexibility: 0,
onHoverScale: 1,
saturation: 120,
brightness: 100,
innerLightBlur: 10,
innerLightSpread: 1,
innerLightColor: "white",
innerLightOpacity: 0,
outerLightBlur: 10,
outerLightSpread: 1,
outerLightColor: "white",
outerLightOpacity: 0,
padding: "10px"
};
// src/assets/normal-maps/index.ts
var distortionMap = "data:image/webp;base64,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";
// src/utils/index.tsx
import "./utils-XF4KTG5J.css";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var renderLayers = (id, blur, borderRadius, saturation, brightness, distortion, backgroundColor, backgroundOpacity, style, innerLightOpacity, outerLightOpacity, borderColor, borderSize, borderOpacity, chromaticAberration, avoidSvgCreation, type) => {
return /* @__PURE__ */ jsxs(Fragment, { children: [
distortion && !avoidSvgCreation ? /* @__PURE__ */ jsxs("svg", { style: { borderRadius }, className: "glass-ui-svg", children: [
" ",
/* @__PURE__ */ jsx("clipPath", { id: `${id}-clip`, children: /* @__PURE__ */ jsx(
"rect",
{
x: "0",
y: "0",
width: "100%",
height: "100%",
rx: 0,
ry: borderRadius
}
) }),
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
"filter",
{
id: `${id}-filter`,
x: "0",
y: "0",
width: "100%",
height: "100%",
colorInterpolationFilters: "sRGB",
children: [
/* @__PURE__ */ jsx(
"feImage",
{
id: "feimage",
x: "0%",
y: "0",
width: "100%",
height: "100%",
href: distortionMap,
result: "originalMap",
preserveAspectRatio: "xMidYMid slice"
}
),
/* @__PURE__ */ jsx(
"feDisplacementMap",
{
in: "SourceGraphic",
in2: "originalMap",
scale: distortion,
xChannelSelector: "R",
yChannelSelector: "G",
result: "distortedOutput"
}
),
/* @__PURE__ */ jsx(
"feColorMatrix",
{
in: "distortedOutput",
type: "matrix",
values: "1 0 0 0 0\r\n 0 0 0 0 0\r\n 0 0 0 0 0\r\n 0 0 0 1 0",
result: "r"
}
),
/* @__PURE__ */ jsx(
"feOffset",
{
in: "r",
dx: -chromaticAberration,
dy: "0",
result: "rOffset"
}
),
/* @__PURE__ */ jsx(
"feColorMatrix",
{
in: "distortedOutput",
type: "matrix",
values: "0 0 0 0 0\r\n 0 1 0 0 0\r\n 0 0 0 0 0\r\n 0 0 0 1 0",
result: "g"
}
),
/* @__PURE__ */ jsx("feOffset", { in: "g", dx: "0", dy: "0", result: "gOffset" }),
/* @__PURE__ */ jsx(
"feColorMatrix",
{
in: "distortedOutput",
type: "matrix",
values: "0 0 0 0 0\r\n 0 0 0 0 0\r\n 0 0 1 0 0\r\n 0 0 0 1 0",
result: "b"
}
),
/* @__PURE__ */ jsx(
"feOffset",
{
in: "b",
dx: chromaticAberration,
dy: "0",
result: "bOffset"
}
),
/* @__PURE__ */ jsx("feBlend", { in: "rOffset", in2: "gOffset", mode: "screen", result: "rgb1" }),
/* @__PURE__ */ jsx(
"feBlend",
{
in: "rgb1",
in2: "bOffset",
mode: "screen",
result: "finalRender"
}
),
/* @__PURE__ */ jsx("feComposite", { in: "finalRender", in2: "SourceAlpha", operator: "in" })
]
}
) })
] }) : "",
type === "range" ? "" : /* @__PURE__ */ jsxs(Fragment, { children: [
borderSize ? /* @__PURE__ */ jsx(
"span",
{
className: "glass-ui-border-layer",
style: {
borderRadius,
border: `${borderSize}px solid ${borderColor}`,
opacity: borderOpacity
}
}
) : "",
innerLightOpacity ? /* @__PURE__ */ jsx(
"span",
{
className: "glass-ui-inner-light",
style: {
borderRadius,
boxShadow: style.innerBoxShadow,
opacity: innerLightOpacity
}
}
) : "",
backgroundOpacity ? /* @__PURE__ */ jsx(
"div",
{
className: "glass-ui-background-layer",
style: {
borderRadius,
opacity: `${backgroundOpacity}`,
backgroundColor: `${backgroundColor}`
}
}
) : "",
distortion || blur || saturation || brightness ? /* @__PURE__ */ jsx(
"div",
{
className: "glass-ui-distortion-layer",
style: {
borderRadius,
clipPath: `url(#${id}-clip)`,
WebkitClipPath: `url(#${id}-clip)`,
filter: `url(#${id}-filter)`,
backdropFilter: `blur(${blur}px) saturate(${saturation}%) brightness(${brightness}%)`,
WebkitBackdropFilter: `blur(${blur}px) saturate(${saturation}%) brightness(${brightness}%)`
}
}
) : "",
outerLightOpacity ? /* @__PURE__ */ jsx(
"span",
{
className: "glass-ui-outer-light",
style: {
borderRadius,
boxShadow: style.outerBoxShadow,
opacity: outerLightOpacity
}
}
) : ""
] })
] });
};
function calculateHoverEffect(e, card, props) {
const {
flexibility = 0,
onHoverScale = 1,
innerLightBlur = 0,
innerLightSpread = 0,
innerLightColor = "white",
outerLightBlur = 0,
outerLightSpread = 0,
outerLightColor = "white"
} = props;
let transform = "none";
if (flexibility > 0) {
const rect = card.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const dx = e.clientX - centerX;
const dy = e.clientY - centerY;
const angle = Math.atan2(dy, dx);
const distance = Math.sqrt(dx * dx + dy * dy);
const scaleFactor = flexibility / 100;
const translateX = Math.cos(angle) * distance * scaleFactor;
const translateY = Math.sin(angle) * distance * scaleFactor;
let stretchX = 1;
let stretchY = 1;
if (onHoverScale) {
stretchX = onHoverScale + Math.abs(translateX) / rect.width;
stretchY = onHoverScale + Math.abs(translateY) / rect.height;
}
transform = `translate(${translateX}px, ${translateY}px) scale(${stretchX}, ${stretchY})`;
}
return {
transform,
innerBoxShadow: `inset 0px 0px ${innerLightBlur}px ${innerLightSpread}px ${innerLightColor}`,
outerBoxShadow: `0 0 ${outerLightBlur}px ${outerLightSpread}px ${outerLightColor}`
};
}
// src/ui-elements/glass-card/index.tsx
import "./glass-card-NPANW5ET.css";
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
var GlassCard = (props) => {
var _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
const _a = __spreadValues(__spreadValues({}, glassDefaultProps), props), {
padding = "10px 20px",
children
} = _a, cardProps = __objRest(_a, [
"padding",
"children"
]);
const id = useMemo(() => {
var _a2;
return (_a2 = cardProps.id) != null ? _a2 : crypto.randomUUID();
}, []);
const glassCardContainerRef = useRef(null);
const glassCardContentRef = useRef(null);
const [isHovered, setIsHovered] = useState(false);
const [style, setStyle] = useState({
transform: "none",
innerBoxShadow: `inset 0 0 ${cardProps.innerLightBlur}px ${cardProps.innerLightSpread}px ${cardProps.innerLightColor}`,
outerBoxShadow: `0 0 ${cardProps.outerLightBlur}px ${cardProps.outerLightSpread}px ${cardProps.outerLightColor}`
});
useEffect(() => {
const card = glassCardContainerRef.current;
if (!card) return;
const handleMouseMove = (e) => {
const result = calculateHoverEffect(e, card, cardProps);
setStyle((prev) => __spreadValues(__spreadValues({}, prev), result));
};
const reset = () => {
setIsHovered(false);
setStyle({
transform: "none",
innerBoxShadow: `inset 0 0 ${cardProps.innerLightBlur}px ${cardProps.innerLightSpread}px ${cardProps.innerLightColor}`,
outerBoxShadow: `0 0 ${cardProps.outerLightBlur}px ${cardProps.outerLightSpread}px ${cardProps.outerLightColor}`
});
};
card.addEventListener("mousemove", handleMouseMove);
card.addEventListener("mouseleave", reset);
return () => {
card.removeEventListener("mousemove", handleMouseMove);
card.removeEventListener("mouseleave", reset);
};
}, [style]);
useEffect(() => {
setStyle((prev) => __spreadProps(__spreadValues({}, prev), {
innerBoxShadow: `inset 0 0 ${cardProps.innerLightBlur}px ${cardProps.innerLightSpread}px ${cardProps.innerLightColor}`,
outerBoxShadow: `0 0 ${cardProps.outerLightBlur}px ${cardProps.outerLightSpread}px ${cardProps.outerLightColor}`
}));
}, [
cardProps.innerLightBlur,
cardProps.innerLightSpread,
cardProps.innerLightColor,
cardProps.outerLightBlur,
cardProps.outerLightSpread,
cardProps.outerLightColor
]);
const handleOnMouseEnter = () => {
setIsHovered(true);
};
const handleOnMouseLeave = () => {
setIsHovered(false);
};
return /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsxs2(
"div",
{
id: cardProps.id,
ref: glassCardContainerRef,
className: `glass-ui-container ${cardProps.className ? cardProps.className : ""}`,
onMouseEnter: handleOnMouseEnter,
onMouseLeave: handleOnMouseLeave,
onClick: cardProps.onClick,
style: {
color: cardProps.color,
width: (_b = cardProps.width) != null ? _b : "fit-content",
height: (_c = cardProps.height) != null ? _c : "fit-content",
borderRadius: cardProps.borderRadius,
transform: style.transform,
transition: isHovered ? "transform 80ms ease-out" : "transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5)",
willChange: "transform",
zIndex: cardProps.zIndex
},
children: [
renderLayers(
id,
(_d = cardProps.blur) != null ? _d : 1,
(_e = cardProps.borderRadius) != null ? _e : 8,
(_f = cardProps.saturation) != null ? _f : 100,
(_g = cardProps.brightness) != null ? _g : 100,
(_h = cardProps.distortion) != null ? _h : 50,
(_i = cardProps.backgroundColor) != null ? _i : "white",
(_j = cardProps.backgroundOpacity) != null ? _j : 0,
style,
(_k = cardProps.innerLightOpacity) != null ? _k : 0.2,
(_l = cardProps.outerLightOpacity) != null ? _l : 0.2,
(_n = (_m = cardProps.borderColor) != null ? _m : cardProps.innerLightColor) != null ? _n : "white",
(_o = cardProps.borderSize) != null ? _o : 1,
(_p = cardProps.borderOpacity) != null ? _p : 1,
(_q = cardProps.chromaticAberration) != null ? _q : 0,
(_r = cardProps.avoidSvgCreation) != null ? _r : false
),
/* @__PURE__ */ jsx2(
"div",
{
ref: glassCardContentRef,
className: `glass-ui-card-content ${cardProps.contentCenter ? "content-center" : ""} ${cardProps.itemsCenter ? "items-center" : ""} ${cardProps.contentCenter || cardProps.itemsCenter ? "d-flex" : ""} ${cardProps.contentClassName ? cardProps.contentClassName : ""}`,
style: {
padding: padding != null ? padding : "",
borderRadius: cardProps.borderRadius
},
children
}
)
]
},
cardProps.key
) });
};
// src/ui-elements/glass-input/index.tsx
import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
import "./glass-input-IFZXYWCK.css";
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
var GlassInput = (props) => {
var _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
const _a = __spreadValues(__spreadValues({}, glassDefaultProps), props), {
height = 40,
type = "text",
maxLength,
minLength,
placeholder = "Placeholder",
label,
labelColor = "white",
multiple = false,
required = false,
autofocus = false,
onChange
} = _a, inputProps = __objRest(_a, [
"height",
"type",
"maxLength",
"minLength",
"placeholder",
"label",
"labelColor",
"multiple",
"required",
"autofocus",
"onChange"
]);
const id = useMemo2(() => {
var _a2;
return (_a2 = inputProps.id) != null ? _a2 : crypto.randomUUID();
}, []);
const glassInputContainerRef = useRef2(null);
const glassInputContentRef = useRef2(null);
const [isHovered, setIsHovered] = useState2(false);
const [style, setStyle] = useState2({
transform: "none",
innerBoxShadow: `inset 0 0 ${inputProps.innerLightBlur}px ${inputProps.innerLightSpread}px ${inputProps.innerLightColor}`,
outerBoxShadow: `0 0 ${inputProps.outerLightBlur}px ${inputProps.outerLightSpread}px ${inputProps.outerLightColor}`
});
useEffect2(() => {
const input = glassInputContainerRef.current;
if (!input) return;
const handleMouseMove = (e) => {
const result = calculateHoverEffect(e, input, inputProps);
setStyle((prev) => __spreadValues(__spreadValues({}, prev), result));
};
const reset = () => {
setIsHovered(false);
setStyle({
transform: "none",
innerBoxShadow: `inset 0 0 ${inputProps.innerLightBlur}px ${inputProps.innerLightSpread}px ${inputProps.innerLightColor}`,
outerBoxShadow: `0 0 ${inputProps.outerLightBlur}px ${inputProps.outerLightSpread}px ${inputProps.outerLightColor}`
});
};
input.addEventListener("mousemove", handleMouseMove);
input.addEventListener("mouseleave", reset);
return () => {
input.removeEventListener("mousemove", handleMouseMove);
input.removeEventListener("mouseleave", reset);
};
}, [style]);
useEffect2(() => {
setStyle((prev) => __spreadProps(__spreadValues({}, prev), {
innerBoxShadow: `inset 0 0 ${inputProps.innerLightBlur}px ${inputProps.innerLightSpread}px ${inputProps.innerLightColor}`,
outerBoxShadow: `0 0 ${inputProps.outerLightBlur}px ${inputProps.outerLightSpread}px ${inputProps.outerLightColor}`
}));
}, [
inputProps.innerLightBlur,
inputProps.innerLightSpread,
inputProps.innerLightColor,
inputProps.outerLightBlur,
inputProps.outerLightSpread,
inputProps.outerLightColor
]);
const handleOnMouseEnter = () => {
setIsHovered(true);
};
const handleOnMouseLeave = () => {
setIsHovered(false);
};
const renderInput = () => {
var _a2, _b2, _c2, _d2, _e2, _f2;
if (type === "range") {
const trackRef = useRef2(null);
const [dragging, setDragging] = useState2(false);
const [rangeValue, setRangeValue] = useState2((_a2 = inputProps.value) != null ? _a2 : 50);
const min = (_b2 = inputProps.min) != null ? _b2 : 0;
const max = (_c2 = inputProps.max) != null ? _c2 : 100;
const step = (_d2 = inputProps.step) != null ? _d2 : 1;
const percent = Math.ceil((rangeValue - min) / (max - min) * 100);
useEffect2(() => {
if (dragging) {
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
} else {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleMouseUp);
}
return () => {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleMouseUp);
};
}, [dragging]);
const handleMouseDown = (e) => {
setDragging(true);
updatePosition(e.clientX);
};
const handleMouseMove = (e) => {
if (dragging) updatePosition(e.clientX);
};
const handleMouseUp = () => setDragging(false);
const updatePosition = (clientX) => {
const track = trackRef.current;
if (!track) return;
const rect = track.getBoundingClientRect();
const x = Math.min(Math.max(clientX - rect.left, 0), rect.width);
const percent2 = x / rect.width;
const clampedValue = min + percent2 * (max - min);
const steppedValue = Math.round(clampedValue / step) * step;
const newValue = Math.min(Math.max(steppedValue, min), max);
setRangeValue(newValue);
onChange == null ? void 0 : onChange({
target: { value: newValue, name: inputProps.name }
});
};
return /* @__PURE__ */ jsxs3(
"div",
{
className: "glass-range-track",
ref: trackRef,
onMouseDown: handleMouseDown,
children: [
/* @__PURE__ */ jsx3(
"div",
{
className: "glass-range-fill",
style: {
width: `${percent}%`,
backgroundColor: inputProps.backgroundColor ? inputProps.backgroundColor : inputProps.borderColor ? inputProps.borderColor : "white",
opacity: dragging ? 0.7 : 1
}
}
),
/* @__PURE__ */ jsx3(
"div",
{
className: "glass-range-after-fill",
style: {
position: "absolute",
top: 0,
bottom: 0,
left: `calc(${percent > 96 ? 96 : percent}% + 30px)`,
width: `calc(${100 - percent}% - 30px)`,
backgroundColor: "rgba(255, 255, 255, 0.202)",
pointerEvents: "none"
}
}
),
/* @__PURE__ */ jsx3(
"div",
{
className: "glass-range-thumb",
style: {
left: `calc(${percent > 96 ? 96 : percent}% + 17px)`,
transform: `translate(-50%, -50%) scale(${dragging ? 1.4 : 1})`,
borderRadius: dragging ? inputProps.borderRadius ? inputProps.borderRadius + 1 : 2 : inputProps.borderRadius,
filter: `url(#${id}-filter)`,
backdropFilter: `blur(${inputProps.blur}px) saturate(${inputProps.saturation}%)`,
WebkitBackdropFilter: `blur(${inputProps.blur}px) saturate(${inputProps.saturation}%)`
},
onMouseDown: handleMouseDown
}
),
/* @__PURE__ */ jsx3(
"div",
{
className: "glass-range-thumb glass-range-border",
style: {
left: `calc(${percent > 96 ? 96 : percent}% + 17px)`,
border: `${(_e2 = inputProps.borderSize) != null ? _e2 : 1}px solid ${(_f2 = inputProps.borderColor) != null ? _f2 : "white"}`,
transform: `translate(-50%, -50%) scale(${dragging ? 1.4 : 1})`,
borderRadius: dragging ? inputProps.borderRadius ? inputProps.borderRadius + 1 : 2 : inputProps.borderRadius
}
}
),
percent > 96 ? /* @__PURE__ */ jsx3(
"div",
{
className: "glass-range-thumb",
style: {
left: `calc(96% + 17px)`,
transform: `translate(-50%, -50%) scale(${dragging ? 1.4 : 1})`,
backgroundColor: inputProps.backgroundColor ? inputProps.backgroundColor : inputProps.borderColor ? inputProps.borderColor : "white",
borderRadius: dragging ? inputProps.borderRadius ? inputProps.borderRadius + 1 : 2 : inputProps.borderRadius
}
}
) : ""
]
}
);
} else {
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
/* @__PURE__ */ jsx3(
"input",
{
value: inputProps.value,
type,
name: inputProps.name,
placeholder,
required,
autoFocus: autofocus,
multiple,
maxLength,
minLength,
className: `glass-input ${inputProps.contentCenter ? "content-center" : ""}`,
onChange: (e) => onChange ? onChange(e) : {},
style: {
color: inputProps.color,
padding: inputProps.padding
}
}
),
type === "file" ? /* @__PURE__ */ jsx3(
"span",
{
style: {
color: inputProps.color
},
className: `file-type-placeholder ${inputProps.contentCenter ? "content-center" : ""} ${inputProps.itemsCenter ? "items-center" : ""} ${inputProps.contentCenter || inputProps.itemsCenter ? "d-flex" : ""} ${inputProps.contentClassName ? inputProps.contentClassName : ""}`,
children: placeholder
}
) : ""
] });
}
};
return /* @__PURE__ */ jsxs3(
"div",
{
id: inputProps.id,
className: `glass-ui-input-container${inputProps.className ? ` ${inputProps.className}` : ""}`,
children: [
label && /* @__PURE__ */ jsx3("label", { className: "glass-ui-input-label", style: { color: labelColor }, children: label }),
/* @__PURE__ */ jsxs3(
"div",
{
ref: glassInputContainerRef,
className: "glass-ui-container",
onMouseEnter: handleOnMouseEnter,
onMouseLeave: handleOnMouseLeave,
style: {
color: inputProps.color,
width: inputProps.width,
height: type === "range" ? 30 : height,
borderRadius: inputProps.borderRadius,
transform: style.transform,
transition: isHovered ? "transform 80ms ease-out" : "transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5)",
willChange: "transform",
zIndex: inputProps.zIndex
},
children: [
renderLayers(
id,
(_b = inputProps.blur) != null ? _b : 1,
(_c = inputProps.borderRadius) != null ? _c : 8,
(_d = inputProps.saturation) != null ? _d : 100,
(_e = inputProps.brightness) != null ? _e : 100,
(_f = inputProps.distortion) != null ? _f : 50,
(_g = inputProps.backgroundColor) != null ? _g : "white",
(_h = inputProps.backgroundOpacity) != null ? _h : 0,
style,
(_i = inputProps.innerLightOpacity) != null ? _i : 0.2,
(_j = inputProps.outerLightOpacity) != null ? _j : 0.2,
(_l = (_k = inputProps.borderColor) != null ? _k : inputProps.innerLightColor) != null ? _l : "white",
(_m = inputProps.borderSize) != null ? _m : 1,
(_n = inputProps.borderOpacity) != null ? _n : 1,
(_o = inputProps.chromaticAberration) != null ? _o : 0,
(_p = inputProps.avoidSvgCreation) != null ? _p : false,
type
),
/* @__PURE__ */ jsx3(
"div",
{
ref: glassInputContentRef,
className: "glass-ui-input-content",
style: {
display: type === "range" ? "flex" : "block",
alignItems: "center",
justifyContent: "center",
borderRadius: inputProps.borderRadius
},
children: renderInput()
}
)
]
}
)
]
},
inputProps.key
);
};
// src/ui-elements/glass-button/index.tsx
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
import "./glass-button-Z4JXODNC.css";
import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
var GlassButton = (props) => {
var _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
const _a = __spreadValues(__spreadValues({}, glassDefaultProps), props), {
contentCenter = true,
itemsCenter = true,
children
} = _a, buttonProps = __objRest(_a, [
"contentCenter",
"itemsCenter",
"children"
]);
const id = useMemo3(() => {
var _a2;
return (_a2 = buttonProps.id) != null ? _a2 : crypto.randomUUID();
}, []);
const glassButtonContainerRef = useRef3(null);
const glassButtonContentRef = useRef3(null);
const [isHovered, setIsHovered] = useState3(false);
const [style, setStyle] = useState3({
transform: "none",
innerBoxShadow: `inset 0 0 ${buttonProps.innerLightBlur}px ${buttonProps.innerLightSpread}px ${buttonProps.innerLightColor}`,
outerBoxShadow: `0 0 ${buttonProps.outerLightBlur}px ${buttonProps.outerLightSpread}px ${buttonProps.outerLightColor}`
});
useEffect3(() => {
const input = glassButtonContainerRef.current;
if (!input) return;
const handleMouseMove = (e) => {
const result = calculateHoverEffect(e, input, buttonProps);
setStyle((prev) => __spreadValues(__spreadValues({}, prev), result));
};
const reset = () => {
setIsHovered(false);
setStyle({
transform: "none",
innerBoxShadow: `inset 0 0 ${buttonProps.innerLightBlur}px ${buttonProps.innerLightSpread}px ${buttonProps.innerLightColor}`,
outerBoxShadow: `0 0 ${buttonProps.outerLightBlur}px ${buttonProps.outerLightSpread}px ${buttonProps.outerLightColor}`
});
};
input.addEventListener("mousemove", handleMouseMove);
input.addEventListener("mouseleave", reset);
return () => {
input.removeEventListener("mousemove", handleMouseMove);
input.removeEventListener("mouseleave", reset);
};
}, [style]);
useEffect3(() => {
setStyle((prev) => __spreadProps(__spreadValues({}, prev), {
innerBoxShadow: `inset 0 0 ${buttonProps.innerLightBlur}px ${buttonProps.innerLightSpread}px ${buttonProps.innerLightColor}`,
outerBoxShadow: `0 0 ${buttonProps.outerLightBlur}px ${buttonProps.outerLightSpread}px ${buttonProps.outerLightColor}`
}));
}, [
buttonProps.innerLightBlur,
buttonProps.innerLightSpread,
buttonProps.innerLightColor,
buttonProps.outerLightBlur,
buttonProps.outerLightSpread,
buttonProps.outerLightColor
]);
const handleOnMouseEnter = () => {
setIsHovered(true);
};
const handleOnMouseLeave = () => {
setIsHovered(false);
};
return /* @__PURE__ */ jsx4(Fragment4, { children: /* @__PURE__ */ jsxs4(
"div",
{
id: buttonProps.id,
ref: glassButtonContainerRef,
className: `glass-ui-container ${buttonProps.className ? buttonProps.className : ""}`,
onClick: buttonProps.onClick,
onMouseEnter: handleOnMouseEnter,
onMouseLeave: handleOnMouseLeave,
style: {
color: buttonProps.color,
width: (_b = buttonProps.width) != null ? _b : "100%",
height: buttonProps.height,
borderRadius: buttonProps.borderRadius,
transform: style.transform,
transition: isHovered ? "transform 80ms ease-out" : "transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5)",
willChange: "transform",
zIndex: buttonProps.zIndex
},
children: [
renderLayers(
id,
(_c = buttonProps.blur) != null ? _c : 1,
(_d = buttonProps.borderRadius) != null ? _d : 8,
(_e = buttonProps.saturation) != null ? _e : 100,
(_f = buttonProps.brightness) != null ? _f : 100,
(_g = buttonProps.distortion) != null ? _g : 50,
(_h = buttonProps.backgroundColor) != null ? _h : "white",
(_i = buttonProps.backgroundOpacity) != null ? _i : 0,
style,
(_j = buttonProps.innerLightOpacity) != null ? _j : 0.2,
(_k = buttonProps.outerLightOpacity) != null ? _k : 0.2,
(_m = (_l = buttonProps.borderColor) != null ? _l : buttonProps.innerLightColor) != null ? _m : "white",
(_n = buttonProps.borderSize) != null ? _n : 1,
(_o = buttonProps.borderOpacity) != null ? _o : 1,
(_p = buttonProps.chromaticAberration) != null ? _p : 0,
(_q = buttonProps.avoidSvgCreation) != null ? _q : false
),
/* @__PURE__ */ jsx4(
"div",
{
ref: glassButtonContentRef,
className: `glass-ui-button-content ${contentCenter ? "content-center" : ""} ${itemsCenter ? "items-center" : ""} ${contentCenter || itemsCenter ? "d-flex" : ""} ${buttonProps.contentClassName ? buttonProps.contentClassName : ""}`,
style: {
padding: buttonProps.padding,
borderRadius: buttonProps.borderSize
},
children
}
)
]
},
buttonProps.key
) });
};
export {
GlassButton,
GlassCard,
GlassInput
};