@carbon-labs/react-animated-header 0.32.0 → 0.33.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.
@@ -43,14 +43,10 @@ const AnimatedHeader = ({
43
43
  const blockClass = `${prefix}--animated-header`;
44
44
  const animationContainer = useRef(null);
45
45
  const animRef = useRef(null);
46
- const [open, setOpen] = useState(true);
46
+ const [isOpen, setIsOpen] = useState(true);
47
47
  const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
48
- const collapsed = `${blockClass}--collapsed`;
49
- const contentCollapsed = `${blockClass}__content--collapsed`;
50
- const descriptionCollapsed = `${blockClass}__left-area-container--collapsed`;
51
- const lottieCollapsed = `${blockClass}__lottie-animation--collapsed`;
52
48
  const handleButtonCollapseClick = () => {
53
- setOpen(!open);
49
+ setIsOpen(!isOpen);
54
50
  };
55
51
  useEffect(() => {
56
52
  // Make sure any prior instance is destroyed before creating a new one
@@ -100,8 +96,11 @@ const AnimatedHeader = ({
100
96
  // Re-init when the JSON or reduced-motion preference changes
101
97
  }, [headerAnimation, isReduced]);
102
98
  return /*#__PURE__*/React.createElement("header", {
103
- className: `${blockClass}${!open ? ` ${collapsed}` : ''}`
104
- }, /*#__PURE__*/React.createElement(Grid, null, /*#__PURE__*/React.createElement("div", {
99
+ className: blockClass,
100
+ "data-expanded": isOpen
101
+ }, /*#__PURE__*/React.createElement(Grid, {
102
+ className: `${blockClass}__grid`
103
+ }, /*#__PURE__*/React.createElement("div", {
105
104
  className: `${blockClass}__gradient--overlay`
106
105
  }), /*#__PURE__*/React.createElement("div", {
107
106
  className: `${blockClass}__container--gradient`
@@ -119,7 +118,8 @@ const AnimatedHeader = ({
119
118
  className: `${blockClass}__lottie-animation--container`
120
119
  }, /*#__PURE__*/React.createElement("div", {
121
120
  ref: animationContainer,
122
- className: `${blockClass}__lottie-animation${!open ? ` ${lottieCollapsed}` : ''}`,
121
+ className: `${blockClass}__lottie-animation`,
122
+ "data-expanded": isOpen,
123
123
  "aria-hidden": "true"
124
124
  })), /*#__PURE__*/React.createElement(Column, {
125
125
  sm: 4,
@@ -128,14 +128,15 @@ const AnimatedHeader = ({
128
128
  }, /*#__PURE__*/React.createElement(HeaderTitle, {
129
129
  userName: userName,
130
130
  welcomeText: welcomeText,
131
- headerExpanded: open,
131
+ headerExpanded: isOpen,
132
132
  ariaLabels: ariaLabels
133
133
  })), (description || tasksControllerConfig) && /*#__PURE__*/React.createElement(Column, {
134
134
  sm: 4,
135
135
  md: 8,
136
136
  lg: 4,
137
137
  id: `${blockClass}-content`,
138
- className: `${blockClass}__left-area-container${!open ? ` ${descriptionCollapsed}` : ''}`
138
+ className: `${blockClass}__left-area-container`,
139
+ "data-expanded": isOpen
139
140
  }, description && /*#__PURE__*/React.createElement("h2", {
140
141
  className: `${blockClass}__description`,
141
142
  "aria-label": ariaLabels?.description ?? `Header description`
@@ -151,7 +152,8 @@ const AnimatedHeader = ({
151
152
  lg: 12,
152
153
  className: `${blockClass}__content`
153
154
  }, !!workspaceSelectorConfig?.allWorkspaces?.length && /*#__PURE__*/React.createElement("div", {
154
- className: `${blockClass}__workspace--container${!open ? ` ${contentCollapsed}` : ''}`
155
+ className: `${blockClass}__workspace--container`,
156
+ "data-expanded": isOpen
155
157
  }, /*#__PURE__*/React.createElement(WorkspaceSelector, {
156
158
  workspaceSelectorConfig: workspaceSelectorConfig,
157
159
  userName: userName,
@@ -173,7 +175,7 @@ const AnimatedHeader = ({
173
175
  key: key,
174
176
  tileId: resolvedTileId
175
177
  }, rest, {
176
- open: open,
178
+ open: isOpen,
177
179
  productName: productName,
178
180
  isLoading: isLoading || tile.isLoading,
179
181
  disabledTaskLabel: disabledTaskLabel,
@@ -191,12 +193,12 @@ const AnimatedHeader = ({
191
193
  }, /*#__PURE__*/React.createElement(Button, {
192
194
  id: `${blockClass}__button-collapse`,
193
195
  kind: "ghost",
194
- renderIcon: open ? ChevronUp : ChevronDown,
196
+ renderIcon: isOpen ? ChevronUp : ChevronDown,
195
197
  onClick: handleButtonCollapseClick,
196
- "aria-expanded": open,
198
+ "aria-expanded": isOpen,
197
199
  "aria-controls": `${blockClass}-content`,
198
- "aria-label": open ? ariaLabels?.collapseButton ?? 'Collapse header details' : ariaLabels?.expandButton ?? 'Expand header details'
199
- }, open ? collapseButtonLabel : expandButtonLabel))));
200
+ "aria-label": isOpen ? ariaLabels?.collapseButton ?? 'Collapse header details' : ariaLabels?.expandButton ?? 'Expand header details'
201
+ }, isOpen ? collapseButtonLabel : expandButtonLabel))));
200
202
  };
201
203
  AnimatedHeader.displayName = 'Animated Header';
202
204
  AnimatedHeader.propTypes = {
@@ -27,7 +27,6 @@ const AIPromptTile = ({
27
27
  }) => {
28
28
  const prefix = usePrefix();
29
29
  const blockClass = `${prefix}--animated-header__ai-prompt-tile`;
30
- const collapsed = `${blockClass}--collapsed`;
31
30
  const disabled = `${blockClass}--disabled`;
32
31
  const [textInput, setTextInput] = useState('');
33
32
  const handleTextInput = e => {
@@ -54,7 +53,8 @@ const AIPromptTile = ({
54
53
  }, isLoading ? /*#__PURE__*/React.createElement(SkeletonPlaceholder, {
55
54
  className: `${blockClass}--loading-skeleton`
56
55
  }) : /*#__PURE__*/React.createElement("div", {
57
- className: `${blockClass}--body${!open ? ` ${collapsed}` : ''}`
56
+ className: `${blockClass}--body`,
57
+ "data-expanded": open
58
58
  }, /*#__PURE__*/React.createElement("div", {
59
59
  className: `${blockClass}--body-background`
60
60
  }), /*#__PURE__*/React.createElement("div", {
@@ -20,14 +20,14 @@ const GlassTileBody = ({
20
20
  }) => {
21
21
  const prefix = usePrefix();
22
22
  const blockClass = `${prefix}--animated-header__glass-tile`;
23
- const collapsed = `${blockClass}--collapsed`;
24
23
  if (isLoading) {
25
24
  return /*#__PURE__*/React.createElement(SkeletonPlaceholder, {
26
25
  className: `${blockClass}--loading-skeleton`
27
26
  });
28
27
  }
29
28
  return /*#__PURE__*/React.createElement("div", {
30
- className: `${blockClass}--body${!open ? ` ${collapsed}` : ''}`
29
+ className: `${blockClass}--body`,
30
+ "data-expanded": open
31
31
  }, /*#__PURE__*/React.createElement("div", {
32
32
  className: `${blockClass}--body-background`
33
33
  }), customContent ? /*#__PURE__*/React.createElement("div", {
@@ -47,14 +47,10 @@ const AnimatedHeader = ({
47
47
  const blockClass = `${prefix}--animated-header`;
48
48
  const animationContainer = React.useRef(null);
49
49
  const animRef = React.useRef(null);
50
- const [open, setOpen] = React.useState(true);
50
+ const [isOpen, setIsOpen] = React.useState(true);
51
51
  const isReduced = window.matchMedia('(prefers-reduced-motion)').matches;
52
- const collapsed = `${blockClass}--collapsed`;
53
- const contentCollapsed = `${blockClass}__content--collapsed`;
54
- const descriptionCollapsed = `${blockClass}__left-area-container--collapsed`;
55
- const lottieCollapsed = `${blockClass}__lottie-animation--collapsed`;
56
52
  const handleButtonCollapseClick = () => {
57
- setOpen(!open);
53
+ setIsOpen(!isOpen);
58
54
  };
59
55
  React.useEffect(() => {
60
56
  // Make sure any prior instance is destroyed before creating a new one
@@ -104,8 +100,11 @@ const AnimatedHeader = ({
104
100
  // Re-init when the JSON or reduced-motion preference changes
105
101
  }, [headerAnimation, isReduced]);
106
102
  return /*#__PURE__*/React.createElement("header", {
107
- className: `${blockClass}${!open ? ` ${collapsed}` : ''}`
108
- }, /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement("div", {
103
+ className: blockClass,
104
+ "data-expanded": isOpen
105
+ }, /*#__PURE__*/React.createElement(react.Grid, {
106
+ className: `${blockClass}__grid`
107
+ }, /*#__PURE__*/React.createElement("div", {
109
108
  className: `${blockClass}__gradient--overlay`
110
109
  }), /*#__PURE__*/React.createElement("div", {
111
110
  className: `${blockClass}__container--gradient`
@@ -123,7 +122,8 @@ const AnimatedHeader = ({
123
122
  className: `${blockClass}__lottie-animation--container`
124
123
  }, /*#__PURE__*/React.createElement("div", {
125
124
  ref: animationContainer,
126
- className: `${blockClass}__lottie-animation${!open ? ` ${lottieCollapsed}` : ''}`,
125
+ className: `${blockClass}__lottie-animation`,
126
+ "data-expanded": isOpen,
127
127
  "aria-hidden": "true"
128
128
  })), /*#__PURE__*/React.createElement(react.Column, {
129
129
  sm: 4,
@@ -132,14 +132,15 @@ const AnimatedHeader = ({
132
132
  }, /*#__PURE__*/React.createElement(HeaderTitle.default, {
133
133
  userName: userName,
134
134
  welcomeText: welcomeText,
135
- headerExpanded: open,
135
+ headerExpanded: isOpen,
136
136
  ariaLabels: ariaLabels
137
137
  })), (description || tasksControllerConfig) && /*#__PURE__*/React.createElement(react.Column, {
138
138
  sm: 4,
139
139
  md: 8,
140
140
  lg: 4,
141
141
  id: `${blockClass}-content`,
142
- className: `${blockClass}__left-area-container${!open ? ` ${descriptionCollapsed}` : ''}`
142
+ className: `${blockClass}__left-area-container`,
143
+ "data-expanded": isOpen
143
144
  }, description && /*#__PURE__*/React.createElement("h2", {
144
145
  className: `${blockClass}__description`,
145
146
  "aria-label": ariaLabels?.description ?? `Header description`
@@ -155,7 +156,8 @@ const AnimatedHeader = ({
155
156
  lg: 12,
156
157
  className: `${blockClass}__content`
157
158
  }, !!workspaceSelectorConfig?.allWorkspaces?.length && /*#__PURE__*/React.createElement("div", {
158
- className: `${blockClass}__workspace--container${!open ? ` ${contentCollapsed}` : ''}`
159
+ className: `${blockClass}__workspace--container`,
160
+ "data-expanded": isOpen
159
161
  }, /*#__PURE__*/React.createElement(WorkspaceSelector.default, {
160
162
  workspaceSelectorConfig: workspaceSelectorConfig,
161
163
  userName: userName,
@@ -177,7 +179,7 @@ const AnimatedHeader = ({
177
179
  key: key,
178
180
  tileId: resolvedTileId
179
181
  }, rest, {
180
- open: open,
182
+ open: isOpen,
181
183
  productName: productName,
182
184
  isLoading: isLoading || tile.isLoading,
183
185
  disabledTaskLabel: disabledTaskLabel,
@@ -195,12 +197,12 @@ const AnimatedHeader = ({
195
197
  }, /*#__PURE__*/React.createElement(react.Button, {
196
198
  id: `${blockClass}__button-collapse`,
197
199
  kind: "ghost",
198
- renderIcon: open ? iconsReact.ChevronUp : iconsReact.ChevronDown,
200
+ renderIcon: isOpen ? iconsReact.ChevronUp : iconsReact.ChevronDown,
199
201
  onClick: handleButtonCollapseClick,
200
- "aria-expanded": open,
202
+ "aria-expanded": isOpen,
201
203
  "aria-controls": `${blockClass}-content`,
202
- "aria-label": open ? ariaLabels?.collapseButton ?? 'Collapse header details' : ariaLabels?.expandButton ?? 'Expand header details'
203
- }, open ? collapseButtonLabel : expandButtonLabel))));
204
+ "aria-label": isOpen ? ariaLabels?.collapseButton ?? 'Collapse header details' : ariaLabels?.expandButton ?? 'Expand header details'
205
+ }, isOpen ? collapseButtonLabel : expandButtonLabel))));
204
206
  };
205
207
  AnimatedHeader.displayName = 'Animated Header';
206
208
  AnimatedHeader.propTypes = {
@@ -29,7 +29,6 @@ const AIPromptTile = ({
29
29
  }) => {
30
30
  const prefix = usePrefix.usePrefix();
31
31
  const blockClass = `${prefix}--animated-header__ai-prompt-tile`;
32
- const collapsed = `${blockClass}--collapsed`;
33
32
  const disabled = `${blockClass}--disabled`;
34
33
  const [textInput, setTextInput] = React.useState('');
35
34
  const handleTextInput = e => {
@@ -56,7 +55,8 @@ const AIPromptTile = ({
56
55
  }, isLoading ? /*#__PURE__*/React.createElement(react.SkeletonPlaceholder, {
57
56
  className: `${blockClass}--loading-skeleton`
58
57
  }) : /*#__PURE__*/React.createElement("div", {
59
- className: `${blockClass}--body${!open ? ` ${collapsed}` : ''}`
58
+ className: `${blockClass}--body`,
59
+ "data-expanded": open
60
60
  }, /*#__PURE__*/React.createElement("div", {
61
61
  className: `${blockClass}--body-background`
62
62
  }), /*#__PURE__*/React.createElement("div", {
@@ -22,14 +22,14 @@ const GlassTileBody = ({
22
22
  }) => {
23
23
  const prefix = usePrefix.usePrefix();
24
24
  const blockClass = `${prefix}--animated-header__glass-tile`;
25
- const collapsed = `${blockClass}--collapsed`;
26
25
  if (isLoading) {
27
26
  return /*#__PURE__*/React.createElement(react.SkeletonPlaceholder, {
28
27
  className: `${blockClass}--loading-skeleton`
29
28
  });
30
29
  }
31
30
  return /*#__PURE__*/React.createElement("div", {
32
- className: `${blockClass}--body${!open ? ` ${collapsed}` : ''}`
31
+ className: `${blockClass}--body`,
32
+ "data-expanded": open
33
33
  }, /*#__PURE__*/React.createElement("div", {
34
34
  className: `${blockClass}--body-background`
35
35
  }), customContent ? /*#__PURE__*/React.createElement("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbon-labs/react-animated-header",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -45,5 +45,5 @@
45
45
  "devDependencies": {
46
46
  "@carbon-labs/utilities": "canary"
47
47
  },
48
- "gitHead": "0b30143dcd8880b14e38986db3979f6b32f2c484"
48
+ "gitHead": "2cb890436fa0c3e0f5a0b9738f2d59fb1a50eb31"
49
49
  }
@@ -46,17 +46,37 @@ body {
46
46
  .#{$prefix} {
47
47
  position: relative;
48
48
  display: flex;
49
- overflow: visible;
50
49
  background: $background;
51
50
  inline-size: 100%;
52
- max-block-size: 200vh;
53
- outline: 1px solid transparent;
54
- padding-block: 0 $spacing-10;
55
- transition: padding 500ms motion.motion(standard, expressive),
56
- max-block-size 500ms motion.motion(standard, expressive), color 200ms linear,
57
- background-color 200ms linear,
58
- outline 500ms motion.motion(standard, expressive);
51
+ max-block-size: 85vh;
59
52
  writing-mode: horizontal-tb;
53
+
54
+ &[data-expanded='true'] {
55
+ overflow: visible;
56
+ max-block-size: 85vh;
57
+ outline: 1px solid transparent;
58
+
59
+ @media (prefers-reduced-motion: no-preference) {
60
+ transition: max-block-size 500ms motion.motion(entrance, expressive),
61
+ color 200ms linear, background-color 200ms linear,
62
+ outline 500ms motion.motion(entrance, expressive);
63
+ }
64
+ }
65
+
66
+ &[data-expanded='false'] {
67
+ overflow: hidden;
68
+ max-block-size: $spacing-09;
69
+ outline: 1px solid $border-subtle-00;
70
+
71
+ @media (prefers-reduced-motion: no-preference) {
72
+ transition: max-block-size 500ms motion.motion(exit, expressive),
73
+ outline 500ms motion.motion(exit, expressive);
74
+ }
75
+ }
76
+ }
77
+
78
+ .#{$prefix}__grid {
79
+ padding-block: 0 $spacing-10;
60
80
  }
61
81
 
62
82
  .#{$prefix}__static--container {
@@ -88,8 +108,6 @@ body {
88
108
 
89
109
  background-position: top right;
90
110
  background-repeat: no-repeat;
91
- transform: translateY(0);
92
- transition: transform 500ms motion.motion(standard, expressive);
93
111
  }
94
112
 
95
113
  .#{$prefix}__ui-heading {
@@ -151,12 +169,20 @@ body {
151
169
  flex-direction: column;
152
170
  gap: $spacing-07;
153
171
  margin-block-start: $spacing-08;
154
- opacity: 1;
155
- transition: opacity 500ms linear;
156
- }
157
172
 
158
- .#{$prefix}__left-area-container--collapsed {
159
- opacity: 0;
173
+ @media (prefers-reduced-motion: no-preference) {
174
+ transition: opacity 500ms linear;
175
+ }
176
+
177
+ &[data-expanded='true'] {
178
+ opacity: 1;
179
+ transition-delay: 110ms;
180
+ }
181
+
182
+ &[data-expanded='false'] {
183
+ opacity: 0;
184
+ transition-delay: 0ms;
185
+ }
160
186
  }
161
187
 
162
188
  .#{$prefix}__description {
@@ -238,15 +264,25 @@ body {
238
264
  flex-direction: column;
239
265
  margin: 0;
240
266
  margin-block-start: $spacing-08;
241
- opacity: 1;
242
- transition: opacity 500ms linear;
243
267
  }
244
268
 
245
269
  .#{$prefix}__workspace--container {
246
270
  margin-block-start: calc(-1 * $spacing-08);
247
271
  min-block-size: $spacing-08;
248
- opacity: 1;
249
- transition: opacity 500ms linear;
272
+
273
+ @media (prefers-reduced-motion: no-preference) {
274
+ transition: opacity 500ms linear;
275
+ }
276
+
277
+ &[data-expanded='true'] {
278
+ opacity: 1;
279
+ transition-delay: 110ms;
280
+ }
281
+
282
+ &[data-expanded='false'] {
283
+ opacity: 0;
284
+ transition-delay: 0ms;
285
+ }
250
286
  }
251
287
 
252
288
  .#{$prefix}__workspace {
@@ -264,10 +300,6 @@ body {
264
300
  gap: $spacing-05;
265
301
  }
266
302
 
267
- .#{$prefix}__content--collapsed {
268
- opacity: 0;
269
- }
270
-
271
303
  .#{$prefix}__tile {
272
304
  animation: 500ms motion.motion(standard, expressive) 0ms 1 slide-in;
273
305
  animation-fill-mode: both;
@@ -326,12 +358,17 @@ body {
326
358
  z-index: 0;
327
359
  display: flex;
328
360
 
329
- transform: translateY(0);
330
- transition: transform 500ms motion.motion(standard, expressive);
331
- }
361
+ @media (prefers-reduced-motion: no-preference) {
362
+ transition: transform 500ms motion.motion(standard, expressive);
363
+ }
332
364
 
333
- .#{$prefix}__lottie-animation--collapsed {
334
- transform: translateY(-16px);
365
+ &[data-expanded='true'] {
366
+ transform: translateY(0);
367
+ }
368
+
369
+ &[data-expanded='false'] {
370
+ transform: translateY(-16px);
371
+ }
335
372
  }
336
373
 
337
374
  .#{$prefix}__button-collapse--container {
@@ -383,13 +420,6 @@ body {
383
420
  color: $text-primary;
384
421
  }
385
422
 
386
- .#{$prefix}--collapsed {
387
- overflow: hidden;
388
- padding: 0;
389
- max-block-size: $spacing-09;
390
- outline: 1px solid $border-subtle-00;
391
- }
392
-
393
423
  // Small
394
424
  @media only screen and (width >= 20rem) {
395
425
  .#{$prefix}__lottie-animation {
@@ -564,7 +594,7 @@ body {
564
594
  /*
565
595
  If the user has expressed their preference for
566
596
  reduced motion, then don't use animations
567
- */
597
+ */
568
598
  @media (prefers-reduced-motion: reduce) {
569
599
  .#{$prefix},
570
600
  .#{$prefix}__static,
@@ -50,8 +50,20 @@ $prefix: 'clabs--animated-header__ai-prompt-tile' !default;
50
50
  padding: $spacing-05;
51
51
  background-color: transparent;
52
52
  color: $text-primary;
53
- opacity: 1;
54
- transition: opacity 500ms linear;
53
+
54
+ @media (prefers-reduced-motion: no-preference) {
55
+ transition: opacity 500ms linear;
56
+ }
57
+
58
+ &[data-expanded='true'] {
59
+ opacity: 1;
60
+ transition-delay: 110ms;
61
+ }
62
+
63
+ &[data-expanded='false'] {
64
+ opacity: 0;
65
+ transition-delay: 0ms;
66
+ }
55
67
  }
56
68
 
57
69
  /* Semi-transparent background layer */
@@ -50,8 +50,20 @@ $prefix: 'clabs--animated-header__glass-tile' !default;
50
50
  padding: $spacing-05;
51
51
  background-color: transparent;
52
52
  color: $text-primary;
53
- opacity: 1;
54
- transition: opacity 500ms linear;
53
+
54
+ @media (prefers-reduced-motion: no-preference) {
55
+ transition: opacity 500ms linear;
56
+ }
57
+
58
+ &[data-expanded='true'] {
59
+ opacity: 1;
60
+ transition-delay: 110ms;
61
+ }
62
+
63
+ &[data-expanded='false'] {
64
+ opacity: 0;
65
+ transition-delay: 0ms;
66
+ }
55
67
  }
56
68
 
57
69
  /* Semi-transparent background layer */