@kaizen/components 2.2.3 → 2.3.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/codemods/migrateGuidanceBlockActionsToActionsSlot/migrateGuidanceBlockActionsToActionsSlot.spec.ts +209 -26
- package/codemods/migrateGuidanceBlockActionsToActionsSlot/migrateGuidanceBlockActionsToActionsSlot.ts +24 -1
- package/codemods/migrateGuidanceBlockActionsToActionsSlot/transformActionsToActionsSlot.spec.ts +107 -1
- package/codemods/migrateGuidanceBlockActionsToActionsSlot/transformActionsToActionsSlot.ts +20 -0
- package/codemods/runV1Codemods/__snapshots__/runV1Codemods.spec.ts.snap +2 -3
- package/codemods/runV1Codemods/runV1Codemods.spec.ts +2 -3
- package/codemods/utils/transformV1ButtonPropsToButtonOrLinkButton.ts +44 -14
- package/dist/cjs/src/MenuV1/index.cjs +4 -3
- package/dist/cjs/src/TitleBlock/TitleBlock.cjs +26 -36
- package/dist/cjs/src/TitleBlock/TitleBlock.module.scss.cjs +3 -0
- 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 +27 -37
- package/dist/esm/src/TitleBlock/TitleBlock.module.scss.mjs +3 -0
- 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 +51 -201
- 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/TitleBlock/TitleBlock.module.scss +28 -10
- package/src/TitleBlock/TitleBlock.spec.tsx +33 -461
- package/src/TitleBlock/TitleBlock.tsx +4 -24
- package/src/TitleBlock/_docs/TitleBlock.stories.tsx +25 -5
- package/src/TitleBlock/_mixins.scss +6 -0
- package/src/TitleBlock/subcomponents/MainActions.module.scss +27 -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
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState } from 'react'
|
|
2
|
-
import classnames from 'classnames'
|
|
3
|
-
import { FocusOn } from 'react-focus-on'
|
|
4
|
-
import type { ButtonProps } from '~components/Button'
|
|
5
|
-
import { Icon } from '~components/Icon'
|
|
6
|
-
import { MenuHeading, MenuItem, MenuList } from '~components/MenuV1'
|
|
7
|
-
import { TITLE_BLOCK_ZEN_OTHER_ACTIONS_HTML_ID } from '../constants'
|
|
8
|
-
import {
|
|
9
|
-
type DefaultActionProps,
|
|
10
|
-
type PrimaryActionProps,
|
|
11
|
-
type SecondaryActionsProps,
|
|
12
|
-
type TitleBlockButtonProps,
|
|
13
|
-
type TitleBlockMenuGroup,
|
|
14
|
-
type TitleBlockMenuItemProps,
|
|
15
|
-
} from '../types'
|
|
16
|
-
import { convertSecondaryActionsToMenuItems, isMenuGroupNotButton } from '../utils'
|
|
17
|
-
import { TitleBlockMenuItem } from './TitleBlockMenuItem'
|
|
18
|
-
|
|
19
|
-
import styles from './MobileActions.module.scss'
|
|
20
|
-
|
|
21
|
-
const menuItemIsLink: (item: TitleBlockMenuItemProps) => boolean = (item) => 'href' in item
|
|
22
|
-
|
|
23
|
-
const defaultActionIsLink: (action: DefaultActionProps) => boolean = (action) => 'href' in action
|
|
24
|
-
|
|
25
|
-
const defaultActionIsButton: (action: DefaultActionProps) => boolean = (action) =>
|
|
26
|
-
(!('href' in action) && 'onClick' in action) || 'component' in action
|
|
27
|
-
|
|
28
|
-
const filterActions = (
|
|
29
|
-
menuItems: TitleBlockMenuItemProps[],
|
|
30
|
-
filterType: 'link' | 'action',
|
|
31
|
-
): TitleBlockMenuItemProps[] =>
|
|
32
|
-
menuItems.filter((item) => (filterType === 'link' ? menuItemIsLink(item) : !menuItemIsLink(item)))
|
|
33
|
-
|
|
34
|
-
/** Returns a filtered array of TitleBlockMenuItem based on actionType
|
|
35
|
-
* This is use to sort a selectively render the action into a specifc order
|
|
36
|
-
*/
|
|
37
|
-
const renderPrimaryActionDrawerContent = (
|
|
38
|
-
primaryAction: PrimaryActionProps,
|
|
39
|
-
actionType: 'link' | 'action',
|
|
40
|
-
): JSX.Element[] | null => {
|
|
41
|
-
if (!primaryAction) return null
|
|
42
|
-
|
|
43
|
-
if (isMenuGroupNotButton(primaryAction)) {
|
|
44
|
-
const filteredActions = filterActions(primaryAction.menuItems, actionType)
|
|
45
|
-
return filteredActions.map((item, idx) => {
|
|
46
|
-
const itemType = menuItemIsLink(item) ? 'link' : 'action'
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<TitleBlockMenuItem
|
|
50
|
-
{...item}
|
|
51
|
-
key={`title-block-mobile-actions-primary-${itemType}-${idx}`}
|
|
52
|
-
data-automation-id={`title-block-mobile-actions-primary-${itemType}-${idx}`}
|
|
53
|
-
data-testid={`title-block-mobile-actions-primary-${itemType}-${idx}`}
|
|
54
|
-
/>
|
|
55
|
-
)
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return null
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const renderDefaultLink = (defaultAction: DefaultActionProps): JSX.Element | undefined => {
|
|
63
|
-
if (!defaultActionIsLink(defaultAction)) return
|
|
64
|
-
if ('component' in defaultAction) {
|
|
65
|
-
return (
|
|
66
|
-
<TitleBlockMenuItem
|
|
67
|
-
{...defaultAction}
|
|
68
|
-
key="title-block-mobile-actions-default-link"
|
|
69
|
-
data-automation-id="title-block-mobile-actions-default-link"
|
|
70
|
-
data-testid="title-block-mobile-actions-default-link"
|
|
71
|
-
/>
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
return (
|
|
75
|
-
<MenuItem
|
|
76
|
-
href={defaultAction.href}
|
|
77
|
-
label={defaultAction.label}
|
|
78
|
-
icon={defaultAction.icon}
|
|
79
|
-
disabled={defaultAction.disabled}
|
|
80
|
-
key="title-block-mobile-actions-default-link"
|
|
81
|
-
data-automation-id="title-block-mobile-actions-default-link"
|
|
82
|
-
data-testid="title-block-mobile-actions-default-link"
|
|
83
|
-
id={defaultAction.id}
|
|
84
|
-
/>
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const renderDefaultAction = (defaultAction: DefaultActionProps): JSX.Element | null => {
|
|
89
|
-
if (!defaultActionIsLink(defaultAction)) {
|
|
90
|
-
return (
|
|
91
|
-
<TitleBlockMenuItem
|
|
92
|
-
{...defaultAction}
|
|
93
|
-
key="title-block-mobile-actions-default-action"
|
|
94
|
-
data-automation-id="title-block-mobile-actions-default-action"
|
|
95
|
-
data-testid="title-block-mobile-actions-default-action"
|
|
96
|
-
/>
|
|
97
|
-
)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return null
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const renderSecondaryActions = (
|
|
104
|
-
secondaryActions: SecondaryActionsProps | undefined,
|
|
105
|
-
): JSX.Element[] | null => {
|
|
106
|
-
if (!secondaryActions) return null
|
|
107
|
-
const secondaryActionMenuItems: TitleBlockMenuItemProps[] =
|
|
108
|
-
convertSecondaryActionsToMenuItems(secondaryActions)
|
|
109
|
-
|
|
110
|
-
return secondaryActionMenuItems.map((item, idx) => (
|
|
111
|
-
<TitleBlockMenuItem
|
|
112
|
-
{...item}
|
|
113
|
-
key={`title-block-mobile-actions-secondary-action-${idx}`}
|
|
114
|
-
data-testid="title-block-mobile-actions-secondary-action"
|
|
115
|
-
/>
|
|
116
|
-
))
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const renderSecondaryOverflowMenuItems = (
|
|
120
|
-
secondaryOverflowMenuItems: TitleBlockMenuItemProps[],
|
|
121
|
-
): JSX.Element[] =>
|
|
122
|
-
secondaryOverflowMenuItems.map((item, idx) => (
|
|
123
|
-
<TitleBlockMenuItem
|
|
124
|
-
{...item}
|
|
125
|
-
key={`title-block-mobile-actions-overflow-menu-item-${idx}`}
|
|
126
|
-
data-testid="title-block-mobile-actions-overflow-menu-item"
|
|
127
|
-
/>
|
|
128
|
-
))
|
|
129
|
-
|
|
130
|
-
type DrawerMenuContentProps = {
|
|
131
|
-
primaryAction?: PrimaryActionProps
|
|
132
|
-
defaultAction?: DefaultActionProps
|
|
133
|
-
secondaryActions?: SecondaryActionsProps
|
|
134
|
-
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[]
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const DrawerMenuContent = ({
|
|
138
|
-
primaryAction,
|
|
139
|
-
defaultAction,
|
|
140
|
-
secondaryActions,
|
|
141
|
-
secondaryOverflowMenuItems,
|
|
142
|
-
}: DrawerMenuContentProps): JSX.Element => {
|
|
143
|
-
const showOtherActionsHeading =
|
|
144
|
-
(defaultAction && defaultActionIsButton(defaultAction)) ??
|
|
145
|
-
secondaryActions ??
|
|
146
|
-
secondaryOverflowMenuItems
|
|
147
|
-
|
|
148
|
-
return (
|
|
149
|
-
<>
|
|
150
|
-
<MenuList>
|
|
151
|
-
{primaryAction && renderPrimaryActionDrawerContent(primaryAction, 'link')}
|
|
152
|
-
{defaultAction && renderDefaultLink(defaultAction)}
|
|
153
|
-
{primaryAction && renderPrimaryActionDrawerContent(primaryAction, 'action')}
|
|
154
|
-
</MenuList>
|
|
155
|
-
{(defaultAction ?? secondaryActions ?? secondaryOverflowMenuItems) && (
|
|
156
|
-
<MenuList
|
|
157
|
-
heading={showOtherActionsHeading ? <MenuHeading>Other actions</MenuHeading> : undefined}
|
|
158
|
-
>
|
|
159
|
-
{defaultAction && renderDefaultAction(defaultAction)}
|
|
160
|
-
{secondaryActions && renderSecondaryActions(secondaryActions)}
|
|
161
|
-
{secondaryOverflowMenuItems &&
|
|
162
|
-
renderSecondaryOverflowMenuItems(secondaryOverflowMenuItems)}
|
|
163
|
-
</MenuList>
|
|
164
|
-
)}
|
|
165
|
-
</>
|
|
166
|
-
)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const renderDrawerHandleLabel = (
|
|
170
|
-
label: string,
|
|
171
|
-
icon?: JSX.Element,
|
|
172
|
-
drawerHandleLabelIconPosition?: ButtonProps['iconPosition'],
|
|
173
|
-
): JSX.Element => {
|
|
174
|
-
if (drawerHandleLabelIconPosition === 'end') {
|
|
175
|
-
return (
|
|
176
|
-
<>
|
|
177
|
-
<span className={styles.drawerHandleLabelText} data-testid="drawer-handle-lable-text">
|
|
178
|
-
{label}
|
|
179
|
-
</span>
|
|
180
|
-
<>{icon && <span className={styles.drawerHandleIcon}>{icon}</span>}</>
|
|
181
|
-
</>
|
|
182
|
-
)
|
|
183
|
-
} else {
|
|
184
|
-
return (
|
|
185
|
-
<>
|
|
186
|
-
<>{icon && <span className={styles.drawerHandleIcon}>{icon}</span>}</>
|
|
187
|
-
<span className={styles.drawerHandleLabelText} data-testid="drawer-handle-lable-text">
|
|
188
|
-
{label}
|
|
189
|
-
</span>
|
|
190
|
-
</>
|
|
191
|
-
)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
type HrefAndOnClick = Pick<TitleBlockButtonProps, 'href' | 'onClick'>
|
|
196
|
-
type ButtonOrLinkActionProps =
|
|
197
|
-
| HrefAndOnClick
|
|
198
|
-
| TitleBlockButtonProps['href']
|
|
199
|
-
| TitleBlockButtonProps['onClick']
|
|
200
|
-
type ButtonOrLinkProps = {
|
|
201
|
-
action?: ButtonOrLinkActionProps
|
|
202
|
-
children: React.ReactNode
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const ButtonOrLink = ({ action, children }: ButtonOrLinkProps): JSX.Element => {
|
|
206
|
-
if (typeof action === 'object' && 'onClick' in action && 'href' in action) {
|
|
207
|
-
return (
|
|
208
|
-
<a
|
|
209
|
-
onClick={action.onClick}
|
|
210
|
-
href={action.href}
|
|
211
|
-
className={classnames(styles.mobileActionsPrimaryLabel, styles.mobileActionsPrimaryButton)}
|
|
212
|
-
data-testid="title-block-mobile-actions-primary-button"
|
|
213
|
-
>
|
|
214
|
-
{children}
|
|
215
|
-
</a>
|
|
216
|
-
)
|
|
217
|
-
}
|
|
218
|
-
if (typeof action === 'function') {
|
|
219
|
-
return (
|
|
220
|
-
<button
|
|
221
|
-
type="button"
|
|
222
|
-
onClick={action}
|
|
223
|
-
className={classnames(styles.mobileActionsPrimaryLabel, styles.mobileActionsPrimaryButton)}
|
|
224
|
-
data-testid="title-block-mobile-actions-primary-button"
|
|
225
|
-
>
|
|
226
|
-
{children}
|
|
227
|
-
</button>
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
if (typeof action === 'string') {
|
|
231
|
-
return (
|
|
232
|
-
<a
|
|
233
|
-
href={action}
|
|
234
|
-
className={classnames(styles.mobileActionsPrimaryLabel, styles.mobileActionsPrimaryButton)}
|
|
235
|
-
data-testid="title-block-mobile-actions-primary-button"
|
|
236
|
-
>
|
|
237
|
-
{children}
|
|
238
|
-
</a>
|
|
239
|
-
)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// when there's no action (e.g. primary button is disabled)
|
|
243
|
-
return (
|
|
244
|
-
<button
|
|
245
|
-
type="button"
|
|
246
|
-
className={classnames(styles.mobileActionsPrimaryLabel, styles.mobileActionsPrimaryButton)}
|
|
247
|
-
data-testid="title-block-mobile-actions-primary-button"
|
|
248
|
-
>
|
|
249
|
-
{children}
|
|
250
|
-
</button>
|
|
251
|
-
)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const getAction = (primaryAction: TitleBlockButtonProps): ButtonOrLinkActionProps => {
|
|
255
|
-
if (primaryAction && !primaryAction.disabled) {
|
|
256
|
-
if (primaryAction.onClick && primaryAction.href) {
|
|
257
|
-
return {
|
|
258
|
-
href: primaryAction.href,
|
|
259
|
-
onClick: primaryAction.onClick,
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
if (primaryAction.onClick) {
|
|
263
|
-
return primaryAction.onClick
|
|
264
|
-
}
|
|
265
|
-
if (primaryAction.href) {
|
|
266
|
-
return primaryAction.href
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return undefined
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
type DrawerHandleProps = {
|
|
274
|
-
primaryAction: PrimaryActionProps | undefined
|
|
275
|
-
secondaryActions: SecondaryActionsProps | undefined
|
|
276
|
-
defaultAction?: DefaultActionProps | TitleBlockMenuGroup
|
|
277
|
-
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[]
|
|
278
|
-
drawerHandleLabelIconPosition?: ButtonProps['iconPosition']
|
|
279
|
-
toggleDisplay: () => void
|
|
280
|
-
isOpen: boolean
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const DrawerHandle = ({
|
|
284
|
-
primaryAction,
|
|
285
|
-
secondaryActions,
|
|
286
|
-
defaultAction,
|
|
287
|
-
secondaryOverflowMenuItems,
|
|
288
|
-
drawerHandleLabelIconPosition,
|
|
289
|
-
toggleDisplay,
|
|
290
|
-
isOpen,
|
|
291
|
-
}: DrawerHandleProps): JSX.Element | null => {
|
|
292
|
-
const showDrawer = defaultAction ?? secondaryActions ?? secondaryOverflowMenuItems
|
|
293
|
-
if (primaryAction) {
|
|
294
|
-
// If the primary action is a menu
|
|
295
|
-
if (isMenuGroupNotButton(primaryAction)) {
|
|
296
|
-
return (
|
|
297
|
-
<div
|
|
298
|
-
className={classnames(styles.mobileActionsTopRow, styles.mobileActionsTopRowSingleButton)}
|
|
299
|
-
data-testid="title-block-mobile-actions-drawer-handle"
|
|
300
|
-
>
|
|
301
|
-
<button
|
|
302
|
-
type="button"
|
|
303
|
-
className={classnames(
|
|
304
|
-
styles.mobileActionsExpandButton,
|
|
305
|
-
styles.mobileActionsPrimaryLabel,
|
|
306
|
-
)}
|
|
307
|
-
onClick={toggleDisplay}
|
|
308
|
-
aria-expanded={isOpen}
|
|
309
|
-
>
|
|
310
|
-
{primaryAction.label}
|
|
311
|
-
<span className={styles.mobileActionsChevronSquare}>
|
|
312
|
-
<Icon name={isOpen ? 'keyboard_arrow_down' : 'keyboard_arrow_up'} isPresentational />
|
|
313
|
-
</span>
|
|
314
|
-
</button>
|
|
315
|
-
</div>
|
|
316
|
-
)
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// If the primary action is a button, or has no onClick/href/action
|
|
320
|
-
return (
|
|
321
|
-
<div
|
|
322
|
-
className={classnames(
|
|
323
|
-
styles.mobileActionsTopRow,
|
|
324
|
-
!showDrawer && styles.mobileActionsTopRowSingleButton,
|
|
325
|
-
)}
|
|
326
|
-
data-testid="title-block-mobile-actions-drawer-handle"
|
|
327
|
-
>
|
|
328
|
-
{'component' in primaryAction ? (
|
|
329
|
-
<primaryAction.component
|
|
330
|
-
className={classnames(
|
|
331
|
-
styles.mobileActionsPrimaryLabel,
|
|
332
|
-
styles.mobileActionsPrimaryButton,
|
|
333
|
-
)}
|
|
334
|
-
{...primaryAction}
|
|
335
|
-
>
|
|
336
|
-
{primaryAction.label &&
|
|
337
|
-
renderDrawerHandleLabel(
|
|
338
|
-
primaryAction.label,
|
|
339
|
-
primaryAction.icon,
|
|
340
|
-
drawerHandleLabelIconPosition,
|
|
341
|
-
)}
|
|
342
|
-
</primaryAction.component>
|
|
343
|
-
) : (
|
|
344
|
-
<ButtonOrLink action={getAction(primaryAction)}>
|
|
345
|
-
{renderDrawerHandleLabel(
|
|
346
|
-
primaryAction.label,
|
|
347
|
-
primaryAction.icon,
|
|
348
|
-
drawerHandleLabelIconPosition,
|
|
349
|
-
)}
|
|
350
|
-
</ButtonOrLink>
|
|
351
|
-
)}
|
|
352
|
-
|
|
353
|
-
{/* If there are no secondary etc. actions, just show the button without drawer */}
|
|
354
|
-
{showDrawer && (
|
|
355
|
-
<button
|
|
356
|
-
type="button"
|
|
357
|
-
className={styles.mobileActionsExpandButton}
|
|
358
|
-
onClick={toggleDisplay}
|
|
359
|
-
aria-expanded={isOpen}
|
|
360
|
-
id={TITLE_BLOCK_ZEN_OTHER_ACTIONS_HTML_ID}
|
|
361
|
-
aria-label="Other actions"
|
|
362
|
-
>
|
|
363
|
-
<Icon name={isOpen ? 'keyboard_arrow_down' : 'keyboard_arrow_up'} isPresentational />
|
|
364
|
-
</button>
|
|
365
|
-
)}
|
|
366
|
-
</div>
|
|
367
|
-
)
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// if there are default/secondary actions but no primary action
|
|
371
|
-
if (showDrawer) {
|
|
372
|
-
return (
|
|
373
|
-
<div
|
|
374
|
-
className={classnames(styles.mobileActionsTopRow, styles.mobileActionsTopRowSingleButton)}
|
|
375
|
-
data-testid="title-block-mobile-actions-drawer-handle"
|
|
376
|
-
>
|
|
377
|
-
<button
|
|
378
|
-
type="button"
|
|
379
|
-
className={classnames(styles.mobileActionsExpandButton, styles.mobileActionsPrimaryLabel)}
|
|
380
|
-
onClick={toggleDisplay}
|
|
381
|
-
aria-expanded={isOpen}
|
|
382
|
-
id={TITLE_BLOCK_ZEN_OTHER_ACTIONS_HTML_ID}
|
|
383
|
-
>
|
|
384
|
-
{renderDrawerHandleLabel('Other actions')}
|
|
385
|
-
<span className={styles.mobileActionsChevronSquare}>
|
|
386
|
-
<Icon name={isOpen ? 'keyboard_arrow_down' : 'keyboard_arrow_up'} isPresentational />
|
|
387
|
-
</span>
|
|
388
|
-
</button>
|
|
389
|
-
</div>
|
|
390
|
-
)
|
|
391
|
-
}
|
|
392
|
-
return null
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export type MobileActionsProps = {
|
|
396
|
-
primaryAction?: PrimaryActionProps
|
|
397
|
-
defaultAction?: DefaultActionProps
|
|
398
|
-
secondaryActions?: SecondaryActionsProps
|
|
399
|
-
secondaryOverflowMenuItems?: TitleBlockMenuItemProps[]
|
|
400
|
-
drawerHandleLabelIconPosition?: ButtonProps['iconPosition']
|
|
401
|
-
autoHide?: boolean
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export const MobileActions = ({
|
|
405
|
-
primaryAction,
|
|
406
|
-
defaultAction,
|
|
407
|
-
secondaryActions,
|
|
408
|
-
secondaryOverflowMenuItems,
|
|
409
|
-
drawerHandleLabelIconPosition,
|
|
410
|
-
autoHide = false,
|
|
411
|
-
}: MobileActionsProps): JSX.Element => {
|
|
412
|
-
const [isOpen, setIsOpen] = useState<boolean>(false)
|
|
413
|
-
const menuContent = React.createRef<HTMLDivElement>()
|
|
414
|
-
const toggleDisplay = (): void => {
|
|
415
|
-
setIsOpen(!isOpen)
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// This callback handler will not run when autoHide === "off"
|
|
419
|
-
const handleDocumentClickForAutoHide = useCallback(
|
|
420
|
-
(e: MouseEvent) => {
|
|
421
|
-
if (isOpen && e.target instanceof Node && menuContent.current?.contains(e.target)) {
|
|
422
|
-
setIsOpen(false)
|
|
423
|
-
}
|
|
424
|
-
},
|
|
425
|
-
// @todo: Fix if possible - avoiding breaking in eslint upgrade
|
|
426
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
427
|
-
[menuContent],
|
|
428
|
-
)
|
|
429
|
-
|
|
430
|
-
useEffect(() => {
|
|
431
|
-
if (autoHide) {
|
|
432
|
-
document.addEventListener('click', handleDocumentClickForAutoHide, true)
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return () => {
|
|
436
|
-
if (autoHide) {
|
|
437
|
-
document.removeEventListener('click', handleDocumentClickForAutoHide, true)
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}, [autoHide, handleDocumentClickForAutoHide])
|
|
441
|
-
|
|
442
|
-
return (
|
|
443
|
-
<div className={classnames(styles.mobileActionsContainer, isOpen && styles.isOpen)}>
|
|
444
|
-
<FocusOn enabled={isOpen} scrollLock={false}>
|
|
445
|
-
<DrawerHandle
|
|
446
|
-
primaryAction={primaryAction}
|
|
447
|
-
secondaryActions={secondaryActions}
|
|
448
|
-
defaultAction={defaultAction}
|
|
449
|
-
secondaryOverflowMenuItems={secondaryOverflowMenuItems}
|
|
450
|
-
drawerHandleLabelIconPosition={drawerHandleLabelIconPosition}
|
|
451
|
-
toggleDisplay={toggleDisplay}
|
|
452
|
-
isOpen={isOpen}
|
|
453
|
-
/>
|
|
454
|
-
{(defaultAction ??
|
|
455
|
-
secondaryActions ??
|
|
456
|
-
secondaryOverflowMenuItems ??
|
|
457
|
-
(primaryAction && isMenuGroupNotButton(primaryAction))) && (
|
|
458
|
-
<div ref={menuContent} className={styles.mobileActionsMenuContainer}>
|
|
459
|
-
<DrawerMenuContent
|
|
460
|
-
primaryAction={primaryAction}
|
|
461
|
-
defaultAction={defaultAction}
|
|
462
|
-
secondaryActions={secondaryActions}
|
|
463
|
-
secondaryOverflowMenuItems={secondaryOverflowMenuItems}
|
|
464
|
-
/>
|
|
465
|
-
</div>
|
|
466
|
-
)}
|
|
467
|
-
</FocusOn>
|
|
468
|
-
</div>
|
|
469
|
-
)
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
MobileActions.displayName = 'MobileActions'
|