@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.
- package/es/__stories__/AnimatedHeader.stories.d.ts +132 -4
- package/es/__stories__/data/index.d.ts +25 -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 +2 -1
- package/es/index.js +1 -0
- package/lib/__stories__/AnimatedHeader.stories.d.ts +132 -4
- package/lib/__stories__/data/index.d.ts +25 -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 +2 -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
|
@@ -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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -17,6 +17,8 @@ import { BaseTile } from '../Tiles/BaseTile/BaseTile.js';
|
|
|
17
17
|
import TasksController from '../TasksController/TasksController.js';
|
|
18
18
|
import WorkspaceSelector from '../WorkspaceSelector/WorkspaceSelector.js';
|
|
19
19
|
import HeaderTitle from '../HeaderTitle/HeaderTitle.js';
|
|
20
|
+
import ContentSwitcherSelector from '../ContentSwitcherSelector/ContentSwitcherSelector.js';
|
|
21
|
+
import HeaderAction from '../HeaderAction/HeaderAction.js';
|
|
20
22
|
|
|
21
23
|
/** Animated Header */
|
|
22
24
|
|
|
@@ -31,6 +33,8 @@ const AnimatedHeader = ({
|
|
|
31
33
|
productName = '[Product name]',
|
|
32
34
|
userName,
|
|
33
35
|
welcomeText,
|
|
36
|
+
contentSwitcherConfig,
|
|
37
|
+
headerActionConfig,
|
|
34
38
|
tasksControllerConfig,
|
|
35
39
|
workspaceSelectorConfig,
|
|
36
40
|
isLoading,
|
|
@@ -124,13 +128,22 @@ const AnimatedHeader = ({
|
|
|
124
128
|
})), /*#__PURE__*/React.createElement(Column, {
|
|
125
129
|
sm: 4,
|
|
126
130
|
md: 8,
|
|
127
|
-
lg: 16
|
|
131
|
+
lg: 16,
|
|
132
|
+
className: `${blockClass}__title-row`
|
|
133
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
134
|
+
className: `${blockClass}__title-and-actions`
|
|
128
135
|
}, /*#__PURE__*/React.createElement(HeaderTitle, {
|
|
129
136
|
userName: userName,
|
|
130
137
|
welcomeText: welcomeText,
|
|
131
138
|
headerExpanded: isOpen,
|
|
132
139
|
ariaLabels: ariaLabels
|
|
133
|
-
})
|
|
140
|
+
}), contentSwitcherConfig ? /*#__PURE__*/React.createElement("div", {
|
|
141
|
+
className: `${blockClass}__actions`
|
|
142
|
+
}, /*#__PURE__*/React.createElement(ContentSwitcherSelector, {
|
|
143
|
+
contentSwitcherConfig: contentSwitcherConfig,
|
|
144
|
+
isLoading: isLoading || contentSwitcherConfig.isLoading,
|
|
145
|
+
headerExpanded: isOpen
|
|
146
|
+
})) : null)), (description || tasksControllerConfig) && /*#__PURE__*/React.createElement(Column, {
|
|
134
147
|
sm: 4,
|
|
135
148
|
md: 8,
|
|
136
149
|
lg: 4,
|
|
@@ -140,7 +153,7 @@ const AnimatedHeader = ({
|
|
|
140
153
|
}, description && /*#__PURE__*/React.createElement("h2", {
|
|
141
154
|
className: `${blockClass}__description`,
|
|
142
155
|
"aria-label": ariaLabels?.description ?? `Header description`
|
|
143
|
-
}, description), /*#__PURE__*/React.createElement(TasksController, {
|
|
156
|
+
}, description), tasksControllerConfig && /*#__PURE__*/React.createElement(TasksController, {
|
|
144
157
|
tasksControllerConfig: tasksControllerConfig,
|
|
145
158
|
isLoading: isLoading,
|
|
146
159
|
allTileGroups: allTileGroups,
|
|
@@ -190,7 +203,10 @@ const AnimatedHeader = ({
|
|
|
190
203
|
className: `${blockClass}__button-collapse--gradient`
|
|
191
204
|
}), /*#__PURE__*/React.createElement("div", {
|
|
192
205
|
className: `${blockClass}__button-collapse--container`
|
|
193
|
-
}, /*#__PURE__*/React.createElement(
|
|
206
|
+
}, headerActionConfig ? /*#__PURE__*/React.createElement(HeaderAction, {
|
|
207
|
+
config: headerActionConfig,
|
|
208
|
+
headerExpanded: isOpen
|
|
209
|
+
}) : null, /*#__PURE__*/React.createElement(Button, {
|
|
194
210
|
id: `${blockClass}__button-collapse`,
|
|
195
211
|
kind: "ghost",
|
|
196
212
|
renderIcon: isOpen ? ChevronUp : ChevronDown,
|
|
@@ -218,6 +234,24 @@ AnimatedHeader.propTypes = {
|
|
|
218
234
|
* Custom collapse button label
|
|
219
235
|
*/
|
|
220
236
|
collapseButtonLabel: PropTypes.string,
|
|
237
|
+
/**
|
|
238
|
+
* Configuration for Carbon Content Switcher in header.
|
|
239
|
+
* Customized tasks are used to allow users that have multiple roles and
|
|
240
|
+
* permissions to experience better tailored content based on their need.
|
|
241
|
+
*/
|
|
242
|
+
contentSwitcherConfig: PropTypes.shape({
|
|
243
|
+
items: PropTypes.arrayOf(PropTypes.shape({
|
|
244
|
+
id: PropTypes.string,
|
|
245
|
+
text: PropTypes.string.isRequired,
|
|
246
|
+
onSelect: PropTypes.func
|
|
247
|
+
}).isRequired).isRequired,
|
|
248
|
+
ariaLabel: PropTypes.string,
|
|
249
|
+
isLoading: PropTypes.bool,
|
|
250
|
+
lowContrast: PropTypes.bool,
|
|
251
|
+
headerExpanded: PropTypes.bool,
|
|
252
|
+
visibleCount: PropTypes.oneOf([2, 3]),
|
|
253
|
+
onChange: PropTypes.func
|
|
254
|
+
}),
|
|
221
255
|
/**
|
|
222
256
|
* Provide short sentence in max. 3 lines related to product context
|
|
223
257
|
*/
|
|
@@ -226,6 +260,34 @@ AnimatedHeader.propTypes = {
|
|
|
226
260
|
* Custom expand button label
|
|
227
261
|
*/
|
|
228
262
|
expandButtonLabel: PropTypes.string,
|
|
263
|
+
/**
|
|
264
|
+
* Configuration for the header action control (icon button / ghost button / carousel - *coming soon*).
|
|
265
|
+
* This sits to the left of the Collapse button and can trigger generic actions
|
|
266
|
+
* (open modal/panel) or page through tiles.
|
|
267
|
+
*/
|
|
268
|
+
headerActionConfig: PropTypes.shape({
|
|
269
|
+
type: PropTypes.oneOf(['icon-button', 'ghost-button']).isRequired,
|
|
270
|
+
// Carbon IconButton variant
|
|
271
|
+
iconButton: PropTypes.shape({
|
|
272
|
+
icon: PropTypes.elementType.isRequired,
|
|
273
|
+
iconLabel: PropTypes.string.isRequired,
|
|
274
|
+
onClick: PropTypes.func.isRequired,
|
|
275
|
+
disabled: PropTypes.bool,
|
|
276
|
+
ariaLabel: PropTypes.string,
|
|
277
|
+
// Override Carbon IconButton props if needed
|
|
278
|
+
propsOverrides: PropTypes.object
|
|
279
|
+
}),
|
|
280
|
+
// Carbon Ghost Button variant
|
|
281
|
+
ghostButton: PropTypes.shape({
|
|
282
|
+
label: PropTypes.string.isRequired,
|
|
283
|
+
icon: PropTypes.elementType,
|
|
284
|
+
onClick: PropTypes.func.isRequired,
|
|
285
|
+
disabled: PropTypes.bool,
|
|
286
|
+
ariaLabel: PropTypes.string,
|
|
287
|
+
// Override Carbon Button props if needed
|
|
288
|
+
propsOverrides: PropTypes.object
|
|
289
|
+
})
|
|
290
|
+
}),
|
|
229
291
|
/**
|
|
230
292
|
* In-product imagery / lottie animation (.json) dim. 1312 x 738
|
|
231
293
|
* (to update headerAnimation content storybook requires remount in toolbar)
|
|
@@ -254,23 +316,21 @@ AnimatedHeader.propTypes = {
|
|
|
254
316
|
*/
|
|
255
317
|
setSelectedTileGroup: PropTypes.func,
|
|
256
318
|
/**
|
|
257
|
-
* Configuration for Carbon button
|
|
258
|
-
* tasks are used to allow users that have multiple roles and
|
|
259
|
-
* to experience better tailored content based on their need.
|
|
260
|
-
* It also allows to override Carbon Button props by specifying them in tasksConfig.button.propsOverrides
|
|
261
|
-
* or to override Carbon Dropdown props by specifying them in tasksConfig.dropdown.propsOverrides.
|
|
319
|
+
* Configuration for Carbon button / dropdown in header.
|
|
320
|
+
* Customized tasks are used to allow users that have multiple roles and
|
|
321
|
+
* permissions to experience better tailored content based on their need.
|
|
262
322
|
*/
|
|
263
323
|
tasksControllerConfig: PropTypes.shape({
|
|
264
324
|
type: PropTypes.oneOf(['button', 'dropdown']).isRequired,
|
|
325
|
+
isLoading: PropTypes.bool,
|
|
265
326
|
button: PropTypes.shape({
|
|
266
327
|
text: PropTypes.string.isRequired,
|
|
267
328
|
// Override Carbon Button props
|
|
268
329
|
propsOverrides: PropTypes.object
|
|
269
330
|
}),
|
|
270
331
|
dropdown: PropTypes.shape({
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
setSelectedTileGroup: PropTypes.func.isRequired,
|
|
332
|
+
label: PropTypes.string,
|
|
333
|
+
ariaLabel: PropTypes.string,
|
|
274
334
|
// Override Carbon Dropdown props
|
|
275
335
|
propsOverrides: PropTypes.object
|
|
276
336
|
})
|
|
@@ -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,70 @@
|
|
|
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 { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
+
import React, { useMemo } from 'react';
|
|
10
|
+
import { SkeletonPlaceholder, ContentSwitcher, Switch } from '@carbon/react';
|
|
11
|
+
import { usePrefix } from '../../node_modules/@carbon-labs/utilities/es/usePrefix.js';
|
|
12
|
+
|
|
13
|
+
const ContentSwitcherSelector = ({
|
|
14
|
+
contentSwitcherConfig,
|
|
15
|
+
isLoading,
|
|
16
|
+
headerExpanded
|
|
17
|
+
}) => {
|
|
18
|
+
const prefix = usePrefix();
|
|
19
|
+
const blockClass = `${prefix}--animated-header__content-switcher`;
|
|
20
|
+
if (!contentSwitcherConfig) return null;
|
|
21
|
+
if (isLoading || contentSwitcherConfig.isLoading) {
|
|
22
|
+
return /*#__PURE__*/React.createElement(SkeletonPlaceholder, {
|
|
23
|
+
className: `${blockClass}-skeleton`
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const {
|
|
27
|
+
items = [],
|
|
28
|
+
visibleCount,
|
|
29
|
+
lowContrast,
|
|
30
|
+
ariaLabel,
|
|
31
|
+
onChange,
|
|
32
|
+
selectedIndex,
|
|
33
|
+
...rest
|
|
34
|
+
} = contentSwitcherConfig;
|
|
35
|
+
const count = visibleCount === 3 ? 3 : 2;
|
|
36
|
+
const visibleItems = items.slice(0, count);
|
|
37
|
+
if (visibleItems.length < 2 || visibleItems.length > 3) {
|
|
38
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
39
|
+
console.warn('[ContentSwitcherSelector] contentSwitcherConfig.items must contain 2 or 3 items.');
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const selectedIndexSafe = useMemo(() => {
|
|
44
|
+
const idx = typeof selectedIndex === 'number' ? selectedIndex : 0;
|
|
45
|
+
return Math.min(Math.max(idx, 0), visibleItems.length - 1);
|
|
46
|
+
}, [selectedIndex, visibleItems.length]);
|
|
47
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
48
|
+
className: `${blockClass}--container`,
|
|
49
|
+
"data-expanded": headerExpanded
|
|
50
|
+
}, /*#__PURE__*/React.createElement(ContentSwitcher, _extends({
|
|
51
|
+
className: `${blockClass}`,
|
|
52
|
+
"aria-label": ariaLabel ?? 'Select a task group',
|
|
53
|
+
lowContrast: lowContrast,
|
|
54
|
+
selectedIndex: selectedIndexSafe,
|
|
55
|
+
size: "md",
|
|
56
|
+
onChange: ev => {
|
|
57
|
+
onChange?.(ev);
|
|
58
|
+
const idx = ev.index ?? ev.selectedIndex ?? 0;
|
|
59
|
+
visibleItems[idx]?.onSelect?.();
|
|
60
|
+
}
|
|
61
|
+
}, rest), visibleItems.map((item, idx) => {
|
|
62
|
+
return /*#__PURE__*/React.createElement(Switch, {
|
|
63
|
+
key: item.id ?? idx,
|
|
64
|
+
name: `option-${idx}`,
|
|
65
|
+
text: item.text
|
|
66
|
+
});
|
|
67
|
+
})));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export { ContentSwitcherSelector 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
|
+
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,69 @@
|
|
|
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 from 'react';
|
|
9
|
+
import { IconButton, Button } from '@carbon/react';
|
|
10
|
+
import { usePrefix } from '../../node_modules/@carbon-labs/utilities/es/usePrefix.js';
|
|
11
|
+
|
|
12
|
+
const HeaderAction = ({
|
|
13
|
+
config,
|
|
14
|
+
headerExpanded
|
|
15
|
+
}) => {
|
|
16
|
+
const prefix = usePrefix();
|
|
17
|
+
const blockClass = `${prefix}--animated-header__header-action`;
|
|
18
|
+
|
|
19
|
+
// ICON
|
|
20
|
+
if (config.type === 'icon-button') {
|
|
21
|
+
const {
|
|
22
|
+
icon: Icon,
|
|
23
|
+
iconLabel,
|
|
24
|
+
onClick,
|
|
25
|
+
disabled,
|
|
26
|
+
ariaLabel
|
|
27
|
+
} = config;
|
|
28
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
29
|
+
className: blockClass,
|
|
30
|
+
"aria-label": ariaLabel,
|
|
31
|
+
"aria-hidden": !headerExpanded,
|
|
32
|
+
"data-expanded": headerExpanded
|
|
33
|
+
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
34
|
+
kind: "ghost",
|
|
35
|
+
size: "lg",
|
|
36
|
+
label: iconLabel,
|
|
37
|
+
onClick: onClick,
|
|
38
|
+
disabled: disabled
|
|
39
|
+
}, Icon && /*#__PURE__*/React.createElement(Icon, {
|
|
40
|
+
fill: `var(--cds-icon-secondary)`,
|
|
41
|
+
size: 16
|
|
42
|
+
})));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// GHOST
|
|
46
|
+
if (config.type === 'ghost-button') {
|
|
47
|
+
const {
|
|
48
|
+
label,
|
|
49
|
+
icon,
|
|
50
|
+
onClick,
|
|
51
|
+
disabled,
|
|
52
|
+
ariaLabel
|
|
53
|
+
} = config;
|
|
54
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
55
|
+
className: blockClass,
|
|
56
|
+
"aria-label": ariaLabel,
|
|
57
|
+
"aria-hidden": !headerExpanded,
|
|
58
|
+
"data-expanded": headerExpanded
|
|
59
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
60
|
+
kind: "ghost",
|
|
61
|
+
size: "lg",
|
|
62
|
+
onClick: onClick,
|
|
63
|
+
disabled: disabled,
|
|
64
|
+
renderIcon: icon
|
|
65
|
+
}, label));
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { HeaderAction as default };
|
|
@@ -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 {};
|
|
@@ -31,13 +31,12 @@ const HeaderTitle = ({
|
|
|
31
31
|
const blockClass = `${prefix}--animated-header__title`;
|
|
32
32
|
const currentLang = typeof window !== 'undefined' ? document.documentElement.lang || 'en' : 'en';
|
|
33
33
|
const isNameFirst = NAME_FIRST_LANGS.includes(currentLang.slice(0, 2));
|
|
34
|
-
const headingCollapsed = `${blockClass}-collapsed`;
|
|
35
|
-
const headingExpanded = `${blockClass}-expanded`;
|
|
36
34
|
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
37
35
|
align: "bottom",
|
|
38
36
|
label: `${welcomeText}, ${userName}`
|
|
39
37
|
}, /*#__PURE__*/React.createElement("h1", {
|
|
40
|
-
className:
|
|
38
|
+
className: blockClass,
|
|
39
|
+
"data-expanded": headerExpanded,
|
|
41
40
|
"aria-label": ariaLabels?.welcome ?? `${welcomeText}, ${userName}`
|
|
42
41
|
}, isNameFirst ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
43
42
|
className: `${blockClass}-first`
|
|
@@ -17,6 +17,7 @@ export interface TasksControllerConfig {
|
|
|
17
17
|
};
|
|
18
18
|
dropdown?: {
|
|
19
19
|
propsOverrides?: Partial<Omit<DropdownProps<TileGroup>, 'id' | 'items' | 'selectedItem'>>;
|
|
20
|
+
label?: string;
|
|
20
21
|
ariaLabel?: string;
|
|
21
22
|
};
|
|
22
23
|
}
|
|
@@ -25,7 +26,9 @@ export type TasksControllerProps = {
|
|
|
25
26
|
isLoading?: boolean;
|
|
26
27
|
allTileGroups?: TileGroup[];
|
|
27
28
|
selectedTileGroup?: TileGroup | null;
|
|
28
|
-
setSelectedTileGroup
|
|
29
|
+
setSelectedTileGroup?: (group: TileGroup | {
|
|
30
|
+
selectedItem: TileGroup;
|
|
31
|
+
}) => void;
|
|
29
32
|
};
|
|
30
33
|
declare const TasksController: ({ tasksControllerConfig, isLoading, allTileGroups, selectedTileGroup, setSelectedTileGroup, }: TasksControllerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
31
34
|
export default TasksController;
|