@@ -698,8 +698,8 @@ export default {
698
698
</NcActions>
699
699
</p>
700
700
701
- <h2>Popover </h2>
702
- Has any elements, including text input element, or no buttons.
701
+ <h2>Dialog </h2>
702
+ Includes data input elements
703
703
<p>
704
704
<NcActions aria-label="Group management">
705
705
<NcActionInput trailing-button-label="Submit" label="Rename group">
@@ -715,6 +715,19 @@ export default {
715
715
</NcActionButton>
716
716
</NcActions>
717
717
</p>
718
+
719
+ <h2>Toolip</h2>
720
+ Has only text and not interactive elements
721
+ <p>
722
+ <NcActions aria-label="Contact" :inline="1">
723
+ <NcActionLink aria-label="View profile" href="/u/alice" icon="icon-user-white">
724
+ View profile
725
+ </NcActionLink>
726
+ <NcActionText icon="icon-timezone-white">
727
+ Local time: 10:12
728
+ </NcActionText>
729
+ </NcActions>
730
+ </p>
718
731
</div>
719
732
</template>
720
733
794
807
}
795
808
</style>
796
809
```
797
-
798
810
</docs >
799
811
800
812
<script >
@@ -836,7 +848,7 @@ export default {
836
848
* Provide the role for NcAction* components in the NcActions content.
837
849
* @type {import('vue').ComputedRef<boolean>}
838
850
*/
839
- ' NcActions:isSemanticMenu' : computed (() => this .isSemanticMenu ),
851
+ ' NcActions:isSemanticMenu' : computed (() => this .actionsMenuSemanticType === ' menu ' ),
840
852
}
841
853
},
842
854
@@ -992,9 +1004,10 @@ export default {
992
1004
opened: this .open ,
993
1005
focusIndex: 0 ,
994
1006
randomId: ` menu-${ GenRandomId ()} ` ,
995
- isSemanticMenu: false ,
996
- isSemanticNavigation: false ,
997
- isSemanticPopoverLike: false ,
1007
+ /**
1008
+ * @type {'menu'|'navigation'|'dialog'|'tooltip'|''}
1009
+ */
1010
+ actionsMenuSemanticType: ' ' ,
998
1011
}
999
1012
},
1000
1013
@@ -1006,6 +1019,10 @@ export default {
1006
1019
// If it has a name, we use a secondary button
1007
1020
: this .menuName ? ' secondary' : ' tertiary' )
1008
1021
},
1022
+
1023
+ withFocusTrap () {
1024
+ return this .actionsMenuSemanticType === ' dialog'
1025
+ },
1009
1026
},
1010
1027
1011
1028
watch: {
@@ -1097,8 +1114,10 @@ export default {
1097
1114
// close everything
1098
1115
this .focusIndex = 0
1099
1116
1100
- // focus back the menu button
1101
- this .$refs .menuButton .$el .focus ()
1117
+ if (returnFocus) {
1118
+ // Focus back the menu button
1119
+ this .$refs .menuButton .$el .focus ()
1120
+ }
1102
1121
},
1103
1122
1104
1123
onOpen (event ) {
@@ -1136,8 +1155,10 @@ export default {
1136
1155
* @param {object} event The keydown event
1137
1156
*/
1138
1157
onKeydown (event ) {
1139
- if (event .key === ' Tab' && ! this .isSemanticPopoverLike ) {
1140
- this .closeMenu (false )
1158
+ if (event .key === ' Tab' && ! this .withFocusTrap ) {
1159
+ // Return focus to restore Tab sequence
1160
+ // So browser will correctly move focus to the next element
1161
+ this .closeMenu (true )
1141
1162
}
1142
1163
1143
1164
if (event .key === ' ArrowUp' ) {
@@ -1231,6 +1252,12 @@ export default {
1231
1252
},
1232
1253
onBlur (event ) {
1233
1254
this .$emit (' blur' , event )
1255
+
1256
+ // When there is no focusable elements to handle Tab press from actions menu
1257
+ // It requries manual closing
1258
+ if (this .actionsMenuSemanticType === ' tooltip' ) {
1259
+ this .closeMenu (false )
1260
+ }
1234
1261
},
1235
1262
},
1236
1263
@@ -1287,18 +1314,23 @@ export default {
1287
1314
const hasMenuItemAction = menuActions .some (action => menuItemsActions .includes (this .getActionName (action)))
1288
1315
const hasLinkAction = menuActions .some (action => linkActions .includes (this .getActionName (action)))
1289
1316
1290
- // We consider the NcActions to have role="menu" if it consists some button-like action and not text inputs
1291
- this .isSemanticMenu = hasMenuItemAction && ! hasTextInputAction
1292
- // We consider the NcActions to be navigation if it consists some link-like action
1293
- this .isSemanticNavigation = hasLinkAction && ! hasMenuItemAction && ! hasTextInputAction
1294
- // If it is not a menu and not a navigation, it is a popover with items: a form or just a text
1295
- this .isSemanticPopoverLike = ! this .isSemanticMenu && ! this .isSemanticNavigation
1317
+ if (hasTextInputAction) {
1318
+ this .actionsMenuSemanticType = ' dialog'
1319
+ } else if (hasMenuItemAction) {
1320
+ this .actionsMenuSemanticType = ' menu'
1321
+ } else if (hasLinkAction) {
1322
+ this .actionsMenuSemanticType = ' navigation'
1323
+ } else {
1324
+ this .actionsMenuSemanticType = ' tooltip'
1325
+ }
1296
1326
1297
- const popupRole = this .isSemanticMenu
1298
- ? ' menu'
1299
- : hasTextInputAction
1300
- ? ' dialog'
1301
- : ' true'
1327
+ const actionsRoleToHtmlPopupRole = {
1328
+ dialog: ' dialog' ,
1329
+ menu: ' menu' ,
1330
+ navigation: ' true' ,
1331
+ tooltip: ' true' ,
1332
+ }
1333
+ const popupRole = actionsRoleToHtmlPopupRole[this .actionsMenuSemanticType ]
1302
1334
1303
1335
/**
1304
1336
* Render the provided action
@@ -1404,10 +1436,8 @@ export default {
1404
1436
container: this .container ,
1405
1437
popoverBaseClass: ' action-item__popper' ,
1406
1438
popupRole,
1407
- // Menu and navigation should not have focus trap
1408
- // Tab should close the menu and move focus to the next UI element
1409
- setReturnFocus: ! this .isSemanticPopoverLike ? null : this .$refs .menuButton ? .$el ,
1410
- focusTrap: this .isSemanticPopoverLike ,
1439
+ setReturnFocus: this .withFocusTrap ? this .$refs .menuButton ? .$el : null ,
1440
+ focusTrap: this .withFocusTrap ,
1411
1441
},
1412
1442
// For some reason the popover component
1413
1443
// does not react to props given under the 'props' key,
0 commit comments