@carbon-labs/react-animated-header 0.34.0 → 0.35.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.
Files changed (33) hide show
  1. package/es/__stories__/AnimatedHeader.stories.d.ts +132 -4
  2. package/es/__stories__/data/index.d.ts +25 -0
  3. package/es/components/AnimatedHeader/AnimatedHeader.d.ts +4 -1
  4. package/es/components/AnimatedHeader/AnimatedHeader.js +72 -12
  5. package/es/components/ContentSwitcherSelector/ContentSwitcherSelector.d.ts +30 -0
  6. package/es/components/ContentSwitcherSelector/ContentSwitcherSelector.js +70 -0
  7. package/es/components/HeaderAction/HeaderAction.d.ts +15 -0
  8. package/es/components/HeaderAction/HeaderAction.js +69 -0
  9. package/es/components/HeaderAction/header-action.types.d.ts +32 -0
  10. package/es/components/HeaderTitle/HeaderTitle.js +2 -3
  11. package/es/components/TasksController/TasksController.d.ts +4 -1
  12. package/es/components/TasksController/TasksController.js +33 -23
  13. package/es/index.d.ts +2 -1
  14. package/es/index.js +1 -0
  15. package/lib/__stories__/AnimatedHeader.stories.d.ts +132 -4
  16. package/lib/__stories__/data/index.d.ts +25 -0
  17. package/lib/components/AnimatedHeader/AnimatedHeader.d.ts +4 -1
  18. package/lib/components/AnimatedHeader/AnimatedHeader.js +72 -12
  19. package/lib/components/ContentSwitcherSelector/ContentSwitcherSelector.d.ts +30 -0
  20. package/lib/components/ContentSwitcherSelector/ContentSwitcherSelector.js +74 -0
  21. package/lib/components/HeaderAction/HeaderAction.d.ts +15 -0
  22. package/lib/components/HeaderAction/HeaderAction.js +73 -0
  23. package/lib/components/HeaderAction/header-action.types.d.ts +32 -0
  24. package/lib/components/HeaderTitle/HeaderTitle.js +2 -3
  25. package/lib/components/TasksController/TasksController.d.ts +4 -1
  26. package/lib/components/TasksController/TasksController.js +33 -23
  27. package/lib/index.d.ts +2 -1
  28. package/lib/index.js +2 -0
  29. package/package.json +2 -2
  30. package/scss/AnimatedHeader/animated-header.scss +82 -0
  31. package/scss/HeaderAction/header-action.scss +54 -0
  32. package/scss/HeaderTitle/header-title.scss +18 -12
  33. package/scss/animated-header.scss +1 -0
@@ -6,8 +6,8 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import { SkeletonPlaceholder, Button, Dropdown } from '@carbon/react';
10
9
  import React, { useMemo } from 'react';
10
+ import { SkeletonPlaceholder, Button, Dropdown } from '@carbon/react';
11
11
  import { usePrefix } from '../../node_modules/@carbon-labs/utilities/es/usePrefix.js';
12
12
 
