@kaizen/components 0.0.0-canary-guidance-block-codemod-20251215033932 → 0.0.0-canary-01-titleblock-20251216220648
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/codemods/migrateGuidanceBlockActionsToActionsSlot/transformActionsToActionsSlot.spec.ts +105 -0
- package/codemods/utils/transformV1ButtonPropsToButtonOrLinkButton.ts +4 -14
- package/dist/cjs/src/MenuV1/index.cjs +4 -3
- package/dist/cjs/src/TitleBlock/TitleBlock.cjs +32 -36
- package/dist/cjs/src/TitleBlock/TitleBlock.module.scss.cjs +5 -1
- package/dist/cjs/src/TitleBlock/subcomponents/MainActions.cjs +90 -45
- package/dist/cjs/src/TitleBlock/subcomponents/MainActions.module.scss.cjs +3 -1
- package/dist/cjs/src/TitleBlock/subcomponents/SecondaryActions.cjs +51 -14
- package/dist/esm/src/MenuV1/index.mjs +5 -3
- package/dist/esm/src/TitleBlock/TitleBlock.mjs +33 -37
- package/dist/esm/src/TitleBlock/TitleBlock.module.scss.mjs +5 -1
- package/dist/esm/src/TitleBlock/subcomponents/MainActions.mjs +92 -47
- package/dist/esm/src/TitleBlock/subcomponents/MainActions.module.scss.mjs +3 -1
- package/dist/esm/src/TitleBlock/subcomponents/SecondaryActions.mjs +51 -14
- package/dist/styles.css +89 -210
- package/dist/types/TitleBlock/TitleBlock.d.ts +1 -1
- package/dist/types/TitleBlock/subcomponents/MainActions.d.ts +4 -3
- package/package.json +1 -1
- package/src/Avatar/Avatar.module.css +1 -0
- package/src/TitleBlock/TitleBlock.module.scss +63 -19
- package/src/TitleBlock/TitleBlock.spec.tsx +33 -461
- package/src/TitleBlock/TitleBlock.tsx +7 -24
- package/src/TitleBlock/_docs/TitleBlock.stories.tsx +59 -12
- package/src/TitleBlock/_mixins.scss +6 -0
- package/src/TitleBlock/subcomponents/MainActions.module.scss +20 -2
- package/src/TitleBlock/subcomponents/MainActions.tsx +127 -70
- package/src/TitleBlock/subcomponents/SecondaryActions.tsx +105 -45
- package/src/TitleBlock/subcomponents/Toolbar.tsx +1 -0
- package/dist/cjs/src/MenuV1/subcomponents/MenuHeading/MenuHeading.cjs +0 -27
- package/dist/cjs/src/MenuV1/subcomponents/MenuHeading/MenuHeading.module.scss.cjs +0 -6
- package/dist/cjs/src/TitleBlock/subcomponents/MobileActions.cjs +0 -306
- package/dist/cjs/src/TitleBlock/subcomponents/MobileActions.module.scss.cjs +0 -16
- package/dist/esm/src/MenuV1/subcomponents/MenuHeading/MenuHeading.mjs +0 -21
- package/dist/esm/src/MenuV1/subcomponents/MenuHeading/MenuHeading.module.scss.mjs +0 -4
- package/dist/esm/src/TitleBlock/subcomponents/MobileActions.mjs +0 -300
- package/dist/esm/src/TitleBlock/subcomponents/MobileActions.module.scss.mjs +0 -14
- package/dist/types/TitleBlock/subcomponents/MobileActions.d.ts +0 -14
- package/src/TitleBlock/subcomponents/MobileActions.module.scss +0 -208
- package/src/TitleBlock/subcomponents/MobileActions.spec.tsx +0 -210
- package/src/TitleBlock/subcomponents/MobileActions.tsx +0 -472
|
@@ -8,7 +8,6 @@ import { Select } from '~components/Select'
|
|
|
8
8
|
import { Tag } from '~components/Tag'
|
|
9
9
|
import { useMediaQueries } from '~components/utils/useMediaQueries'
|
|
10
10
|
import { MainActions } from './subcomponents/MainActions'
|
|
11
|
-
import { MobileActions } from './subcomponents/MobileActions'
|
|
12
11
|
import { SecondaryActions } from './subcomponents/SecondaryActions'
|
|
13
12
|
import {
|
|
14
13
|
type NavigationTabs,
|
|
@@ -18,7 +17,7 @@ import {
|
|
|
18
17
|
type TitleBlockProps,
|
|
19
18
|
type TitleBlockVariant,
|
|
20
19
|
} from './types'
|
|
21
|
-
import {
|
|
20
|
+
import { isReversed } from './utils'
|
|
22
21
|
import styles from './TitleBlock.module.scss'
|
|
23
22
|
|
|
24
23
|
const renderTag = (surveyStatus: SurveyStatus): ReactNode => {
|
|
@@ -156,6 +155,9 @@ const Breadcrumb = ({
|
|
|
156
155
|
<div className={styles.circle}>
|
|
157
156
|
<Icon name="arrow_back" isPresentational shouldMirrorInRTL />
|
|
158
157
|
</div>
|
|
158
|
+
<div className={styles.staticIcon}>
|
|
159
|
+
<Icon name="arrow_back" isPresentational shouldMirrorInRTL />
|
|
160
|
+
</div>
|
|
159
161
|
<span
|
|
160
162
|
className={styles.breadcrumbTextLink}
|
|
161
163
|
data-automation-id={textAutomationId}
|
|
@@ -258,7 +260,6 @@ export const TitleBlock = ({
|
|
|
258
260
|
sectionTitleDescriptionAutomationId = 'TitleBlock__SectionTitleDescription',
|
|
259
261
|
breadcrumbAutomationId = 'TitleBlock__Breadcrumb',
|
|
260
262
|
breadcrumbTextAutomationId = 'TitleBlock__BreadcrumbText',
|
|
261
|
-
autoHideMobileActionsMenu = false,
|
|
262
263
|
}: TitleBlockProps): JSX.Element => {
|
|
263
264
|
const hasNavigationTabs = navigationTabs && navigationTabs.length > 0
|
|
264
265
|
const collapseNavigationArea =
|
|
@@ -343,19 +344,13 @@ export const TitleBlock = ({
|
|
|
343
344
|
</>
|
|
344
345
|
</div>
|
|
345
346
|
</div>
|
|
346
|
-
{(primaryAction ??
|
|
347
|
-
defaultAction ??
|
|
348
|
-
secondaryActions ??
|
|
349
|
-
secondaryOverflowMenuItems) && (
|
|
347
|
+
{(primaryAction ?? defaultAction ?? secondaryActions) && (
|
|
350
348
|
<MainActions
|
|
351
349
|
primaryAction={primaryAction}
|
|
352
350
|
defaultAction={defaultAction}
|
|
351
|
+
secondaryActions={secondaryActions}
|
|
352
|
+
secondaryOverflowMenuItems={secondaryOverflowMenuItems}
|
|
353
353
|
reversed={isReversed(variant)}
|
|
354
|
-
overflowMenuItems={createTabletOverflowMenuItems(
|
|
355
|
-
secondaryActions,
|
|
356
|
-
secondaryOverflowMenuItems,
|
|
357
|
-
)}
|
|
358
|
-
showOverflowMenu={isSmallOrMediumViewport}
|
|
359
354
|
/>
|
|
360
355
|
)}
|
|
361
356
|
</div>
|
|
@@ -395,18 +390,6 @@ export const TitleBlock = ({
|
|
|
395
390
|
</div>
|
|
396
391
|
</div>
|
|
397
392
|
</div>
|
|
398
|
-
<MobileActions
|
|
399
|
-
primaryAction={primaryAction}
|
|
400
|
-
defaultAction={defaultAction}
|
|
401
|
-
secondaryActions={secondaryActions}
|
|
402
|
-
secondaryOverflowMenuItems={secondaryOverflowMenuItems}
|
|
403
|
-
drawerHandleLabelIconPosition={
|
|
404
|
-
primaryAction && 'iconPosition' in primaryAction
|
|
405
|
-
? primaryAction.iconPosition
|
|
406
|
-
: undefined
|
|
407
|
-
}
|
|
408
|
-
autoHide={autoHideMobileActionsMenu}
|
|
409
|
-
/>
|
|
410
393
|
</div>
|
|
411
394
|
</>
|
|
412
395
|
)
|
|
@@ -34,7 +34,7 @@ const meta = {
|
|
|
34
34
|
layout: 'fullscreen',
|
|
35
35
|
},
|
|
36
36
|
args: {
|
|
37
|
-
title: 'Page title',
|
|
37
|
+
title: 'Page title Page title Page title ',
|
|
38
38
|
surveyStatus: { text: 'Due July 8, 2030', status: 'default' },
|
|
39
39
|
avatar: {
|
|
40
40
|
avatarSrc: assetUrl('site/empty-state.png'),
|
|
@@ -112,15 +112,42 @@ export const Viewports: Story = {
|
|
|
112
112
|
type: 'desktop',
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
|
-
defaultViewport: 'default',
|
|
115
|
+
// defaultViewport: 'default',
|
|
116
116
|
},
|
|
117
117
|
chromatic: {
|
|
118
118
|
disable: false,
|
|
119
|
-
viewports: [1079, 1365, 1366],
|
|
119
|
+
viewports: [1079, 1365, 1366, 760, 360],
|
|
120
120
|
},
|
|
121
121
|
},
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
export const WithNoSecondaryOverflow: Story = {
|
|
125
|
+
parameters: {
|
|
126
|
+
viewport: {
|
|
127
|
+
viewports: {
|
|
128
|
+
default: {
|
|
129
|
+
name: 'Above or equal to 1366',
|
|
130
|
+
styles: { width: '1366px', height: '800px' },
|
|
131
|
+
type: 'desktop',
|
|
132
|
+
},
|
|
133
|
+
under1366: {
|
|
134
|
+
name: 'Under 1366',
|
|
135
|
+
styles: { width: '1365px', height: '800px' },
|
|
136
|
+
type: 'desktop',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
// defaultViewport: 'default',
|
|
140
|
+
},
|
|
141
|
+
chromatic: {
|
|
142
|
+
disable: false,
|
|
143
|
+
viewports: [1365, 1366, 760, 360],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
args: {
|
|
147
|
+
title: 'Test no secondary overflow menu items',
|
|
148
|
+
secondaryOverflowMenuItems: undefined,
|
|
149
|
+
},
|
|
150
|
+
}
|
|
124
151
|
export const HasLongTitle: Story = {
|
|
125
152
|
parameters: {
|
|
126
153
|
viewport: {
|
|
@@ -136,11 +163,11 @@ export const HasLongTitle: Story = {
|
|
|
136
163
|
type: 'desktop',
|
|
137
164
|
},
|
|
138
165
|
},
|
|
139
|
-
defaultViewport: 'default',
|
|
166
|
+
// defaultViewport: 'default',
|
|
140
167
|
},
|
|
141
168
|
chromatic: {
|
|
142
169
|
disable: false,
|
|
143
|
-
viewports: [1365, 1366],
|
|
170
|
+
viewports: [1365, 1366, 760, 360],
|
|
144
171
|
},
|
|
145
172
|
},
|
|
146
173
|
args: { title: 'A long title with over thirty characters' },
|
|
@@ -156,21 +183,41 @@ export const LightVariant: Story = {
|
|
|
156
183
|
viewport: {
|
|
157
184
|
viewports: {
|
|
158
185
|
default: {
|
|
159
|
-
name: '
|
|
186
|
+
name: 'desktop (above or equal to 1366)',
|
|
160
187
|
styles: { width: '1366px', height: '800px' },
|
|
161
188
|
type: 'desktop',
|
|
162
189
|
},
|
|
163
|
-
|
|
164
|
-
name: '
|
|
190
|
+
desktopSm: {
|
|
191
|
+
name: 'desktop-sm (1024 - 1365)',
|
|
165
192
|
styles: { width: '1365px', height: '800px' },
|
|
166
193
|
type: 'desktop',
|
|
167
194
|
},
|
|
195
|
+
tablet: {
|
|
196
|
+
name: 'tablet (672 - 1023)',
|
|
197
|
+
styles: { width: '1023px', height: '800px' },
|
|
198
|
+
type: 'desktop',
|
|
199
|
+
},
|
|
200
|
+
mobileResponsive: {
|
|
201
|
+
name: 'mobile-responsive (512 - 671)',
|
|
202
|
+
styles: { width: '671px', height: '800px' },
|
|
203
|
+
type: 'desktop',
|
|
204
|
+
},
|
|
205
|
+
mobile: {
|
|
206
|
+
name: 'mobile (361 - 512)',
|
|
207
|
+
styles: { width: '511px', height: '800px' },
|
|
208
|
+
type: 'desktop',
|
|
209
|
+
},
|
|
210
|
+
mobileXs: {
|
|
211
|
+
name: 'mobile (under 360)',
|
|
212
|
+
styles: { width: '360px', height: '800px' },
|
|
213
|
+
type: 'desktop',
|
|
214
|
+
},
|
|
168
215
|
},
|
|
169
|
-
defaultViewport: 'default',
|
|
216
|
+
// defaultViewport: 'default',
|
|
170
217
|
},
|
|
171
218
|
chromatic: {
|
|
172
219
|
disable: false,
|
|
173
|
-
viewports: [1365, 1366],
|
|
220
|
+
viewports: [1365, 1366, 760, 360],
|
|
174
221
|
},
|
|
175
222
|
},
|
|
176
223
|
args: {
|
|
@@ -202,7 +249,7 @@ export const AdminVariant: Story = {
|
|
|
202
249
|
type: 'desktop',
|
|
203
250
|
},
|
|
204
251
|
},
|
|
205
|
-
defaultViewport: 'default',
|
|
252
|
+
// defaultViewport: 'default',
|
|
206
253
|
},
|
|
207
254
|
chromatic: {
|
|
208
255
|
disable: false,
|
|
@@ -237,7 +284,7 @@ export const EducationVariant: Story = {
|
|
|
237
284
|
type: 'desktop',
|
|
238
285
|
},
|
|
239
286
|
},
|
|
240
|
-
defaultViewport: 'default',
|
|
287
|
+
// defaultViewport: 'default',
|
|
241
288
|
},
|
|
242
289
|
chromatic: {
|
|
243
290
|
disable: false,
|
|
@@ -8,11 +8,29 @@
|
|
|
8
8
|
justify-content: flex-end;
|
|
9
9
|
flex-grow: 1;
|
|
10
10
|
flex-shrink: 0;
|
|
11
|
+
white-space: nowrap;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
.defaultActionButtonMinimized {
|
|
14
|
+
display: none;
|
|
15
|
+
margin-inline-end: 0;
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
@include title-block-small {
|
|
15
|
-
|
|
19
|
+
justify-content: flex-start;
|
|
20
|
+
padding-left: 2.75rem;
|
|
21
|
+
|
|
22
|
+
@media (max-width: 360px) {
|
|
23
|
+
.defaultActionButton {
|
|
24
|
+
display: none;
|
|
25
|
+
margin-inline-end: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.defaultActionButtonMinimized {
|
|
29
|
+
display: flex;
|
|
30
|
+
margin-inline-end: 3px;
|
|
31
|
+
margin-left: -0.5rem;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
16
34
|
}
|
|
17
35
|
}
|
|
18
36
|
}
|
|
@@ -2,13 +2,14 @@ import React from 'react'
|
|
|
2
2
|
import { Button, IconButton } from '~components/ButtonV1'
|
|
3
3
|
import { Icon } from '~components/Icon'
|
|
4
4
|
import { Menu, MenuList } from '~components/MenuV1'
|
|
5
|
-
import { TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID } from '
|
|
5
|
+
import { TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID } from '~components/TitleBlock'
|
|
6
6
|
import {
|
|
7
7
|
type DefaultActionProps,
|
|
8
8
|
type PrimaryActionProps,
|
|
9
|
+
type SecondaryActionsProps,
|
|
9
10
|
type TitleBlockMenuItemProps,
|
|
10
11
|
} from '../types'
|
|
11
|
-
import { isMenuGroupNotButton } from '../utils'
|
|
12
|
+
import { createTabletOverflowMenuItems, isMenuGroupNotButton } from '../utils'
|
|
12
13
|
import { TitleBlockMenuItem } from './TitleBlockMenuItem'
|
|
13
14
|
import { Toolbar } from './Toolbar'
|
|
14
15
|
import styles from './MainActions.module.scss'
|
|
@@ -17,18 +18,135 @@ type MainActionsProps = {
|
|
|
17
18
|
primaryAction?: PrimaryActionProps
|
|
18
19
|
defaultAction?: DefaultActionProps
|
|
19
20
|
reversed?: boolean
|
|
20
|
-
|
|
21
|
+
secondaryActions?: SecondaryActionsProps
|
|
22
|
+
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[]
|
|
21
23
|
showOverflowMenu?: boolean
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
const renderSecondaryAndOverflowMenu = (
|
|
27
|
+
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[],
|
|
28
|
+
reversed?: boolean,
|
|
29
|
+
): JSX.Element | undefined => {
|
|
30
|
+
if (!secondaryOverflowMenuItems) return undefined
|
|
31
|
+
return (
|
|
32
|
+
<Menu
|
|
33
|
+
align="right"
|
|
34
|
+
button={
|
|
35
|
+
<IconButton
|
|
36
|
+
label={'Open secondary and overflow menu'}
|
|
37
|
+
reversed={reversed}
|
|
38
|
+
icon={<Icon name="more_horiz" isPresentational />}
|
|
39
|
+
id={TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}
|
|
40
|
+
classNameOverride={styles.overflowMenuButton}
|
|
41
|
+
/>
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
<MenuList>
|
|
45
|
+
{secondaryOverflowMenuItems.map((menuItem, i) => (
|
|
46
|
+
<TitleBlockMenuItem key={i} {...menuItem} />
|
|
47
|
+
))}
|
|
48
|
+
</MenuList>
|
|
49
|
+
</Menu>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
24
53
|
export const MainActions = ({
|
|
25
54
|
primaryAction,
|
|
26
55
|
defaultAction,
|
|
56
|
+
secondaryActions,
|
|
57
|
+
secondaryOverflowMenuItems,
|
|
27
58
|
reversed = false,
|
|
28
|
-
overflowMenuItems,
|
|
29
|
-
showOverflowMenu = false,
|
|
30
59
|
}: MainActionsProps): JSX.Element => {
|
|
31
60
|
let items
|
|
61
|
+
|
|
62
|
+
// Build combined secondary + overflow menu items once, to be spread into the toolbar items
|
|
63
|
+
const secondaryAndOverflowMenu: { key: string; node: JSX.Element }[] = []
|
|
64
|
+
|
|
65
|
+
// Convert defaultAction to menu item format and prepend to combined list
|
|
66
|
+
let defaultActionMenuItem: TitleBlockMenuItemProps | undefined
|
|
67
|
+
if (defaultAction) {
|
|
68
|
+
if ('component' in defaultAction) {
|
|
69
|
+
defaultActionMenuItem = defaultAction
|
|
70
|
+
} else if ('onClick' in defaultAction) {
|
|
71
|
+
defaultActionMenuItem = {
|
|
72
|
+
label: defaultAction.label,
|
|
73
|
+
icon: defaultAction.icon,
|
|
74
|
+
onClick: defaultAction.onClick,
|
|
75
|
+
disabled: defaultAction.disabled,
|
|
76
|
+
}
|
|
77
|
+
} else if ('href' in defaultAction) {
|
|
78
|
+
defaultActionMenuItem = {
|
|
79
|
+
label: defaultAction.label,
|
|
80
|
+
icon: defaultAction.icon,
|
|
81
|
+
href: defaultAction.href,
|
|
82
|
+
disabled: defaultAction.disabled,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const combinedSecondaryOverflowItems = createTabletOverflowMenuItems(
|
|
88
|
+
secondaryActions,
|
|
89
|
+
secondaryOverflowMenuItems,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
// Prepend defaultAction to the combined list if it exists
|
|
93
|
+
const allMenuItems = defaultActionMenuItem
|
|
94
|
+
? [defaultActionMenuItem, ...combinedSecondaryOverflowItems]
|
|
95
|
+
: combinedSecondaryOverflowItems
|
|
96
|
+
|
|
97
|
+
if (allMenuItems.length > 0) {
|
|
98
|
+
secondaryAndOverflowMenu.push({
|
|
99
|
+
key: 'overflowMenu',
|
|
100
|
+
node: renderSecondaryAndOverflowMenu(allMenuItems, reversed)!,
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const defaultActionItem = defaultAction
|
|
105
|
+
? [
|
|
106
|
+
{
|
|
107
|
+
key: 'defaultAction',
|
|
108
|
+
node: (
|
|
109
|
+
<Button
|
|
110
|
+
classNameOverride={styles.defaultActionButton}
|
|
111
|
+
{...{
|
|
112
|
+
...defaultAction,
|
|
113
|
+
reversed: defaultAction.reversed ?? reversed,
|
|
114
|
+
}}
|
|
115
|
+
data-automation-id="title-block-default-action-button"
|
|
116
|
+
data-testid="title-block-default-action-button"
|
|
117
|
+
/>
|
|
118
|
+
),
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
|
+
: []
|
|
122
|
+
|
|
123
|
+
const defaultActionItemMinimized = defaultAction
|
|
124
|
+
? [
|
|
125
|
+
{
|
|
126
|
+
key: 'defaultActionMinimized',
|
|
127
|
+
node: (
|
|
128
|
+
<div className={styles.defaultActionButtonMinimized}>
|
|
129
|
+
<Menu
|
|
130
|
+
align="right"
|
|
131
|
+
button={
|
|
132
|
+
<IconButton
|
|
133
|
+
label={'Open default action overflow menu'}
|
|
134
|
+
reversed={reversed}
|
|
135
|
+
icon={<Icon name="more_horiz" isPresentational />}
|
|
136
|
+
id={TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}
|
|
137
|
+
/>
|
|
138
|
+
}
|
|
139
|
+
>
|
|
140
|
+
<MenuList>
|
|
141
|
+
{defaultActionMenuItem && <TitleBlockMenuItem {...defaultActionMenuItem} />}
|
|
142
|
+
</MenuList>
|
|
143
|
+
</Menu>
|
|
144
|
+
</div>
|
|
145
|
+
),
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
: []
|
|
149
|
+
|
|
32
150
|
if (primaryAction && isMenuGroupNotButton(primaryAction)) {
|
|
33
151
|
const menuContent = primaryAction.menuItems.map((item, idx) => (
|
|
34
152
|
<TitleBlockMenuItem
|
|
@@ -40,23 +158,8 @@ export const MainActions = ({
|
|
|
40
158
|
))
|
|
41
159
|
|
|
42
160
|
items = [
|
|
43
|
-
...
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
key: 'defaultAction',
|
|
47
|
-
node: (
|
|
48
|
-
<Button
|
|
49
|
-
{...{
|
|
50
|
-
...defaultAction,
|
|
51
|
-
reversed: defaultAction.reversed ?? reversed,
|
|
52
|
-
}}
|
|
53
|
-
data-automation-id="title-block-default-action-button"
|
|
54
|
-
data-testid="title-block-default-action-button"
|
|
55
|
-
/>
|
|
56
|
-
),
|
|
57
|
-
},
|
|
58
|
-
]
|
|
59
|
-
: []),
|
|
161
|
+
...defaultActionItem,
|
|
162
|
+
...defaultActionItemMinimized,
|
|
60
163
|
...(primaryAction
|
|
61
164
|
? [
|
|
62
165
|
{
|
|
@@ -93,23 +196,8 @@ export const MainActions = ({
|
|
|
93
196
|
]
|
|
94
197
|
} else {
|
|
95
198
|
items = [
|
|
96
|
-
...
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
key: 'defaultAction',
|
|
100
|
-
node: (
|
|
101
|
-
<Button
|
|
102
|
-
{...{
|
|
103
|
-
...defaultAction,
|
|
104
|
-
reversed: defaultAction.reversed ?? reversed,
|
|
105
|
-
}}
|
|
106
|
-
data-automation-id="title-block-default-action-button"
|
|
107
|
-
data-testid="title-block-default-action-button"
|
|
108
|
-
/>
|
|
109
|
-
),
|
|
110
|
-
},
|
|
111
|
-
]
|
|
112
|
-
: []),
|
|
199
|
+
...defaultActionItem,
|
|
200
|
+
...defaultActionItemMinimized,
|
|
113
201
|
...(primaryAction
|
|
114
202
|
? [
|
|
115
203
|
{
|
|
@@ -139,37 +227,6 @@ export const MainActions = ({
|
|
|
139
227
|
]
|
|
140
228
|
}
|
|
141
229
|
|
|
142
|
-
if (overflowMenuItems && showOverflowMenu && overflowMenuItems.length > 0) {
|
|
143
|
-
items = [
|
|
144
|
-
{
|
|
145
|
-
key: 'overflowMenu',
|
|
146
|
-
node: (
|
|
147
|
-
<Menu
|
|
148
|
-
align="right"
|
|
149
|
-
button={
|
|
150
|
-
<IconButton
|
|
151
|
-
id={TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}
|
|
152
|
-
label="Open secondary menu"
|
|
153
|
-
reversed={reversed}
|
|
154
|
-
icon={<Icon name="more_horiz" isPresentational />}
|
|
155
|
-
/>
|
|
156
|
-
}
|
|
157
|
-
>
|
|
158
|
-
<MenuList>
|
|
159
|
-
{overflowMenuItems.map((menuItem, idx) => (
|
|
160
|
-
<TitleBlockMenuItem
|
|
161
|
-
{...menuItem}
|
|
162
|
-
key={`main-action-overflow-item-menu-item-${idx}`}
|
|
163
|
-
/>
|
|
164
|
-
))}
|
|
165
|
-
</MenuList>
|
|
166
|
-
</Menu>
|
|
167
|
-
),
|
|
168
|
-
},
|
|
169
|
-
...items,
|
|
170
|
-
]
|
|
171
|
-
}
|
|
172
|
-
|
|
173
230
|
return (
|
|
174
231
|
<div className={styles.mainActionsContainer}>
|
|
175
232
|
<Toolbar
|
|
@@ -5,6 +5,7 @@ import { Menu, MenuList } from '~components/MenuV1'
|
|
|
5
5
|
import styles from '../TitleBlock.module.scss'
|
|
6
6
|
import { TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID } from '../constants'
|
|
7
7
|
import { type SecondaryActionsProps, type TitleBlockMenuItemProps } from '../types'
|
|
8
|
+
import { convertSecondaryActionsToMenuItems } from '../utils'
|
|
8
9
|
import { TitleBlockMenuItem } from './TitleBlockMenuItem'
|
|
9
10
|
import { Toolbar } from './Toolbar'
|
|
10
11
|
|
|
@@ -18,25 +19,67 @@ const renderSecondaryOverflowMenu = (
|
|
|
18
19
|
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[],
|
|
19
20
|
reversed?: boolean,
|
|
20
21
|
): JSX.Element | undefined => {
|
|
21
|
-
if (!secondaryOverflowMenuItems) return undefined
|
|
22
|
+
if (!secondaryOverflowMenuItems || secondaryOverflowMenuItems.length === 0) return undefined
|
|
22
23
|
return (
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
<div className={styles.secondaryOverflowMenu}>
|
|
25
|
+
<Menu
|
|
26
|
+
align="right"
|
|
27
|
+
button={
|
|
28
|
+
<Button
|
|
29
|
+
secondary
|
|
30
|
+
reversed={reversed}
|
|
31
|
+
label="Menu"
|
|
32
|
+
data-automation-id={TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}
|
|
33
|
+
data-testid={TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}
|
|
34
|
+
icon={<Icon name="keyboard_arrow_down" isPresentational />}
|
|
35
|
+
iconPosition={'end'}
|
|
36
|
+
/>
|
|
37
|
+
}
|
|
38
|
+
>
|
|
39
|
+
<MenuList>
|
|
40
|
+
{secondaryOverflowMenuItems.map((menuItem, i) => (
|
|
41
|
+
<TitleBlockMenuItem key={i} {...menuItem} />
|
|
42
|
+
))}
|
|
43
|
+
</MenuList>
|
|
44
|
+
</Menu>
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// New: combined overflow menu (secondary actions converted + overflow menu items)
|
|
50
|
+
const renderCombinedSecondaryOverflowMenu = (
|
|
51
|
+
secondaryActions?: SecondaryActionsProps,
|
|
52
|
+
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[],
|
|
53
|
+
reversed?: boolean,
|
|
54
|
+
): JSX.Element | undefined => {
|
|
55
|
+
const secondaryConverted = secondaryActions
|
|
56
|
+
? convertSecondaryActionsToMenuItems(secondaryActions)
|
|
57
|
+
: []
|
|
58
|
+
const overflowItems = secondaryOverflowMenuItems ?? []
|
|
59
|
+
|
|
60
|
+
if (secondaryConverted.length === 0 && overflowItems.length === 0) return undefined
|
|
61
|
+
const combined = [...secondaryConverted, ...overflowItems]
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className={styles.secondaryOverflowCombinedMenu}>
|
|
65
|
+
<Menu
|
|
66
|
+
align="right"
|
|
67
|
+
button={
|
|
68
|
+
<IconButton
|
|
69
|
+
label="Open combined secondary + overflow menu"
|
|
70
|
+
reversed={reversed}
|
|
71
|
+
icon={<Icon name="more_horiz" isPresentational />}
|
|
72
|
+
id={`${TITLE_BLOCK_ZEN_SECONDARY_MENU_HTML_ID}__combined`}
|
|
73
|
+
/>
|
|
74
|
+
}
|
|
75
|
+
>
|
|
76
|
+
<MenuList>
|
|
77
|
+
{combined.map((menuItem, i) => (
|
|
78
|
+
<TitleBlockMenuItem key={i} {...menuItem} />
|
|
79
|
+
))}
|
|
80
|
+
</MenuList>
|
|
81
|
+
</Menu>
|
|
82
|
+
</div>
|
|
40
83
|
)
|
|
41
84
|
}
|
|
42
85
|
|
|
@@ -55,26 +98,28 @@ export const SecondaryActions = ({
|
|
|
55
98
|
? secondaryActions.map((action, i) => {
|
|
56
99
|
if ('menuItems' in action) {
|
|
57
100
|
return {
|
|
58
|
-
key:
|
|
101
|
+
key: `titleblock_secondary_action_${i}`,
|
|
59
102
|
node: (
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
103
|
+
<div className={styles.secondaryButtonContainer}>
|
|
104
|
+
<Menu
|
|
105
|
+
align="right"
|
|
106
|
+
button={
|
|
107
|
+
<Button
|
|
108
|
+
secondary
|
|
109
|
+
label={action.label}
|
|
110
|
+
reversed={reversed}
|
|
111
|
+
icon={<Icon name="keyboard_arrow_down" isPresentational />}
|
|
112
|
+
iconPosition="end"
|
|
113
|
+
/>
|
|
114
|
+
}
|
|
115
|
+
>
|
|
116
|
+
<MenuList>
|
|
117
|
+
{action.menuItems.map((menuItem, i2) => (
|
|
118
|
+
<TitleBlockMenuItem key={i2} {...menuItem} />
|
|
119
|
+
))}
|
|
120
|
+
</MenuList>
|
|
121
|
+
</Menu>
|
|
122
|
+
</div>
|
|
78
123
|
),
|
|
79
124
|
}
|
|
80
125
|
} else {
|
|
@@ -86,15 +131,17 @@ export const SecondaryActions = ({
|
|
|
86
131
|
)
|
|
87
132
|
}
|
|
88
133
|
return {
|
|
89
|
-
key: `${i}`,
|
|
134
|
+
key: `${i}`,
|
|
90
135
|
node: (
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
136
|
+
<div className={styles.secondaryButtonContainer}>
|
|
137
|
+
<Button
|
|
138
|
+
secondary
|
|
139
|
+
reversed={reversed}
|
|
140
|
+
{...action}
|
|
141
|
+
data-automation-id="title-block-secondary-actions-button"
|
|
142
|
+
data-testid="title-block-secondary-actions-button"
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
98
145
|
),
|
|
99
146
|
}
|
|
100
147
|
}
|
|
@@ -102,6 +149,11 @@ export const SecondaryActions = ({
|
|
|
102
149
|
: []
|
|
103
150
|
|
|
104
151
|
const overflowMenu = renderSecondaryOverflowMenu(secondaryOverflowMenuItems, reversed)
|
|
152
|
+
const combinedOverflowMenu = renderCombinedSecondaryOverflowMenu(
|
|
153
|
+
secondaryActions,
|
|
154
|
+
secondaryOverflowMenuItems,
|
|
155
|
+
reversed,
|
|
156
|
+
)
|
|
105
157
|
|
|
106
158
|
const toolbarItems = [
|
|
107
159
|
...secondaryActionsAsToolbarItems,
|
|
@@ -113,6 +165,14 @@ export const SecondaryActions = ({
|
|
|
113
165
|
},
|
|
114
166
|
]
|
|
115
167
|
: []),
|
|
168
|
+
...(combinedOverflowMenu
|
|
169
|
+
? [
|
|
170
|
+
{
|
|
171
|
+
key: 'combinedOverflowMenu',
|
|
172
|
+
node: combinedOverflowMenu,
|
|
173
|
+
},
|
|
174
|
+
]
|
|
175
|
+
: []),
|
|
116
176
|
]
|
|
117
177
|
|
|
118
178
|
return (
|
|
@@ -21,6 +21,7 @@ export const Toolbar = ({ items, noGap = false, automationId }: ToolbarProps): J
|
|
|
21
21
|
if (!items || items?.length === 0) {
|
|
22
22
|
return <></>
|
|
23
23
|
}
|
|
24
|
+
|
|
24
25
|
return (
|
|
25
26
|
<div className={styles.toolbar} data-automation-id={automationId} data-testid={automationId}>
|
|
26
27
|
{items.map((item) => (
|