@carbon-labs/react-animated-header 0.42.0 → 0.43.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.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright IBM Corp. 2025
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import React from 'react';
10
+ export interface AnimatedBackgroundProps {
11
+ headerAnimation?: object;
12
+ isOpen: boolean;
13
+ }
14
+ declare const AnimatedBackground: React.FC<AnimatedBackgroundProps>;
15
+ export default AnimatedBackground;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React, { useRef, useEffect } from 'react';
9
+ import lottie from 'lottie-web';
10
+ import { usePrefix } from '@carbon-labs/utilities/usePrefix';
11
+
12
+ const AnimatedBackground = ({
13
+ headerAnimation,
14
+ isOpen
15
+ }) => {
16
+ const prefix = usePrefix();
17
+ const blockClass = `${prefix}--animated-header__lottie-animation`;
18
+ const animationContainer = useRef(null);
19
+ const animRef = useRef(null);
20
+ const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
21
+ useEffect(() => {
22
+ // Make sure any prior instance is destroyed before creating a new one
23
+ if (animRef.current) {
24
+ animRef.current.destroy();
25
+ animRef.current = null;
26
+ }
27
+ if (!animationContainer.current || !headerAnimation) {
28
+ return;
29
+ }
30
+ const animation = lottie.loadAnimation({
31
+ container: animationContainer.current,
32
+ animationData: headerAnimation,
33
+ renderer: 'svg',
34
+ loop: false,
35
+ autoplay: false,
36
+ rendererSettings: {
37
+ preserveAspectRatio: 'xMidYMid slice'
38
+ }
39
+ });
40
+ animRef.current = animation;
41
+ animation.setSpeed(1);
42
+ const onDomLoaded = () => {
43
+ const totalFrames = animation.getDuration(true);
44
+ if (isReduced) {
45
+ animation.goToAndStop(totalFrames, true);
46
+ } else {
47
+ animation.play();
48
+ }
49
+ };
50
+ animation.addEventListener('DOMLoaded', onDomLoaded);
51
+ return () => {
52
+ animation.removeEventListener('DOMLoaded', onDomLoaded);
53
+ animation.destroy();
54
+ animRef.current = null;
55
+ };
56
+ // Re-init when the JSON or reduced-motion preference changes
57
+ }, [headerAnimation, isReduced]);
58
+ return /*#__PURE__*/React.createElement("div", {
59
+ className: `${blockClass}--container`
60
+ }, /*#__PURE__*/React.createElement("div", {
61
+ ref: animationContainer,
62
+ className: `${blockClass}`,
63
+ "data-expanded": isOpen,
64
+ "aria-hidden": "true"
65
+ }));
66
+ };
67
+
68
+ export { AnimatedBackground as default };
@@ -6,9 +6,8 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React, { useRef, useState, useEffect } from 'react';
9
+ import React, { useState, Suspense, lazy } from 'react';
10
10
  import PropTypes from 'prop-types';
11
- import lottie from 'lottie-web';
12
11
  import { Grid, Column, Button } from '@carbon/react';
13
12
  import { ChevronUp, ChevronDown } from '@carbon/icons-react';
14
13
  import { usePrefix } from '@carbon-labs/utilities/usePrefix';
@@ -17,9 +16,12 @@ import { BaseTile } from '../Tiles/BaseTile/BaseTile.js';
17
16
  import TasksController from '../TasksController/TasksController.js';
18
17
  import WorkspaceSelector from '../WorkspaceSelector/WorkspaceSelector.js';
19
18
  import HeaderTitle from '../HeaderTitle/HeaderTitle.js';
19
+ import StaticBackground from '../StaticBackground/StaticBackground.js';
20
20
  import ContentSwitcherSelector from '../ContentSwitcherSelector/ContentSwitcherSelector.js';
21
21
  import HeaderAction from '../HeaderAction/HeaderAction.js';
22
22
 