13
13
  const TasksController = ({
@@ -17,54 +17,64 @@ const TasksController = ({
17
17
  selectedTileGroup,
18
18
  setSelectedTileGroup
19
19
  }) => {
20
+ const prefix = usePrefix();
21
+ const blockClass = `${prefix}--animated-header`;
22
+
23
+ /** Button overrides */
20
24
  const {
21
25
  className: buttonCustomClass,
22
26
  ...buttonOverrideProps
23
27
  } = tasksControllerConfig?.button?.propsOverrides || {};
28
+
29
+ /** Dropdown overrides */
24
30
  const {
25
31
  className: dropdownCustomClass,
26
32
  onChange: dropdownCustomOnChange,
27
33
  ...dropdownOverrideProps
28
34
  } = tasksControllerConfig?.dropdown?.propsOverrides || {};
29
- const prefix = usePrefix();
30
- const blockClass = `${prefix}--animated-header`;
35
+
36
+ /** Early outs */
37
+ if (!tasksControllerConfig?.type) return null;
38
+ if (isLoading || tasksControllerConfig?.isLoading) {
39
+ return /*#__PURE__*/React.createElement(SkeletonPlaceholder, {
40
+ className: `${blockClass}__task-controller-skeleton`
41
+ });
42
+ }
43
+
44
+ /** Button mode */
45
+ if (tasksControllerConfig?.type === 'button' && tasksControllerConfig?.button?.text) {
46
+ return /*#__PURE__*/React.createElement(Button, _extends({
47
+ className: `${blockClass}__button${buttonCustomClass ? ` ${buttonCustomClass}` : ''}`
48
+ }, buttonOverrideProps), tasksControllerConfig.button.text);
49
+ }
50
+
51
+ /** Build Dropdown props (uses top-level list/selection/setter) */
31
52
  const dropdownProps = useMemo(() => {
32
- if (!allTileGroups?.length) {
33
- return null;
34
- }
53
+ if (!allTileGroups?.length) return null;
35
54
  return {
36
55
  id: `${blockClass}__header-dropdown`,
37
56
  className: `${blockClass}__header-dropdown${dropdownCustomClass ? ` ${dropdownCustomClass}` : ''}`,
38
57
  size: 'md',
39
58
  titleText: 'Label',
40
- label: allTileGroups[0]?.label ?? '',
59
+ label: tasksControllerConfig?.dropdown?.label ?? allTileGroups[0]?.label ?? '',
41
60
  hideLabel: true,
42
61
  type: 'inline',
43
62
  items: allTileGroups,
44
63
  selectedItem: selectedTileGroup ?? undefined,
45
64
  onChange: e => {
46
- setSelectedTileGroup?.(e);
65
+ if (e.selectedItem) {
66
+ setSelectedTileGroup?.({
67
+ selectedItem: e.selectedItem
68
+ });
69
+ }
47
70
  dropdownCustomOnChange?.(e);
48
71
  },
49
72
  'aria-label': tasksControllerConfig?.dropdown?.ariaLabel ?? 'Select a task group',
50
73
  ...dropdownOverrideProps
51
74
  };
52
- }, [allTileGroups, blockClass, dropdownCustomClass, selectedTileGroup, tasksControllerConfig?.dropdown?.ariaLabel, dropdownOverrideProps, setSelectedTileGroup, dropdownCustomOnChange]);
53
- if (!tasksControllerConfig?.type) {
54
- return null;
55
- }
56
- if (isLoading || tasksControllerConfig?.isLoading) {
57
- return /*#__PURE__*/React.createElement(SkeletonPlaceholder, {
58
- className: `${blockClass}__task-controller-skeleton`
59
- });
60
- }
75
+ }, [allTileGroups, selectedTileGroup, setSelectedTileGroup, blockClass, dropdownCustomClass, dropdownOverrideProps, dropdownCustomOnChange, tasksControllerConfig?.dropdown?.label, tasksControllerConfig?.dropdown?.ariaLabel]);
61
76
 
62
- // Button
63
- if (tasksControllerConfig?.type === 'button' && tasksControllerConfig?.button?.text) {
64
- return /*#__PURE__*/React.createElement(Button, _extends({
65
- className: `${blockClass}__button${buttonCustomClass ? ` ${buttonCustomClass}` : ''}`
66
- }, buttonOverrideProps), tasksControllerConfig.button.text);
67
- }
77
+ /** Dropdown mode */
68
78
  if (tasksControllerConfig?.type === 'dropdown' && dropdownProps) {
69
79
  return /*#__PURE__*/React.createElement("div", {
70
80
  className: `${blockClass}__header-dropdown--container`
package/es/index.d.ts CHANGED
@@ -8,9 +8,10 @@
8
8
  */
9
9
  import AnimatedHeader from './components/AnimatedHeader/AnimatedHeader';
10
10
  import { AriaLabels, TileGroup } from './components/AnimatedHeader/types';
11
+ import HeaderAction from './components/HeaderAction/HeaderAction';
11
12
  import HeaderTitle from './components/HeaderTitle/HeaderTitle';
12
13
  import { BaseTile } from './components/Tiles/index';
13
14
  export * from './assets';
14
15
  export type { Workspace, WorkspaceSelectorConfig, } from './components/WorkspaceSelector/WorkspaceSelector';
15
16
  export type { TasksControllerConfig } from './components/TasksController/TasksController';
16
- export { AnimatedHeader, BaseTile, HeaderTitle, type AriaLabels, type TileGroup, };
17
+ export { AnimatedHeader, BaseTile, HeaderAction, HeaderTitle, type AriaLabels, type TileGroup, };
package/es/index.js CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  export { default as AnimatedHeader } from './components/AnimatedHeader/AnimatedHeader.js';
9
+ export { default as HeaderAction } from './components/HeaderAction/HeaderAction.js';
9
10
  export { default as HeaderTitle } from './components/HeaderTitle/HeaderTitle.js';
10
11
  import 'react';
11
12
  import '@carbon/react';
@@ -1,3 +1,11 @@
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
+ */
1
9
  import AnimatedHeader from '../components/AnimatedHeader/AnimatedHeader';
2
10
  import type { Meta } from '@storybook/react-webpack5';
3
11
  import '../components/animated-header.scss';
@@ -15124,11 +15132,68 @@ export declare const ThemeG10: {
15124
15132
  };
15125
15133
  expandButtonLabel: {
15126
15134
  description: string;
15127
- type: string;
15128
15135
  };
15129
15136
  collapseButtonLabel: {
15130
15137
  description: string;
15131
- type: string;
15138
+ };
15139
+ headerActionConfig: {
15140
+ description: string;
15141
+ control: {
15142
+ type: string;
15143
+ labels: {
15144
+ 0: string;
15145
+ 1: string;
15146
+ 2: string;
15147
+ };
15148
+ };
15149
+ options: number[];
15150
+ };
15151
+ contentSwitcherConfig: {
15152
+ description: string;
15153
+ control: {
15154
+ type: string;
15155
+ labels: {
15156
+ 0: string;
15157
+ 1: string;
15158
+ 2: string;
15159
+ 3: string;
15160
+ };
15161
+ };
15162
+ options: number[];
15163
+ mapping: {
15164
+ 0: null;
15165
+ 1: {
15166
+ ariaLabel: string;
15167
+ visibleCount: number;
15168
+ items: {
15169
+ id: string;
15170
+ text: string;
15171
+ }[];
15172
+ };
15173
+ 2: {
15174
+ ariaLabel: string;
15175
+ visibleCount: number;
15176
+ items: {
15177
+ id: string;
15178
+ text: string;
15179
+ }[];
15180
+ };
15181
+ 3: {
15182
+ ariaLabel: string;
15183
+ isLoading: boolean;
15184
+ visibleCount: number;
15185
+ items: never[];
15186
+ };
15187
+ };
15188
+ };
15189
+ contentSwitcherLowContrast: {
15190
+ description: string;
15191
+ control: {
15192
+ type: string;
15193
+ };
15194
+ table: {
15195
+ category: string;
15196
+ };
15132
15197
  };
15133
15198
  };
15134
15199
  args: {
@@ -15152,6 +15217,9 @@ export declare const ThemeG10: {
15152
15217
  expandButton: string;
15153
15218
  tilesContainer: string;
15154
15219
  };
15220
+ headerActionConfig: number;
15221
+ contentSwitcherConfig: number;
15222
+ contentSwitcherLowContrast: boolean;
15155
15223
  headerAnimation: number;
15156
15224
  };
15157
15225
  };
@@ -30276,11 +30344,68 @@ export declare const ThemeG100: {
30276
30344
  };
30277
30345
  expandButtonLabel: {
30278
30346
  description: string;
30279
- type: string;
30280
30347
  };
30281
30348
  collapseButtonLabel: {
30282
30349
  description: string;
30283
- type: string;
30350
+ };
30351
+ headerActionConfig: {
30352
+ description: string;
30353
+ control: {
30354
+ type: string;
30355
+ labels: {
30356
+ 0: string;
30357
+ 1: string;
30358
+ 2: string;
30359
+ };
30360
+ };
30361
+ options: number[];
30362
+ };
30363
+ contentSwitcherConfig: {
30364
+ description: string;
30365
+ control: {
30366
+ type: string;
30367
+ labels: {
30368
+ 0: string;
30369
+ 1: string;
30370
+ 2: string;
30371
+ 3: string;
30372
+ };
30373
+ };
30374
+ options: number[];
30375
+ mapping: {
30376
+ 0: null;
30377
+ 1: {
30378
+ ariaLabel: string;
30379
+ visibleCount: number;
30380
+ items: {
30381
+ id: string;
30382
+ text: string;
30383
+ }[];
30384
+ };
30385
+ 2: {
30386
+ ariaLabel: string;
30387
+ visibleCount: number;
30388
+ items: {
30389
+ id: string;
30390
+ text: string;
30391
+ }[];
30392
+ };
30393
+ 3: {
30394
+ ariaLabel: string;
30395
+ isLoading: boolean;
30396
+ visibleCount: number;
30397
+ items: never[];
30398
+ };
30399
+ };
30400
+ };
30401
+ contentSwitcherLowContrast: {
30402
+ description: string;
30403
+ control: {
30404
+ type: string;
30405
+ };
30406
+ table: {
30407
+ category: string;
30408
+ };
30284
30409
  };
30285
30410
  };
30286
30411
  args: {
@@ -30304,6 +30429,9 @@ export declare const ThemeG100: {
30304
30429
  expandButton: string;
30305
30430
  tilesContainer: string;
30306
30431
  };
30432
+ headerActionConfig: number;
30433
+ contentSwitcherConfig: number;
30434
+ contentSwitcherLowContrast: boolean;
30307
30435
  headerAnimation: number;
30308
30436
  };
30309
30437
  globals: {
@@ -7,6 +7,7 @@
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
9
  import { TileGroup } from '../../components/AnimatedHeader/types';
10
+ import type { HeaderActionConfig } from '../../components/HeaderAction/header-action.types';
10
11
  export declare const workspaceData: {
11
12
  id: string;
12
13
  label: string;
@@ -35,6 +36,28 @@ export declare const tasksControllerConfigLoading: {
35
36
  type: string;
36
37
  isLoading: boolean;
37
38
  };
39
+ export declare const contentSwitcherConfigTwo: {
40
+ ariaLabel: string;
41
+ visibleCount: number;
42
+ items: {
43
+ id: string;
44
+ text: string;
45
+ }[];
46
+ };
47
+ export declare const contentSwitcherConfigThree: {
48
+ ariaLabel: string;
49
+ visibleCount: number;
50
+ items: {
51
+ id: string;
52
+ text: string;
53
+ }[];
54
+ };
55
+ export declare const contentSwitcherConfigLoading: {
56
+ ariaLabel: string;
57
+ isLoading: boolean;
58
+ visibleCount: number;
59
+ items: never[];
60
+ };
38
61
  export declare const workspaceSelectorConfig: {
39
62
  allWorkspaces: {
40
63
  id: string;
@@ -55,3 +78,5 @@ export declare const workspaceSelectorConfigLoading: {
55
78
  setSelectedWorkspace: () => void;
56
79
  isLoading: boolean;
57
80
  };
81
+ export declare const headerActionIcon: HeaderActionConfig;
82
+ export declare const headerActionGhost: HeaderActionConfig;
@@ -10,12 +10,15 @@ import React from 'react';
10
10
  import { TasksControllerProps } from '../TasksController/TasksController';
11
11
  import { WorkspaceSelectorProps } from '../WorkspaceSelector/WorkspaceSelector';
12
12
  import { Tile, TileGroup, AriaLabels } from './types';
13
+ import { type ContentSwitcherConfig } from '../ContentSwitcherSelector/ContentSwitcherSelector';
14
+ import type { HeaderActionProps } from '../HeaderAction/header-action.types';
13
15
  /** Animated Header */
14
16
  export type AnimatedHeaderProps = {
15
17
  allTileGroups?: TileGroup[];
16
18
  ariaLabels?: AriaLabels;
17
19
  selectedTileGroup?: TileGroup;
18
20
  setSelectedTileGroup?: (e: any) => void;
21
+ contentSwitcherConfig?: ContentSwitcherConfig;
19
22
  description?: string;
20
23
  headerAnimation?: object;
21
24
  headerStatic?: React.JSX.Element | string;
@@ -27,6 +30,6 @@ export type AnimatedHeaderProps = {
27
30
  expandButtonLabel?: string;
28
31
  collapseButtonLabel?: string;
29
32
  tileClickHandler?: (tile: Tile) => void;
30
- } & TasksControllerProps & WorkspaceSelectorProps;
33
+ } & TasksControllerProps & WorkspaceSelectorProps & HeaderActionProps;
31
34
  declare const AnimatedHeader: React.FC<AnimatedHeaderProps>;
32
35
  export default AnimatedHeader;
@@ -21,6 +21,8 @@ var BaseTile = require('../Tiles/BaseTile/BaseTile.js');
21
21
  var TasksController = require('../TasksController/TasksController.js');
22
22
  var WorkspaceSelector = require('../WorkspaceSelector/WorkspaceSelector.js');
23
23
  var HeaderTitle = require('../HeaderTitle/HeaderTitle.js');
24
+ var ContentSwitcherSelector = require('../ContentSwitcherSelector/ContentSwitcherSelector.js');
25
+ var HeaderAction = require('../HeaderAction/HeaderAction.js');
24
26
 
25
27
  /** Animated Header */
26
28
 
@@ -35,6 +37,8 @@ const AnimatedHeader = ({
35
37
  productName = '[Product name]',
36
38
  userName,
37
39
  welcomeText,
40
+ contentSwitcherConfig,
41
+ headerActionConfig,
38
42
  tasksControllerConfig,
39
43
  workspaceSelectorConfig,
40
44
  isLoading,
@@ -128,13 +132,22 @@ const AnimatedHeader = ({
128
132
  })), /*#__PURE__*/React.createElement(react.Column, {
129
133
  sm: 4,
130
134
  md: 8,
131
- lg: 16
135
+ lg: 16,
136
+ className: `${blockClass}__title-row`
137
+ }, /*#__PURE__*/React.createElement("div", {
138
+ className: `${blockClass}__title-and-actions`
132
139
  }, /*#__PURE__*/React.createElement(HeaderTitle.default, {
133
140
  userName: userName,
134
141
  welcomeText: welcomeText,
135
142
  headerExpanded: isOpen,
136
143
  ariaLabels: ariaLabels
137
- })), (description || tasksControllerConfig) && /*#__PURE__*/React.createElement(react.Column, {
144
+ }), contentSwitcherConfig ? /*#__PURE__*/React.createElement("div", {
145
+ className: `${blockClass}__actions`
146
+ }, /*#__PURE__*/React.createElement(ContentSwitcherSelector.default, {
147
+ contentSwitcherConfig: contentSwitcherConfig,
148
+ isLoading: isLoading || contentSwitcherConfig.isLoading,
149
+ headerExpanded: isOpen
150
+ })) : null)), (description || tasksControllerConfig) && /*#__PURE__*/React.createElement(react.Column, {
138
151
  sm: 4,
139
152
  md: 8,
140
153
  lg: 4,
@@ -144,7 +157,7 @@ const AnimatedHeader = ({
144
157
  }, description && /*#__PURE__*/React.createElement("h2", {
145
158
  className: `${blockClass}__description`,
146
159
  "aria-label": ariaLabels?.description ?? `Header description`
147
- }, description), /*#__PURE__*/React.createElement(TasksController.default, {
160
+ }, description), tasksControllerConfig && /*#__PURE__*/React.createElement(TasksController.default, {
148
161
  tasksControllerConfig: tasksControllerConfig,
149
162
  isLoading: isLoading,
150
163
  allTileGroups: allTileGroups,
@@ -194,7 +207,10 @@ const AnimatedHeader = ({
194
207
  className: `${blockClass}__button-collapse--gradient`
195
208
  }), /*#__PURE__*/React.createElement("div", {
196
209
  className: `${blockClass}__button-collapse--container`
197
- }, /*#__PURE__*/React.createElement(react.Button, {
210
+ }, headerActionConfig ? /*#__PURE__*/React.createElement(HeaderAction.default, {
211
+ config: headerActionConfig,
212
+ headerExpanded: isOpen
213
+ }) : null, /*#__PURE__*/React.createElement(react.Button, {
198
214
  id: `${blockClass}__button-collapse`,
199
215
  kind: "ghost",
200
216
  renderIcon: isOpen ? iconsReact.ChevronUp : iconsReact.ChevronDown,
@@ -222,6 +238,24 @@ AnimatedHeader.propTypes = {
222
238
  * Custom collapse button label
223
239
  */
224
240
  collapseButtonLabel: PropTypes.string,
241
+ /**
242
+ * Configuration for Carbon Content Switcher in header.
243
+ * Customized tasks are used to allow users that have multiple roles and
244
+ * permissions to experience better tailored content based on their need.
245
+ */
246
+ contentSwitcherConfig: PropTypes.shape({
247
+ items: PropTypes.arrayOf(PropTypes.shape({
248
+ id: PropTypes.string,
249
+ text: PropTypes.string.isRequired,
250
+ onSelect: PropTypes.func
251
+ }).isRequired).isRequired,
252
+ ariaLabel: PropTypes.string,
253
+ isLoading: PropTypes.bool,
254
+ lowContrast: PropTypes.bool,
255
+ headerExpanded: PropTypes.bool,
256
+ visibleCount: PropTypes.oneOf([2, 3]),
257
+ onChange: PropTypes.func
258
+ }),
225
259
  /**
226
260
  * Provide short sentence in max. 3 lines related to product context
227
261
  */
@@ -230,6 +264,34 @@ AnimatedHeader.propTypes = {
230
264
  * Custom expand button label
231
265
  */
232
266
  expandButtonLabel: PropTypes.string,
267
+ /**
268
+ * Configuration for the header action control (icon button / ghost button / carousel - *coming soon*).
269
+ * This sits to the left of the Collapse button and can trigger generic actions
270
+ * (open modal/panel) or page through tiles.
271
+ */
272
+ headerActionConfig: PropTypes.shape({
273
+ type: PropTypes.oneOf(['icon-button', 'ghost-button']).isRequired,
274
+ // Carbon IconButton variant
275
+ iconButton: PropTypes.shape({
276
+ icon: PropTypes.elementType.isRequired,
277
+ iconLabel: PropTypes.string.isRequired,
278
+ onClick: PropTypes.func.isRequired,
279
+ disabled: PropTypes.bool,
280
+ ariaLabel: PropTypes.string,
281
+ // Override Carbon IconButton props if needed
282
+ propsOverrides: PropTypes.object
283
+ }),
284
+ // Carbon Ghost Button variant
285
+ ghostButton: PropTypes.shape({
286
+ label: PropTypes.string.isRequired,
287
+ icon: PropTypes.elementType,
288
+ onClick: PropTypes.func.isRequired,
289
+ disabled: PropTypes.bool,
290
+ ariaLabel: PropTypes.string,
291
+ // Override Carbon Button props if needed
292
+ propsOverrides: PropTypes.object
293
+ })
294
+ }),
233
295
  /**
234
296
  * In-product imagery / lottie animation (.json) dim. 1312 x 738
235
297
  * (to update headerAnimation content storybook requires remount in toolbar)
@@ -258,23 +320,21 @@ AnimatedHeader.propTypes = {
258
320
  */
259
321
  setSelectedTileGroup: PropTypes.func,
260
322
  /**
261
- * Configuration for Carbon button or dropdown menu in header. Customized
262
- * tasks are used to allow users that have multiple roles and permissions
263
- * to experience better tailored content based on their need.
264
- * It also allows to override Carbon Button props by specifying them in tasksConfig.button.propsOverrides
265
- * or to override Carbon Dropdown props by specifying them in tasksConfig.dropdown.propsOverrides.
323
+ * Configuration for Carbon button / dropdown in header.
324
+ * Customized tasks are used to allow users that have multiple roles and
325
+ * permissions to experience better tailored content based on their need.
266
326
  */
267
327
  tasksControllerConfig: PropTypes.shape({
268
328
  type: PropTypes.oneOf(['button', 'dropdown']).isRequired,
329
+ isLoading: PropTypes.bool,
269
330
  button: PropTypes.shape({
270
331
  text: PropTypes.string.isRequired,
271
332
  // Override Carbon Button props
272
333
  propsOverrides: PropTypes.object
273
334
  }),
274
335
  dropdown: PropTypes.shape({
275
- allTileGroups: PropTypes.arrayOf(PropTypes.object),
276
- selectedTileGroup: PropTypes.object,
277
- setSelectedTileGroup: PropTypes.func.isRequired,
336
+ label: PropTypes.string,
337
+ ariaLabel: PropTypes.string,
278
338
  // Override Carbon Dropdown props
279
339
  propsOverrides: PropTypes.object
280
340
  })
@@ -0,0 +1,30 @@
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
+ import { type ContentSwitcherProps } from '@carbon/react';
11
+ export type ContentSwitcherItem = {
12
+ id?: string;
13
+ text: string;
14
+ onSelect?: () => void;
15
+ };
16
+ export type ContentSwitcherConfig = Omit<ContentSwitcherProps, 'children' | 'onChange' | 'size' | 'lowContrast'> & {
17
+ items: ContentSwitcherItem[];
18
+ ariaLabel?: string;
19
+ isLoading?: boolean;
20
+ lowContrast?: boolean;
21
+ visibleCount?: 2 | 3;
22
+ onChange?: ContentSwitcherProps['onChange'];
23
+ };
24
+ export type ContentSwitcherSelectorProps = {
25
+ contentSwitcherConfig?: ContentSwitcherConfig | null;
26
+ isLoading?: boolean;
27
+ headerExpanded?: boolean;
28
+ };
29
+ declare const ContentSwitcherSelector: React.FC<ContentSwitcherSelectorProps>;
30
+ export default ContentSwitcherSelector;
@@ -0,0 +1,74 @@
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 _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
+ var React = require('react');
14
+ var react = require('@carbon/react');
15
+ var usePrefix = require('../../node_modules/@carbon-labs/utilities/es/usePrefix.js');
16
+
17
+ const ContentSwitcherSelector = ({
18
+ contentSwitcherConfig,
19
+ isLoading,
20
+ headerExpanded
21
+ }) => {
22
+ const prefix = usePrefix.usePrefix();
23
+ const blockClass = `${prefix}--animated-header__content-switcher`;
24
+ if (!contentSwitcherConfig) return null;
25
+ if (isLoading || contentSwitcherConfig.isLoading) {
26
+ return /*#__PURE__*/React.createElement(react.SkeletonPlaceholder, {
27
+ className: `${blockClass}-skeleton`
28
+ });
29
+ }
30
+ const {
31
+ items = [],
32
+ visibleCount,
33
+ lowContrast,
34
+ ariaLabel,
35
+ onChange,
36
+ selectedIndex,
37
+ ...rest
38
+ } = contentSwitcherConfig;
39
+ const count = visibleCount === 3 ? 3 : 2;
40
+ const visibleItems = items.slice(0, count);
41
+ if (visibleItems.length < 2 || visibleItems.length > 3) {
42
+ if (process.env.NODE_ENV !== 'production') {
43
+ console.warn('[ContentSwitcherSelector] contentSwitcherConfig.items must contain 2 or 3 items.');
44
+ }
45
+ return null;
46
+ }
47
+ const selectedIndexSafe = React.useMemo(() => {
48
+ const idx = typeof selectedIndex === 'number' ? selectedIndex : 0;
49
+ return Math.min(Math.max(idx, 0), visibleItems.length - 1);
50
+ }, [selectedIndex, visibleItems.length]);
51
+ return /*#__PURE__*/React.createElement("div", {
52
+ className: `${blockClass}--container`,
53
+ "data-expanded": headerExpanded
54
+ }, /*#__PURE__*/React.createElement(react.ContentSwitcher, _rollupPluginBabelHelpers.extends({
55
+ className: `${blockClass}`,
56
+ "aria-label": ariaLabel ?? 'Select a task group',
57
+ lowContrast: lowContrast,
58
+ selectedIndex: selectedIndexSafe,
59
+ size: "md",
60
+ onChange: ev => {
61
+ onChange?.(ev);
62
+ const idx = ev.index ?? ev.selectedIndex ?? 0;
63
+ visibleItems[idx]?.onSelect?.();
64
+ }
65
+ }, rest), visibleItems.map((item, idx) => {
66
+ return /*#__PURE__*/React.createElement(react.Switch, {
67
+ key: item.id ?? idx,
68
+ name: `option-${idx}`,
69
+ text: item.text
70
+ });
71
+ })));
72
+ };
73
+
74
+ exports.default = ContentSwitcherSelector;
@@ -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
+ import type { HeaderActionConfig } from './header-action.types';
11
+ declare const HeaderAction: React.FC<{
12
+ config: HeaderActionConfig;
13
+ headerExpanded: boolean;
14
+ }>;
15
+ export default HeaderAction;