@carbon-labs/react-animated-header 0.34.0 → 0.36.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.
- package/es/__stories__/AnimatedHeader.stories.d.ts +94 -4
- package/es/__stories__/data/index.d.ts +7 -0
- package/es/components/AnimatedHeader/AnimatedHeader.d.ts +4 -1
- package/es/components/AnimatedHeader/AnimatedHeader.js +72 -12
- package/es/components/ContentSwitcherSelector/ContentSwitcherSelector.d.ts +30 -0
- package/es/components/ContentSwitcherSelector/ContentSwitcherSelector.js +70 -0
- package/es/components/HeaderAction/HeaderAction.d.ts +15 -0
- package/es/components/HeaderAction/HeaderAction.js +69 -0
- package/es/components/HeaderAction/header-action.types.d.ts +32 -0
- package/es/components/HeaderTitle/HeaderTitle.js +2 -3
- package/es/components/TasksController/TasksController.d.ts +4 -1
- package/es/components/TasksController/TasksController.js +33 -23
- package/es/index.d.ts +4 -1
- package/es/index.js +1 -0
- package/lib/__stories__/AnimatedHeader.stories.d.ts +94 -4
- package/lib/__stories__/data/index.d.ts +7 -0
- package/lib/components/AnimatedHeader/AnimatedHeader.d.ts +4 -1
- package/lib/components/AnimatedHeader/AnimatedHeader.js +72 -12
- package/lib/components/ContentSwitcherSelector/ContentSwitcherSelector.d.ts +30 -0
- package/lib/components/ContentSwitcherSelector/ContentSwitcherSelector.js +74 -0
- package/lib/components/HeaderAction/HeaderAction.d.ts +15 -0
- package/lib/components/HeaderAction/HeaderAction.js +73 -0
- package/lib/components/HeaderAction/header-action.types.d.ts +32 -0
- package/lib/components/HeaderTitle/HeaderTitle.js +2 -3
- package/lib/components/TasksController/TasksController.d.ts +4 -1
- package/lib/components/TasksController/TasksController.js +33 -23
- package/lib/index.d.ts +4 -1
- package/lib/index.js +2 -0
- package/package.json +2 -2
- package/scss/AnimatedHeader/animated-header.scss +82 -0
- package/scss/HeaderAction/header-action.scss +54 -0
- package/scss/HeaderTitle/header-title.scss +18 -12
- 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
|
-
|
|
30
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,12 @@
|
|
|
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 {
|
|
17
|
+
export type { HeaderActionConfig } from './components/HeaderAction/header-action.types';
|
|
18
|
+
export type { ContentSwitcherConfig } from './components/ContentSwitcherSelector/ContentSwitcherSelector';
|
|
19
|
+
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,49 @@ 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
|
-
|
|
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: import("..").ContentSwitcherConfig;
|
|
15166
|
+
2: import("..").ContentSwitcherConfig;
|
|
15167
|
+
3: import("..").ContentSwitcherConfig;
|
|
15168
|
+
};
|
|
15169
|
+
};
|
|
15170
|
+
contentSwitcherLowContrast: {
|
|
15171
|
+
description: string;
|
|
15172
|
+
control: {
|
|
15173
|
+
type: string;
|
|
15174
|
+
};
|
|
15175
|
+
table: {
|
|
15176
|
+
category: string;
|
|
15177
|
+
};
|
|
15132
15178
|
};
|
|
15133
15179
|
};
|
|
15134
15180
|
args: {
|
|
@@ -15152,6 +15198,9 @@ export declare const ThemeG10: {
|
|
|
15152
15198
|
expandButton: string;
|
|
15153
15199
|
tilesContainer: string;
|
|
15154
15200
|
};
|
|
15201
|
+
headerActionConfig: number;
|
|
15202
|
+
contentSwitcherConfig: number;
|
|
15203
|
+
contentSwitcherLowContrast: boolean;
|
|
15155
15204
|
headerAnimation: number;
|
|
15156
15205
|
};
|
|
15157
15206
|
};
|
|
@@ -30276,11 +30325,49 @@ export declare const ThemeG100: {
|
|
|
30276
30325
|
};
|
|
30277
30326
|
expandButtonLabel: {
|
|
30278
30327
|
description: string;
|
|
30279
|
-
type: string;
|
|
30280
30328
|
};
|
|
30281
30329
|
collapseButtonLabel: {
|
|
30282
30330
|
description: string;
|
|
30283
|
-
|
|
30331
|
+
};
|
|
30332
|
+
headerActionConfig: {
|
|
30333
|
+
description: string;
|
|
30334
|
+
control: {
|
|
30335
|
+
type: string;
|
|
30336
|
+
labels: {
|
|
30337
|
+
0: string;
|
|
30338
|
+
1: string;
|
|
30339
|
+
2: string;
|
|
30340
|
+
};
|
|
30341
|
+
};
|
|
30342
|
+
options: number[];
|
|
30343
|
+
};
|
|
30344
|
+
contentSwitcherConfig: {
|
|
30345
|
+
description: string;
|
|
30346
|
+
control: {
|
|
30347
|
+
type: string;
|
|
30348
|
+
labels: {
|
|
30349
|
+
0: string;
|
|
30350
|
+
1: string;
|
|
30351
|
+
2: string;
|
|
30352
|
+
3: string;
|
|
30353
|
+
};
|
|
30354
|
+
};
|
|
30355
|
+
options: number[];
|
|
30356
|
+
mapping: {
|
|
30357
|
+
0: null;
|
|
30358
|
+
1: import("..").ContentSwitcherConfig;
|
|
30359
|
+
2: import("..").ContentSwitcherConfig;
|
|
30360
|
+
3: import("..").ContentSwitcherConfig;
|
|
30361
|
+
};
|
|
30362
|
+
};
|
|
30363
|
+
contentSwitcherLowContrast: {
|
|
30364
|
+
description: string;
|
|
30365
|
+
control: {
|
|
30366
|
+
type: string;
|
|
30367
|
+
};
|
|
30368
|
+
table: {
|
|
30369
|
+
category: string;
|
|
30370
|
+
};
|
|
30284
30371
|
};
|
|
30285
30372
|
};
|
|
30286
30373
|
args: {
|
|
@@ -30304,6 +30391,9 @@ export declare const ThemeG100: {
|
|
|
30304
30391
|
expandButton: string;
|
|
30305
30392
|
tilesContainer: string;
|
|
30306
30393
|
};
|
|
30394
|
+
headerActionConfig: number;
|
|
30395
|
+
contentSwitcherConfig: number;
|
|
30396
|
+
contentSwitcherLowContrast: boolean;
|
|
30307
30397
|
headerAnimation: number;
|
|
30308
30398
|
};
|
|
30309
30399
|
globals: {
|
|
@@ -7,6 +7,8 @@
|
|
|
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';
|
|
11
|
+
import type { ContentSwitcherConfig } from '../../components/ContentSwitcherSelector/ContentSwitcherSelector';
|
|
10
12
|
export declare const workspaceData: {
|
|
11
13
|
id: string;
|
|
12
14
|
label: string;
|
|
@@ -35,6 +37,9 @@ export declare const tasksControllerConfigLoading: {
|
|
|
35
37
|
type: string;
|
|
36
38
|
isLoading: boolean;
|
|
37
39
|
};
|
|
40
|
+
export declare const contentSwitcherConfigTwo: ContentSwitcherConfig;
|
|
41
|
+
export declare const contentSwitcherConfigThree: ContentSwitcherConfig;
|
|
42
|
+
export declare const contentSwitcherConfigLoading: ContentSwitcherConfig;
|
|
38
43
|
export declare const workspaceSelectorConfig: {
|
|
39
44
|
allWorkspaces: {
|
|
40
45
|
id: string;
|
|
@@ -55,3 +60,5 @@ export declare const workspaceSelectorConfigLoading: {
|
|
|
55
60
|
setSelectedWorkspace: () => void;
|
|
56
61
|
isLoading: boolean;
|
|
57
62
|
};
|
|
63
|
+
export declare const headerActionIcon: HeaderActionConfig;
|
|
64
|
+
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
|
-
})
|
|
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(
|
|
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
|
|
262
|
-
* tasks are used to allow users that have multiple roles and
|
|
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
|
-
|
|
276
|
-
|
|
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;
|
|
@@ -0,0 +1,73 @@
|
|
|
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 react = require('@carbon/react');
|
|
14
|
+
var usePrefix = require('../../node_modules/@carbon-labs/utilities/es/usePrefix.js');
|
|
15
|
+
|
|
16
|
+
const HeaderAction = ({
|
|
17
|
+
config,
|
|
18
|
+
headerExpanded
|
|
19
|
+
}) => {
|
|
20
|
+
const prefix = usePrefix.usePrefix();
|
|
21
|
+
const blockClass = `${prefix}--animated-header__header-action`;
|
|
22
|
+
|
|
23
|
+
// ICON
|
|
24
|
+
if (config.type === 'icon-button') {
|
|
25
|
+
const {
|
|
26
|
+
icon: Icon,
|
|
27
|
+
iconLabel,
|
|
28
|
+
onClick,
|
|
29
|
+
disabled,
|
|
30
|
+
ariaLabel
|
|
31
|
+
} = config;
|
|
32
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
33
|
+
className: blockClass,
|
|
34
|
+
"aria-label": ariaLabel,
|
|
35
|
+
"aria-hidden": !headerExpanded,
|
|
36
|
+
"data-expanded": headerExpanded
|
|
37
|
+
}, /*#__PURE__*/React.createElement(react.IconButton, {
|
|
38
|
+
kind: "ghost",
|
|
39
|
+
size: "lg",
|
|
40
|
+
label: iconLabel,
|
|
41
|
+
onClick: onClick,
|
|
42
|
+
disabled: disabled
|
|
43
|
+
}, Icon && /*#__PURE__*/React.createElement(Icon, {
|
|
44
|
+
fill: `var(--cds-icon-secondary)`,
|
|
45
|
+
size: 16
|
|
46
|
+
})));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// GHOST
|
|
50
|
+
if (config.type === 'ghost-button') {
|
|
51
|
+
const {
|
|
52
|
+
label,
|
|
53
|
+
icon,
|
|
54
|
+
onClick,
|
|
55
|
+
disabled,
|
|
56
|
+
ariaLabel
|
|
57
|
+
} = config;
|
|
58
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
59
|
+
className: blockClass,
|
|
60
|
+
"aria-label": ariaLabel,
|
|
61
|
+
"aria-hidden": !headerExpanded,
|
|
62
|
+
"data-expanded": headerExpanded
|
|
63
|
+
}, /*#__PURE__*/React.createElement(react.Button, {
|
|
64
|
+
kind: "ghost",
|
|
65
|
+
size: "lg",
|
|
66
|
+
onClick: onClick,
|
|
67
|
+
disabled: disabled,
|
|
68
|
+
renderIcon: icon
|
|
69
|
+
}, label));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
exports.default = HeaderAction;
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { ElementType } from 'react';
|
|
10
|
+
type Base = {
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
headerExpanded?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type HeaderActionIcon = Base & {
|
|
15
|
+
type: 'icon-button';
|
|
16
|
+
icon: ElementType;
|
|
17
|
+
iconLabel: string;
|
|
18
|
+
onClick: () => void;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type HeaderActionGhost = Base & {
|
|
22
|
+
type: 'ghost-button';
|
|
23
|
+
label: string;
|
|
24
|
+
icon?: ElementType;
|
|
25
|
+
onClick: () => void;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type HeaderActionConfig = HeaderActionIcon | HeaderActionGhost;
|
|
29
|
+
export type HeaderActionProps = {
|
|
30
|
+
headerActionConfig?: HeaderActionConfig | null;
|
|
31
|
+
};
|
|
32
|
+
export {};
|