UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

155 lines (152 loc) • 4.24 kB
import { sampleCurve } from "./curves.mjs"; import { VIEW_BASE, domStyle } from "../web/DomView.mjs"; import { resolveEdges, resolveRadius } from "./normalize.mjs"; import { jsx, jsxs } from "react/jsx-runtime"; const EDGES = [ "top", "bottom", "left", "right" ]; const DIRECTIONS = { top: "to bottom", bottom: "to top", left: "to right", right: "to left" }; function curveStops(edge, paint) { const alphas = sampleCurve(edge.curve); const last = alphas.length - 1; return alphas.map((_, index) => { const visible = alphas[last - index] ?? 0; return `${paint(visible)} ${(index / last * edge.size).toFixed(2)}px`; }); } function edgeMask(name, edge) { const stops = curveStops(edge, (visible) => `rgba(0,0,0,${visible})`); return `linear-gradient(${DIRECTIONS[name]}, ${stops.join(", ")}, black ${edge.size}px)`; } function stripLayout(name, size) { const depth = Math.max(0, size); const base = { position: "absolute", pointerEvents: "none" }; switch (name) { case "top": return { ...base, top: 0, left: 0, right: 0, height: depth }; case "bottom": return { ...base, bottom: 0, left: 0, right: 0, height: depth }; case "left": return { ...base, top: 0, bottom: 0, left: 0, width: depth }; case "right": return { ...base, top: 0, bottom: 0, right: 0, width: depth }; } } function stripGradient(name, edge, paint) { const alphas = sampleCurve(edge.curve); const last = alphas.length - 1; const stops = alphas.map((_, index) => { const visible = alphas[last - index] ?? 0; return `${paint(visible)} ${(index / last * 100).toFixed(2)}%`; }); return `linear-gradient(${DIRECTIONS[name]}, ${stops.join(", ")})`; } function colorPaint(color) { return (visible) => `color-mix(in srgb, ${String(color)} ${((1 - visible) * 100).toFixed(2)}%, transparent)`; } function documentIsRTL() { return typeof document !== "undefined" && document.documentElement.dir === "rtl"; } function EdgeFade(props) { const resolved = resolveEdges(props, documentIsRTL()); const { top: _top, bottom: _bottom, left: _left, right: _right, start: _start, end: _end, size: _size, curve: _curve, mode: _mode, color: _color, blurRadius: _blurRadius, frostProgression: _frostProgression, radius, style, children, testID, nativeID } = props; const { borderRadius: styleRadius, ...cleanStyle } = domStyle(style); const resolvedRadius = resolveRadius(radius, styleRadius); const box = { ...VIEW_BASE, ...cleanStyle, ...resolvedRadius != null && { borderRadius: resolvedRadius, overflow: "hidden" } }; const hostProps = { "data-testid": testID, id: nativeID }; const edges = EDGES.flatMap((name) => { const edge = resolved[name]; return edge ? [{ name, edge }] : []; }); if (resolved.mode === "mask") { const maskImage = edges.map(({ name, edge }) => edgeMask(name, edge)).join(", "); const maskStyle = edges.length ? { maskImage, maskComposite: "intersect", maskRepeat: "no-repeat" } : {}; return /* @__PURE__ */ jsx("div", { ...hostProps, style: { ...box, ...maskStyle }, children }); } if (resolved.mode === "overlay") { const fallback = resolved.color ?? "black"; return /* @__PURE__ */ jsxs("div", { ...hostProps, style: box, children: [children, edges.map(({ name, edge }) => /* @__PURE__ */ jsx("div", { style: { ...stripLayout(name, edge.size), backgroundImage: stripGradient(name, edge, colorPaint(edge.color ?? fallback)) } }, name))] }); } const veil = resolved.color; return /* @__PURE__ */ jsxs("div", { ...hostProps, style: box, children: [children, edges.map(({ name, edge }) => { const reach = resolved.frostProgression; const blurMask = stripGradient(name, edge, (visible) => { const strength = Math.min(1, (1 - visible) / reach); return `rgba(0,0,0,${strength.toFixed(4)})`; }); return /* @__PURE__ */ jsx("div", { style: { ...stripLayout(name, edge.size), backdropFilter: `blur(${resolved.blurRadius}px)`, maskImage: blurMask, backgroundImage: veil ? stripGradient(name, edge, colorPaint(veil)) : void 0 } }, name); })] }); } export { EdgeFade }; //# sourceMappingURL=EdgeFade.mjs.map