@homecode/ui 5.20.22 → 5.20.24

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.
@@ -6,8 +6,14 @@ import { Button } from '../Button/Button.js';
6
6
  import { Icon } from '../Icon/Icon.js';
7
7
  import S from './LightBox.styl.js';
8
8
 
9
+ /** Matches the fade-out in LightBox.styl: the blur stays until it ends. */
10
+ const FADE_MS = 200;
9
11
  function LightBox({ children, className, onClose, blur, ...props }) {
10
12
  const [isOpen, setOpen] = useState(false);
13
+ // A closed light box stays mounted at opacity 0, and an invisible
14
+ // full-screen blur still costs a backdrop pass every frame (a list of cards,
15
+ // each with its own light box, stalled the page). Blur only while it shows.
16
+ const [blurOn, setBlurOn] = useState(false);
11
17
  const onKeyDown = useCallback(e => {
12
18
  if (isOpen && e.key === 'Escape') {
13
19
  e.stopPropagation();
@@ -18,11 +24,19 @@ function LightBox({ children, className, onClose, blur, ...props }) {
18
24
  useEffect(() => {
19
25
  setOpen(props.isOpen);
20
26
  }, [props.isOpen]);
27
+ useEffect(() => {
28
+ if (isOpen) {
29
+ setBlurOn(true);
30
+ return;
31
+ }
32
+ const timer = setTimeout(() => setBlurOn(false), FADE_MS);
33
+ return () => clearTimeout(timer);
34
+ }, [isOpen]);
21
35
  useEffect(() => {
22
36
  document.addEventListener('keydown', onKeyDown, true);
23
37
  return () => document.removeEventListener('keydown', onKeyDown, true);
24
38
  }, [isOpen]);
25
- return (jsxs(Paranja, { className: cn(S.root, isOpen && S.open, className), blur: blur, children: [children, jsx(Button, { className: S.close, onClick: onClose, variant: "clear", children: jsx(Icon, { type: "close", size: "l" }) })] }));
39
+ return (jsxs(Paranja, { className: cn(S.root, isOpen && S.open, className), blur: blur && blurOn, children: [children, jsx(Button, { className: S.close, onClick: onClose, variant: "clear", children: jsx(Icon, { type: "close", size: "l" }) })] }));
26
40
  }
27
41
 
28
42
  export { LightBox };
@@ -503,7 +503,10 @@ class Popup extends Component {
503
503
  const wrapperClasses = cn(S.contentWrapper, inline && S.inline, isOpen && S.isOpen, animating && S.animating, wrapperProps.className);
504
504
  const trigger = this.triggerElem.current;
505
505
  const [axis, float] = direction.split('-');
506
- const classes = cn(S.content, outlined && S.outlined, animated && animating && S.animating, elevation && S[`elevation-${elevation}`], S[`size-${size}`], S[`axis-${axis}`], S[`float-${float || 'middle'}`], blur && S.blur, round && S.round, contentProps.className);
506
+ const classes = cn(S.content, outlined && S.outlined, animated && animating && S.animating, elevation && S[`elevation-${elevation}`], S[`size-${size}`], S[`axis-${axis}`], S[`float-${float || 'middle'}`],
507
+ // A closed popup stays mounted at opacity 0; its blur would still cost
508
+ // a backdrop pass every frame, so blur only while the content is shown.
509
+ blur && isContentVisible && S.blur, round && S.round, contentProps.className);
507
510
  if (trigger && !inline && triggerBounds) {
508
511
  const shiftTf = boundaryFit.left !== 0 || boundaryFit.top !== 0
509
512
  ? `translate3d(${boundaryFit.left}px, ${boundaryFit.top}px, 0)`
@@ -1,10 +1,31 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import cn from 'classnames';
3
3
  import S from './ThinkingOutline.styl.js';
4
4
 
5
- function ThinkingOutline({ active, className }) {
5
+ const BASE_DURATION = 3.5; // seconds per lap at speed 1
6
+ const DEFAULT_GRADIENTS = [{}];
7
+ const toSize = (size) => typeof size === 'number' ? `${size}px` : size;
8
+ // Unset values stay undefined so the stylesheet defaults (and the root's vars) apply
9
+ const glowVars = (thickness, spread) => ({
10
+ '--tol-thickness': thickness,
11
+ '--tol-spread': toSize(spread),
12
+ });
13
+ function getLayerStyle({ color, speed = 1, reverse, phase = 0, thickness, spread, }) {
14
+ const duration = BASE_DURATION / (speed > 0 ? speed : 1);
15
+ return {
16
+ ...glowVars(thickness, spread),
17
+ '--tol-color': color,
18
+ '--tol-color-soft': color && `color-mix(in srgb, ${color} 30%, transparent)`,
19
+ '--tol-duration': speed !== 1 ? `${duration}s` : undefined,
20
+ // Negative delay starts the orbit part-way through a lap
21
+ '--tol-delay': phase ? `${-phase * duration}s` : undefined,
22
+ '--tol-direction': reverse ? 'reverse' : undefined,
23
+ };
24
+ }
25
+ function ThinkingOutline({ active, gradients, thickness, spread, className, }) {
6
26
  const isControlled = active !== undefined;
7
- return (jsx("div", { className: cn(S.root, isControlled && active && S.active, !isControlled && S.interactive, className), children: jsx("div", { className: S.bloom }) }));
27
+ const layers = gradients?.length ? gradients : DEFAULT_GRADIENTS;
28
+ return (jsx("div", { className: cn(S.root, isControlled && active && S.active, !isControlled && S.interactive, className), style: glowVars(thickness, spread), children: layers.map((gradient, i) => (jsxs("div", { className: S.layer, style: getLayerStyle(gradient), children: [jsx("div", { className: S.halo }), jsx("div", { className: S.bloom })] }, i))) }));
8
29
  }
9
30
 
10
31
  export { ThinkingOutline };
@@ -1,5 +1,5 @@
1
- var css_248z = "@property --promptGlowAngle{syntax:\"<angle>\";inherits:true;initial-value:0deg}.ThinkingOutline_root__rvvBG{animation:ThinkingOutline_orbitGlow__3bK-F 3.5s linear infinite;animation-play-state:paused;border-radius:inherit;inset:0;opacity:0;pointer-events:none;position:absolute;transition:opacity .5s ease-out}.ThinkingOutline_root__rvvBG.ThinkingOutline_interactive__3jMCg{pointer-events:auto}.ThinkingOutline_root__rvvBG.ThinkingOutline_active__-66iV,.ThinkingOutline_root__rvvBG.ThinkingOutline_interactive__3jMCg:hover{animation-play-state:running;opacity:1}.ThinkingOutline_root__rvvBG:before{background:conic-gradient(from var(--promptGlowAngle),var(--active-color) 0deg,var(--active-color-alpha-300) 48deg,transparent 80deg,transparent 100deg,var(--active-color-alpha-300) 132deg,var(--active-color) 180deg,var(--active-color-alpha-300) 228deg,transparent 260deg,transparent 280deg,var(--active-color-alpha-300) 312deg,var(--active-color) 1turn);border-radius:inherit;content:\"\";inset:0;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:1.5px;position:absolute}.ThinkingOutline_bloom__XKYD5{border-radius:inherit;filter:blur(20px);inset:0;opacity:.55;position:absolute}.ThinkingOutline_bloom__XKYD5:before{background:conic-gradient(from var(--promptGlowAngle),var(--active-color) 0deg,var(--active-color-alpha-300) 48deg,transparent 80deg,transparent 100deg,var(--active-color-alpha-300) 132deg,var(--active-color) 180deg,var(--active-color-alpha-300) 228deg,transparent 260deg,transparent 280deg,var(--active-color-alpha-300) 312deg,var(--active-color) 1turn);border-radius:inherit;content:\"\";inset:0;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:6px;position:absolute}@media (prefers-reduced-motion:reduce){.ThinkingOutline_root__rvvBG{animation:none}}@keyframes ThinkingOutline_orbitGlow__3bK-F{0%{--promptGlowAngle:-30deg}25%{--promptGlowAngle:30deg}50%{--promptGlowAngle:150deg}75%{--promptGlowAngle:210deg}to{--promptGlowAngle:330deg}}";
2
- var S = {"root":"ThinkingOutline_root__rvvBG","orbitGlow":"ThinkingOutline_orbitGlow__3bK-F","interactive":"ThinkingOutline_interactive__3jMCg","active":"ThinkingOutline_active__-66iV","bloom":"ThinkingOutline_bloom__XKYD5"};
1
+ var css_248z = "@property --promptGlowAngle{syntax:\"<angle>\";inherits:true;initial-value:0deg}.ThinkingOutline_root__rvvBG{border-radius:inherit;inset:0;opacity:0;pointer-events:none;position:absolute;transition:opacity .5s ease-out}.ThinkingOutline_root__rvvBG.ThinkingOutline_interactive__3jMCg{pointer-events:auto}.ThinkingOutline_root__rvvBG.ThinkingOutline_active__-66iV,.ThinkingOutline_root__rvvBG.ThinkingOutline_interactive__3jMCg:hover{opacity:1}.ThinkingOutline_root__rvvBG.ThinkingOutline_active__-66iV .ThinkingOutline_layer__lDYzJ,.ThinkingOutline_root__rvvBG.ThinkingOutline_interactive__3jMCg:hover .ThinkingOutline_layer__lDYzJ{animation-play-state:running}.ThinkingOutline_layer__lDYzJ{--tol-source:calc(6px*var(--tol-thickness, 1));--tol-outset:calc(var(--tol-source) - 6px);--tol-halo:calc(3px*var(--tol-thickness, 1));animation:ThinkingOutline_orbitGlow__3bK-F 3.5s linear infinite;animation:ThinkingOutline_orbitGlow__3bK-F var(--tol-duration,3.5s) linear infinite;animation-delay:0s;animation-delay:var(--tol-delay,0s);animation-direction:normal;animation-direction:var(--tol-direction,normal);animation-play-state:paused;border-radius:inherit;inset:0;position:absolute}.ThinkingOutline_layer__lDYzJ:before{background:conic-gradient(from var(--promptGlowAngle),var(--tol-color,var(--active-color)) 0deg,var(--tol-color-soft,var(--active-color-alpha-300)) 48deg,transparent 80deg,transparent 100deg,var(--tol-color-soft,var(--active-color-alpha-300)) 132deg,var(--tol-color,var(--active-color)) 180deg,var(--tol-color-soft,var(--active-color-alpha-300)) 228deg,transparent 260deg,transparent 280deg,var(--tol-color-soft,var(--active-color-alpha-300)) 312deg,var(--tol-color,var(--active-color)) 1turn);border-radius:inherit;content:\"\";inset:0;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:1.5px;padding:var(--tol-line,1.5px);position:absolute}.ThinkingOutline_bloom__XKYD5{border-radius:inherit;filter:blur(20px);filter:blur(var(--tol-spread,20px));inset:0;opacity:min(1,.55);opacity:min(1,calc(var(--tol-thickness, 1)*.55));position:absolute}.ThinkingOutline_bloom__XKYD5:before{background:conic-gradient(from var(--promptGlowAngle),var(--tol-color,var(--active-color)) 0deg,var(--tol-color-soft,var(--active-color-alpha-300)) 48deg,transparent 80deg,transparent 100deg,var(--tol-color-soft,var(--active-color-alpha-300)) 132deg,var(--tol-color,var(--active-color)) 180deg,var(--tol-color-soft,var(--active-color-alpha-300)) 228deg,transparent 260deg,transparent 280deg,var(--tol-color-soft,var(--active-color-alpha-300)) 312deg,var(--tol-color,var(--active-color)) 1turn);border-radius:inherit;content:\"\";inset:calc(var(--tol-outset)*-1);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:var(--tol-source);position:absolute}.ThinkingOutline_halo__tD2oJ{border-radius:inherit;filter:blur(6px);filter:blur(calc(var(--tol-spread, 20px)*.3));inset:0;opacity:clamp(0,0,1);opacity:clamp(0,calc((var(--tol-thickness, 1) - 1)*.5),1);position:absolute}.ThinkingOutline_halo__tD2oJ:before{background:conic-gradient(from var(--promptGlowAngle),var(--tol-color,var(--active-color)) 0deg,var(--tol-color-soft,var(--active-color-alpha-300)) 48deg,transparent 80deg,transparent 100deg,var(--tol-color-soft,var(--active-color-alpha-300)) 132deg,var(--tol-color,var(--active-color)) 180deg,var(--tol-color-soft,var(--active-color-alpha-300)) 228deg,transparent 260deg,transparent 280deg,var(--tol-color-soft,var(--active-color-alpha-300)) 312deg,var(--tol-color,var(--active-color)) 1turn);border-radius:inherit;content:\"\";inset:calc(var(--tol-halo)*-1);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:calc(var(--tol-halo) + 1.5px);position:absolute}@media (prefers-reduced-motion:reduce){.ThinkingOutline_layer__lDYzJ{animation:none}}@keyframes ThinkingOutline_orbitGlow__3bK-F{0%{--promptGlowAngle:-30deg}25%{--promptGlowAngle:30deg}50%{--promptGlowAngle:150deg}75%{--promptGlowAngle:210deg}to{--promptGlowAngle:330deg}}";
2
+ var S = {"root":"ThinkingOutline_root__rvvBG","interactive":"ThinkingOutline_interactive__3jMCg","active":"ThinkingOutline_active__-66iV","layer":"ThinkingOutline_layer__lDYzJ","orbitGlow":"ThinkingOutline_orbitGlow__3bK-F","bloom":"ThinkingOutline_bloom__XKYD5","halo":"ThinkingOutline_halo__tD2oJ"};
3
3
  if (typeof document !== 'undefined') {
4
4
  var __uilibHead = document.head || document.getElementsByTagName('head')[0];
5
5
  if (__uilibHead) {
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -1,3 +1,3 @@
1
- import { ThinkingOutlineProps } from './ThinkingOutline.types';
2
- export type { ThinkingOutlineProps };
3
- export declare function ThinkingOutline({ active, className }: ThinkingOutlineProps): import("react").JSX.Element;
1
+ import { ThinkingOutlineGradient, ThinkingOutlineProps, ThinkingOutlineSize } from './ThinkingOutline.types';
2
+ export type { ThinkingOutlineGradient, ThinkingOutlineProps, ThinkingOutlineSize, };
3
+ export declare function ThinkingOutline({ active, gradients, thickness, spread, className, }: ThinkingOutlineProps): import("react").JSX.Element;
@@ -1,4 +1,16 @@
1
+ export type ThinkingOutlineSize = number | string;
2
+ export type ThinkingOutlineGradient = {
3
+ color?: string;
4
+ speed?: number;
5
+ reverse?: boolean;
6
+ phase?: number;
7
+ thickness?: number;
8
+ spread?: ThinkingOutlineSize;
9
+ };
1
10
  export type ThinkingOutlineProps = {
2
11
  active?: boolean;
12
+ gradients?: ThinkingOutlineGradient[];
13
+ thickness?: number;
14
+ spread?: ThinkingOutlineSize;
3
15
  className?: string;
4
16
  };
@@ -1,2 +1,2 @@
1
1
  export { ThinkingOutline } from './ThinkingOutline';
2
- export type { ThinkingOutlineProps } from './ThinkingOutline';
2
+ export type { ThinkingOutlineGradient, ThinkingOutlineProps, ThinkingOutlineSize, } from './ThinkingOutline';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "5.20.22",
3
+ "version": "5.20.24",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "tests": "jest",