23
+ const AnimatedBackground = /*#__PURE__*/lazy(() => import('../AnimatedBackground/AnimatedBackground.js'));
24
+
23
25
  /** Animated Header */
24
26
 
25
27
  const AnimatedHeader = ({
@@ -45,62 +47,10 @@ const AnimatedHeader = ({
45
47
  }) => {
46
48
  const prefix = usePrefix();
47
49
  const blockClass = `${prefix}--animated-header`;
48
- const animationContainer = useRef(null);
49
- const animRef = useRef(null);
50
50
  const [isOpen, setIsOpen] = useState(true);
51
- const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
52
51
  const handleButtonCollapseClick = () => {
53
52
  setIsOpen(!isOpen);
54
53
  };
55
- useEffect(() => {
56
- // Make sure any prior instance is destroyed before creating a new one
57
- if (animRef.current) {
58
- animRef.current.destroy();
59
- animRef.current = null;
60
- }
61
- if (!animationContainer.current || !headerAnimation) {
62
- return;
63
- }
64
- const animation = lottie.loadAnimation({
65
- container: animationContainer.current,
66
- animationData: headerAnimation,
67
- renderer: 'svg',
68
- loop: false,
69
- autoplay: false,
70
- rendererSettings: {
71
- preserveAspectRatio: 'xMidYMid slice'
72
- }
73
- });
74
- animRef.current = animation;
75
- const onDomLoaded = () => {
76
- const data = animation.animationData;
77
- const markers = data?.markers ?? [];
78
- const first = markers?.[0]?.tm ?? 0;
79
- const totalFrames = animation.getDuration(true);
80
- const second = markers?.[1]?.tm ?? totalFrames;
81
- if (isReduced) {
82
- // Respect reduced motion
83
- const restFrame = (typeof second === 'number' ? second : totalFrames * 0.5) | 0;
84
- animation.goToAndStop(restFrame, true);
85
- return;
86
- }
87
- animation.setSpeed(1);
88
- requestAnimationFrame(() => {
89
- if (typeof first === 'number' && typeof second === 'number') {
90
- animation.playSegments([first, second], true);
91
- } else {
92
- animation.play();
93
- }
94
- });
95
- };
96
- animation.addEventListener('DOMLoaded', onDomLoaded);
97
- return () => {
98
- animation.removeEventListener('DOMLoaded', onDomLoaded);
99
- animation.destroy();
100
- animRef.current = null;
101
- };
102
- // Re-init when the JSON or reduced-motion preference changes
103
- }, [headerAnimation, isReduced]);
104
54
  return /*#__PURE__*/React.createElement("header", {
105
55
  className: blockClass,
106
56
  "data-expanded": isOpen
@@ -110,24 +60,14 @@ const AnimatedHeader = ({
110
60
  className: `${blockClass}__gradient--overlay`
111
61
  }), /*#__PURE__*/React.createElement("div", {
112
62
  className: `${blockClass}__container--gradient`
113
- }), !headerAnimation && headerStatic && /*#__PURE__*/React.createElement("div", {
114
- className: `${blockClass}__static--container`
115
- }, /*#__PURE__*/React.createElement("div", {
116
- className: `${blockClass}__static`
117
- // eslint-disable-next-line react/forbid-dom-props
118
- ,
119
- style: {
120
- backgroundImage: `url(${headerStatic})`
121
- },
122
- "aria-hidden": "true"
123
- })), /*#__PURE__*/React.createElement("div", {
124
- className: `${blockClass}__lottie-animation--container`
125
- }, /*#__PURE__*/React.createElement("div", {
126
- ref: animationContainer,
127
- className: `${blockClass}__lottie-animation`,
128
- "data-expanded": isOpen,
129
- "aria-hidden": "true"
130
- })), /*#__PURE__*/React.createElement(Column, {
63
+ }), headerAnimation ? typeof window !== 'undefined' && /*#__PURE__*/React.createElement(Suspense, {
64
+ fallback: null
65
+ }, /*#__PURE__*/React.createElement(AnimatedBackground, {
66
+ headerAnimation: headerAnimation,
67
+ isOpen: isOpen
68
+ })) : /*#__PURE__*/React.createElement(StaticBackground, {
69
+ headerStatic: headerStatic
70
+ }), /*#__PURE__*/React.createElement(Column, {
131
71
  sm: 4,
132
72
  md: 8,
133
73
  lg: 16,
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface StaticBackgroundProps {
3
+ headerStatic?: React.JSX.Element | string;
4
+ }
5
+ declare const StaticBackground: React.FC<StaticBackgroundProps>;
6
+ export default StaticBackground;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { usePrefix } from '@carbon-labs/utilities/usePrefix';
9
+ import React from 'react';
10
+
11
+ const StaticBackground = ({
12
+ headerStatic
13
+ }) => {
14
+ const prefix = usePrefix();
15
+ const blockClass = `${prefix}--animated-header__static`;
16
+ if (!headerStatic) {
17
+ return null;
18
+ }
19
+ return /*#__PURE__*/React.createElement("div", {
20
+ className: `${blockClass}--container`
21
+ }, /*#__PURE__*/React.createElement("div", {
22
+ className: `${blockClass}`
23
+ // eslint-disable-next-line react/forbid-dom-props
24
+ ,
25
+ style: {
26
+ backgroundImage: `url(${headerStatic})`
27
+ },
28
+ "aria-hidden": "true"
29
+ }));
30
+ };
31
+
32
+ export { StaticBackground as default };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright IBM Corp. 2025
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import React from 'react';
10
+ export interface AnimatedBackgroundProps {
11
+ headerAnimation?: object;
12
+ isOpen: boolean;
13
+ }
14
+ declare const AnimatedBackground: React.FC<AnimatedBackgroundProps>;
15
+ export default AnimatedBackground;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var React = require('react');
13
+ var lottie = require('lottie-web');
14
+ var usePrefix = require('@carbon-labs/utilities/usePrefix');
15
+
16
+ const AnimatedBackground = ({
17
+ headerAnimation,
18
+ isOpen
19
+ }) => {
20
+ const prefix = usePrefix.usePrefix();
21
+ const blockClass = `${prefix}--animated-header__lottie-animation`;
22
+ const animationContainer = React.useRef(null);
23
+ const animRef = React.useRef(null);
24
+ const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
25
+ React.useEffect(() => {
26
+ // Make sure any prior instance is destroyed before creating a new one
27
+ if (animRef.current) {
28
+ animRef.current.destroy();
29
+ animRef.current = null;
30
+ }
31
+ if (!animationContainer.current || !headerAnimation) {
32
+ return;
33
+ }
34
+ const animation = lottie.loadAnimation({
35
+ container: animationContainer.current,
36
+ animationData: headerAnimation,
37
+ renderer: 'svg',
38
+ loop: false,
39
+ autoplay: false,
40
+ rendererSettings: {
41
+ preserveAspectRatio: 'xMidYMid slice'
42
+ }
43
+ });
44
+ animRef.current = animation;
45
+ animation.setSpeed(1);
46
+ const onDomLoaded = () => {
47
+ const totalFrames = animation.getDuration(true);
48
+ if (isReduced) {
49
+ animation.goToAndStop(totalFrames, true);
50
+ } else {
51
+ animation.play();
52
+ }
53
+ };
54
+ animation.addEventListener('DOMLoaded', onDomLoaded);
55
+ return () => {
56
+ animation.removeEventListener('DOMLoaded', onDomLoaded);
57
+ animation.destroy();
58
+ animRef.current = null;
59
+ };
60
+ // Re-init when the JSON or reduced-motion preference changes
61
+ }, [headerAnimation, isReduced]);
62
+ return /*#__PURE__*/React.createElement("div", {
63
+ className: `${blockClass}--container`
64
+ }, /*#__PURE__*/React.createElement("div", {
65
+ ref: animationContainer,
66
+ className: `${blockClass}`,
67
+ "data-expanded": isOpen,
68
+ "aria-hidden": "true"
69
+ }));
70
+ };
71
+
72
+ exports.default = AnimatedBackground;
@@ -12,7 +12,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
12
12
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
13
  var React = require('react');
14
14
  var PropTypes = require('prop-types');
15
- var lottie = require('lottie-web');
16
15
  var react = require('@carbon/react');
17
16
  var iconsReact = require('@carbon/icons-react');
18
17
  var usePrefix = require('@carbon-labs/utilities/usePrefix');
@@ -21,9 +20,12 @@ var BaseTile = require('../Tiles/BaseTile/BaseTile.js');
21
20
  var TasksController = require('../TasksController/TasksController.js');
22
21
  var WorkspaceSelector = require('../WorkspaceSelector/WorkspaceSelector.js');
23
22
  var HeaderTitle = require('../HeaderTitle/HeaderTitle.js');
23
+ var StaticBackground = require('../StaticBackground/StaticBackground.js');
24
24
  var ContentSwitcherSelector = require('../ContentSwitcherSelector/ContentSwitcherSelector.js');
25
25
  var HeaderAction = require('../HeaderAction/HeaderAction.js');
26
26
 
27
+ const AnimatedBackground = /*#__PURE__*/React.lazy(() => Promise.resolve().then(function () { return require('../AnimatedBackground/AnimatedBackground.js'); }));
28
+
27
29
  /** Animated Header */
28
30
 
29
31
  const AnimatedHeader = ({
@@ -49,62 +51,10 @@ const AnimatedHeader = ({
49
51
  }) => {
50
52
  const prefix = usePrefix.usePrefix();
51
53
  const blockClass = `${prefix}--animated-header`;
52
- const animationContainer = React.useRef(null);
53
- const animRef = React.useRef(null);
54
54
  const [isOpen, setIsOpen] = React.useState(true);
55
- const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
56
55
  const handleButtonCollapseClick = () => {
57
56
  setIsOpen(!isOpen);
58
57
  };
59
- React.useEffect(() => {
60
- // Make sure any prior instance is destroyed before creating a new one
61
- if (animRef.current) {
62
- animRef.current.destroy();
63
- animRef.current = null;
64
- }
65
- if (!animationContainer.current || !headerAnimation) {
66
- return;
67
- }
68
- const animation = lottie.loadAnimation({
69
- container: animationContainer.current,
70
- animationData: headerAnimation,
71
- renderer: 'svg',
72
- loop: false,
73
- autoplay: false,
74
- rendererSettings: {
75
- preserveAspectRatio: 'xMidYMid slice'
76
- }
77
- });
78
- animRef.current = animation;
79
- const onDomLoaded = () => {
80
- const data = animation.animationData;
81
- const markers = data?.markers ?? [];
82
- const first = markers?.[0]?.tm ?? 0;
83
- const totalFrames = animation.getDuration(true);
84
- const second = markers?.[1]?.tm ?? totalFrames;
85
- if (isReduced) {
86
- // Respect reduced motion
87
- const restFrame = (typeof second === 'number' ? second : totalFrames * 0.5) | 0;
88
- animation.goToAndStop(restFrame, true);
89
- return;
90
- }
91
- animation.setSpeed(1);
92
- requestAnimationFrame(() => {
93
- if (typeof first === 'number' && typeof second === 'number') {
94
- animation.playSegments([first, second], true);
95
- } else {
96
- animation.play();
97
- }
98
- });
99
- };
100
- animation.addEventListener('DOMLoaded', onDomLoaded);
101
- return () => {
102
- animation.removeEventListener('DOMLoaded', onDomLoaded);
103
- animation.destroy();
104
- animRef.current = null;
105
- };
106
- // Re-init when the JSON or reduced-motion preference changes
107
- }, [headerAnimation, isReduced]);
108
58
  return /*#__PURE__*/React.createElement("header", {
109
59
  className: blockClass,
110
60
  "data-expanded": isOpen
@@ -114,24 +64,14 @@ const AnimatedHeader = ({
114
64
  className: `${blockClass}__gradient--overlay`
115
65
  }), /*#__PURE__*/React.createElement("div", {
116
66
  className: `${blockClass}__container--gradient`
117
- }), !headerAnimation && headerStatic && /*#__PURE__*/React.createElement("div", {
118
- className: `${blockClass}__static--container`
119
- }, /*#__PURE__*/React.createElement("div", {
120
- className: `${blockClass}__static`
121
- // eslint-disable-next-line react/forbid-dom-props
122
- ,
123
- style: {
124
- backgroundImage: `url(${headerStatic})`
125
- },
126
- "aria-hidden": "true"
127
- })), /*#__PURE__*/React.createElement("div", {
128
- className: `${blockClass}__lottie-animation--container`
129
- }, /*#__PURE__*/React.createElement("div", {
130
- ref: animationContainer,
131
- className: `${blockClass}__lottie-animation`,
132
- "data-expanded": isOpen,
133
- "aria-hidden": "true"
134
- })), /*#__PURE__*/React.createElement(react.Column, {
67
+ }), headerAnimation ? typeof window !== 'undefined' && /*#__PURE__*/React.createElement(React.Suspense, {
68
+ fallback: null
69
+ }, /*#__PURE__*/React.createElement(AnimatedBackground, {
70
+ headerAnimation: headerAnimation,
71
+ isOpen: isOpen
72
+ })) : /*#__PURE__*/React.createElement(StaticBackground.default, {
73
+ headerStatic: headerStatic
74
+ }), /*#__PURE__*/React.createElement(react.Column, {
135
75
  sm: 4,
136
76
  md: 8,
137
77
  lg: 16,
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface StaticBackgroundProps {
3
+ headerStatic?: React.JSX.Element | string;
4
+ }
5
+ declare const StaticBackground: React.FC<StaticBackgroundProps>;
6
+ export default StaticBackground;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var usePrefix = require('@carbon-labs/utilities/usePrefix');
13
+ var React = require('react');
14
+
15
+ const StaticBackground = ({
16
+ headerStatic
17
+ }) => {
18
+ const prefix = usePrefix.usePrefix();
19
+ const blockClass = `${prefix}--animated-header__static`;
20
+ if (!headerStatic) {
21
+ return null;
22
+ }
23
+ return /*#__PURE__*/React.createElement("div", {
24
+ className: `${blockClass}--container`
25
+ }, /*#__PURE__*/React.createElement("div", {
26
+ className: `${blockClass}`
27
+ // eslint-disable-next-line react/forbid-dom-props
28
+ ,
29
+ style: {
30
+ backgroundImage: `url(${headerStatic})`
31
+ },
32
+ "aria-hidden": "true"
33
+ }));
34
+ };
35
+
36
+ exports.default = StaticBackground;
@@ -0,0 +1,8 @@
1
+ export { AnimatedBackground as default };
2
+ declare function AnimatedBackground({ headerAnimation, isOpen }: {
3
+ headerAnimation: any;
4
+ isOpen: any;
5
+ }): React.DetailedReactHTMLElement<{
6
+ className: string;
7
+ }, HTMLElement>;
8
+ import React from 'react';
@@ -0,0 +1,7 @@
1
+ export { StaticBackground as default };
2
+ declare function StaticBackground({ headerStatic }: {
3
+ headerStatic: any;
4
+ }): React.DetailedReactHTMLElement<{
5
+ className: string;
6
+ }, HTMLElement> | null;
7
+ import React from 'react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbon-labs/react-animated-header",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -45,5 +45,5 @@
45
45
  "devDependencies": {
46
46
  "@carbon-labs/utilities": "0.21.0"
47
47
  },
48
- "gitHead": "b0e1037e0377d84bd08b8808375e1c18f5e89720"
48
+ "gitHead": "d098948fe99c928fc9884fb0fdb2f2e8a855ae30"
49
49
  }