@carbon/web-components 2.56.0 → 2.57.0-rc.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.
Files changed (110) hide show
  1. package/custom-elements.json +94 -16
  2. package/es/components/breadcrumb/breadcrumb.scss.js +1 -1
  3. package/es/components/checkbox/checkbox.d.ts +2 -2
  4. package/es/components/checkbox/checkbox.js.map +1 -1
  5. package/es/components/combo-box/combo-box.scss.js +1 -1
  6. package/es/components/combo-box/combo-box.scss.js.map +1 -1
  7. package/es/components/combo-button/combo-button.js +1 -1
  8. package/es/components/data-table/data-table.scss.js +1 -1
  9. package/es/components/dropdown/defs.d.ts +5 -1
  10. package/es/components/dropdown/defs.d.ts.map +1 -1
  11. package/es/components/dropdown/defs.js +4 -0
  12. package/es/components/dropdown/defs.js.map +1 -1
  13. package/es/components/dropdown/dropdown.d.ts.map +1 -1
  14. package/es/components/dropdown/dropdown.js +3 -0
  15. package/es/components/dropdown/dropdown.js.map +1 -1
  16. package/es/components/dropdown/dropdown.scss.js +1 -1
  17. package/es/components/dropdown/dropdown.scss.js.map +1 -1
  18. package/es/components/fluid-combo-box/fluid-combo-box.scss.js +1 -1
  19. package/es/components/fluid-dropdown/fluid-dropdown.scss.js +1 -1
  20. package/es/components/fluid-multi-select/fluid-multi-select.scss.js +1 -1
  21. package/es/components/link/link.scss.js +1 -1
  22. package/es/components/menu/menu-item.js +1 -1
  23. package/es/components/menu-button/menu-button.js +2 -2
  24. package/es/components/multi-select/multi-select.d.ts.map +1 -1
  25. package/es/components/multi-select/multi-select.js +10 -11
  26. package/es/components/multi-select/multi-select.js.map +1 -1
  27. package/es/components/multi-select/multi-select.scss.js +1 -1
  28. package/es/components/multi-select/multi-select.scss.js.map +1 -1
  29. package/es/components/overflow-menu/overflow-menu.d.ts +70 -0
  30. package/es/components/overflow-menu/overflow-menu.d.ts.map +1 -1
  31. package/es/components/overflow-menu/overflow-menu.js +256 -17
  32. package/es/components/overflow-menu/overflow-menu.js.map +1 -1
  33. package/es/components/pagination-nav/pagination-nav.js +1 -1
  34. package/es/components/tabs/tabs.d.ts +0 -4
  35. package/es/components/tabs/tabs.d.ts.map +1 -1
  36. package/es/components/tabs/tabs.js +0 -1
  37. package/es/components/tabs/tabs.js.map +1 -1
  38. package/es/components/tabs/tabs.scss.js +1 -1
  39. package/es/components/tabs/tabs.scss.js.map +1 -1
  40. package/es/components/tile/clickable-tile.js +1 -1
  41. package/es/components/tile/tile.scss.js +1 -1
  42. package/es/globals/controllers/floating-controller.d.ts +3 -2
  43. package/es/globals/controllers/floating-controller.d.ts.map +1 -1
  44. package/es/globals/controllers/floating-controller.js +5 -3
  45. package/es/globals/controllers/floating-controller.js.map +1 -1
  46. package/es-custom/components/breadcrumb/breadcrumb.scss.js +1 -1
  47. package/es-custom/components/checkbox/checkbox.d.ts +2 -2
  48. package/es-custom/components/checkbox/checkbox.js.map +1 -1
  49. package/es-custom/components/combo-box/combo-box.scss.js +1 -1
  50. package/es-custom/components/combo-box/combo-box.scss.js.map +1 -1
  51. package/es-custom/components/combo-button/combo-button.js +1 -1
  52. package/es-custom/components/data-table/data-table.scss.js +1 -1
  53. package/es-custom/components/dropdown/defs.d.ts +5 -1
  54. package/es-custom/components/dropdown/defs.d.ts.map +1 -1
  55. package/es-custom/components/dropdown/defs.js +4 -0
  56. package/es-custom/components/dropdown/defs.js.map +1 -1
  57. package/es-custom/components/dropdown/dropdown.d.ts.map +1 -1
  58. package/es-custom/components/dropdown/dropdown.js +3 -0
  59. package/es-custom/components/dropdown/dropdown.js.map +1 -1
  60. package/es-custom/components/dropdown/dropdown.scss.js +1 -1
  61. package/es-custom/components/dropdown/dropdown.scss.js.map +1 -1
  62. package/es-custom/components/fluid-combo-box/fluid-combo-box.scss.js +1 -1
  63. package/es-custom/components/fluid-dropdown/fluid-dropdown.scss.js +1 -1
  64. package/es-custom/components/fluid-multi-select/fluid-multi-select.scss.js +1 -1
  65. package/es-custom/components/link/link.scss.js +1 -1
  66. package/es-custom/components/menu/menu-item.js +1 -1
  67. package/es-custom/components/menu-button/menu-button.js +2 -2
  68. package/es-custom/components/multi-select/multi-select.d.ts.map +1 -1
  69. package/es-custom/components/multi-select/multi-select.js +10 -11
  70. package/es-custom/components/multi-select/multi-select.js.map +1 -1
  71. package/es-custom/components/multi-select/multi-select.scss.js +1 -1
  72. package/es-custom/components/multi-select/multi-select.scss.js.map +1 -1
  73. package/es-custom/components/overflow-menu/overflow-menu.d.ts +70 -0
  74. package/es-custom/components/overflow-menu/overflow-menu.d.ts.map +1 -1
  75. package/es-custom/components/overflow-menu/overflow-menu.js +256 -17
  76. package/es-custom/components/overflow-menu/overflow-menu.js.map +1 -1
  77. package/es-custom/components/pagination-nav/pagination-nav.js +1 -1
  78. package/es-custom/components/tabs/tabs.d.ts +0 -4
  79. package/es-custom/components/tabs/tabs.d.ts.map +1 -1
  80. package/es-custom/components/tabs/tabs.js +0 -1
  81. package/es-custom/components/tabs/tabs.js.map +1 -1
  82. package/es-custom/components/tabs/tabs.scss.js +1 -1
  83. package/es-custom/components/tabs/tabs.scss.js.map +1 -1
  84. package/es-custom/components/tile/clickable-tile.js +1 -1
  85. package/es-custom/components/tile/tile.scss.js +1 -1
  86. package/es-custom/globals/controllers/floating-controller.d.ts +3 -2
  87. package/es-custom/globals/controllers/floating-controller.d.ts.map +1 -1
  88. package/es-custom/globals/controllers/floating-controller.js +5 -3
  89. package/es-custom/globals/controllers/floating-controller.js.map +1 -1
  90. package/lib/components/checkbox/checkbox.d.ts +2 -2
  91. package/lib/components/dropdown/defs.d.ts +5 -1
  92. package/lib/components/dropdown/defs.d.ts.map +1 -1
  93. package/lib/components/dropdown/defs.js +4 -0
  94. package/lib/components/dropdown/defs.js.map +1 -1
  95. package/lib/components/dropdown/dropdown.d.ts.map +1 -1
  96. package/lib/components/multi-select/multi-select.d.ts.map +1 -1
  97. package/lib/components/overflow-menu/overflow-menu.d.ts +70 -0
  98. package/lib/components/overflow-menu/overflow-menu.d.ts.map +1 -1
  99. package/lib/components/tabs/tabs.d.ts +0 -4
  100. package/lib/components/tabs/tabs.d.ts.map +1 -1
  101. package/lib/globals/controllers/floating-controller.d.ts +3 -2
  102. package/lib/globals/controllers/floating-controller.d.ts.map +1 -1
  103. package/lib/globals/controllers/floating-controller.js +5 -3
  104. package/lib/globals/controllers/floating-controller.js.map +1 -1
  105. package/package.json +3 -3
  106. package/scss/components/combo-box/combo-box.scss +3 -1
  107. package/scss/components/dropdown/dropdown.scss +6 -1
  108. package/scss/components/multi-select/multi-select.scss +5 -0
  109. package/scss/components/tabs/tabs.scss +27 -7
  110. package/telemetry.yml +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select.scss.js","names":[],"sources":["../../../src/components/multi-select/multi-select.scss?lit"],"sourcesContent":["//\n// Copyright IBM Corp. 2026\n//\n// This source code is licensed under the Apache-2.0 license found in the\n// LICENSE file in the root directory of this source tree.\n//\n\n$css--plex: true !default;\n\n@use '@carbon/styles/scss/config' as *;\n@use '@carbon/styles/scss/theme' as *;\n@use '@carbon/styles/scss/spacing' as *;\n@use '@carbon/styles/scss/utilities' as *;\n@use '@carbon/styles/scss/components/list-box/list-box';\n@use '@carbon/styles/scss/components/multiselect/index';\n@use '@carbon/styles/scss/components/form';\n@use '@carbon/styles/scss/components/checkbox';\n@use '@carbon/styles/scss/components/tag';\n@use '@carbon/styles/scss/utilities/convert';\n\n:host(#{$prefix}-multi-select) {\n box-sizing: border-box;\n outline: none;\n\n .#{$prefix}--assistive-text {\n inset-block-start: -100%;\n // Hides screen reader cursor\n inset-inline-start: -100%;\n }\n\n .#{$prefix}--label[hidden] {\n display: none;\n }\n\n .#{$prefix}--list-box__menu {\n inset-block-start: 100%;\n margin-block-start: 1px;\n outline: none;\n }\n\n .#{$prefix}--text-input {\n border: none;\n padding-inline-start: 0;\n\n &:focus {\n outline: none;\n }\n }\n\n .#{$prefix}--tag--disabled {\n @extend .#{$prefix}--tag--disabled;\n\n background-color: transparent;\n color: $text-disabled;\n }\n\n .#{$prefix}--list-box__field:focus {\n @extend .#{$prefix}--multi-select--filterable--input-focused;\n }\n\n /* stylelint-disable declaration-no-important */\n .#{$prefix}--list-box__selection--multi::after {\n display: none !important;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable]) {\n .#{$prefix}--list-box__field:focus-within {\n outline: $spacing-01 solid $focus;\n outline-offset: -#{$spacing-01};\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-01;\n }\n }\n}\n:host(#{$prefix}-multi-select[filterable][has-value])\n .#{$prefix}--list-box__field\n ~ ::slotted(#{$prefix}-ai-label) {\n inset-inline-end: calc($spacing-10 + 18px);\n}\n\n:host(#{$prefix}-multi-select[direction='top']) {\n @extend .#{$prefix}--list-box--up;\n\n .#{$prefix}--list-box__menu {\n inset-block-start: auto;\n }\n}\n\n:host(#{$prefix}-multi-select[invalid]:not([disabled]):not([read-only])) {\n .#{$prefix}--form__helper-text {\n color: $text-error;\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[type='inline']) {\n @extend .#{$prefix}--list-box__wrapper--inline;\n\n grid-gap: 0 $spacing-03;\n .#{$prefix}--form__helper-text {\n grid-column: 3;\n }\n}\n\n:host(#{$prefix}-multi-select[type='inline'][warn])\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(56px);\n}\n\n:host(#{$prefix}-multi-select-item) {\n @extend .#{$prefix}--list-box__menu-item;\n\n display: block;\n\n #{$prefix}-checkbox::part(label) {\n display: inline-block;\n overflow: hidden;\n inline-size: 100%;\n padding-inline-start: rem(28px);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .#{$prefix}--list-box__menu-item__option {\n box-sizing: border-box;\n\n .#{$prefix}--checkbox-wrapper {\n display: flex;\n align-items: center;\n block-size: 100%;\n inline-size: 100%;\n }\n\n > .#{$prefix}--form-item {\n flex-direction: row;\n }\n }\n // make the checkbox element transparent to mouse events so it doesn't interfere\n #{$prefix}-checkbox {\n pointer-events: none;\n }\n}\n\n:host(#{$prefix}-multi-select-item:hover) {\n background-color: $layer-hover;\n}\n\n:host(#{$prefix}-multi-select-item[filtered]) {\n display: none;\n}\n\n:host(#{$prefix}-multi-select-item[size='sm']) {\n block-size: fit-content;\n .#{$prefix}--list-box__menu-item__option {\n block-size: $spacing-07;\n padding-block: rem(7px);\n }\n}\n\n:host(#{$prefix}-multi-select-item[size='lg']) {\n block-size: fit-content;\n .#{$prefix}--list-box__menu-item__option {\n block-size: $spacing-09;\n padding-block: rem(15px);\n }\n}\n\n:host(#{$prefix}-multi-select-item[disabled]) {\n cursor: not-allowed;\n .#{$prefix}--list-box__menu-item__option {\n color: $text-disabled;\n text-decoration: none;\n }\n}\n\n:host(#{$prefix}-multi-select-item[highlighted]) {\n @extend .#{$prefix}--list-box__menu-item--highlighted;\n}\n\n:host(#{$prefix}-multi-select-item[selected]) {\n @extend .#{$prefix}--list-box__menu-item--active;\n\n .#{$prefix}--list-box__menu-item__option {\n color: $text-primary;\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) {\n @extend .#{$prefix}--list-box__wrapper--slug;\n\n ::slotted(#{$prefix}-ai-label),\n ::slotted(#{$prefix}-slug) {\n position: absolute;\n inset-block-start: 50%;\n inset-inline-end: calc($spacing-08 + 9px);\n margin-block-start: convert.to-rem(0.5px);\n }\n\n ::slotted(#{$prefix}-ai-label:not([revert-active])),\n ::slotted(#{$prefix}-slug:not([revert-active])) {\n transform: translateY(-50%);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][warn]),\n:host(#{$prefix}-multi-select[ai-label][invalid]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: convert.to-rem(81px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) ::slotted(#{$prefix}-ai-label)::after {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: convert.to-rem(1px);\n inset-block-start: 0;\n inset-inline-end: convert.to-rem(-9px);\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][has-value]),\n:host(#{$prefix}-multi-select[filterable][invalid][has-value]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(78px);\n }\n\n .#{$prefix}--list-box__selection#clear-button::before {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: rem(1px);\n inset-inline-end: rem(27px);\n }\n}\n\n// pad space to account for text-input, placeholder and selections\n\n:host(#{$prefix}-multi-select[filterable])\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(45px);\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-01;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid]),\n:host(#{$prefix}-multi-select[filterable][warn]) {\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: 0;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-08;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-05;\n }\n }\n}\n:host(#{$prefix}-multi-select[filterable][ai-label][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-03;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(43px);\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-10;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-08;\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-10;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-11;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(55px);\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-09;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-11;\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(75px);\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label])\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: 0;\n}\n\n:host(#{$prefix}-multi-select[filterable][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-06;\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(45px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn]) {\n ::slotted(#{$prefix}-ai-label)::before {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: convert.to-rem(1px);\n inset-block-start: 0;\n inset-inline-end: convert.to-rem(24px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][warn]),\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn][filterable]),\n:host(#{$prefix}-multi-select[ai-label][invalid][filterable]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-07;\n }\n }\n .#{$prefix}--list-box__field .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(81px);\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(70px);\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label][warn][has-value]),\n:host(#{$prefix}-multi-select[filterable][ai-label][invalid][has-value]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(114px);\n }\n\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(75px);\n }\n }\n\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(65px);\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(114px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(100px);\n }\n }\n .#{$prefix}--multi-select--selected .#{$prefix}--list-box__field {\n padding-inline-end: rem(105px);\n }\n}\n\n// When select all is turned on, the first item in the listbox\n// is always the \"Select all\" option and gets special border\n// treatment\n:host(#{$prefix}-multi-select-item[is-select-all]) {\n .#{$prefix}--list-box__menu-item__option {\n padding: 0.6875rem $spacing-05;\n margin: 0;\n border-block-end: 1px solid $border-subtle-01;\n }\n}\n\n// When select all is turned on, the second item in the list\n// has special treatment to look correct against the \"Select all\"\n// border treatment, this second item (index=1) gets a `flush-top` attribute\n// so that we can remove its top border.\n:host(#{$prefix}-multi-select-item[flush-top])\n .#{$prefix}--list-box__menu-item__option {\n border-block-start: none;\n}\n\n// remove focus outline for when the label is out of focus\n:host(#{$prefix}-multi-select)\n .#{$prefix}--list-box__field.no-focus-style:focus,\n:host(#{$prefix}-multi-select)\n .#{$prefix}--list-box__field.no-focus-style:focus-within {\n outline: none;\n}\n\n:host(#{$prefix}-multi-select[ai-label])\n .#{$prefix}--list-box__wrapper--decorator {\n @include ai-gradient;\n}\n\n:host(#{$prefix}-multi-select[item-clicked]),\n:host(#{$prefix}-multi-select[has-value]) {\n .#{$prefix}--list-box__field,\n .#{$prefix}--multi-select--invalid {\n outline: 1px solid $focus !important;\n outline-offset: -1px !important;\n }\n}\n\n:host(\n #{$prefix}-multi-select[warn]:not([invalid]):not([ai-label]):not(\n [disabled]\n ):not([read-only])\n ) {\n .#{$prefix}--form__helper-text {\n color: $text-primary;\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(\n #{$prefix}-multi-select[warn][invalid]:not([ai-label]):not([disabled]):not(\n [read-only]\n )\n ) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[disabled]) {\n .#{$prefix}--list-box__field,\n .#{$prefix}--list-box__selection {\n pointer-events: none;\n }\n .#{$prefix}--list-box__field:focus,\n .#{$prefix}--list-box__selection:focus {\n outline: none !important;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"multi-select.scss.js","names":[],"sources":["../../../src/components/multi-select/multi-select.scss?lit"],"sourcesContent":["//\n// Copyright IBM Corp. 2026\n//\n// This source code is licensed under the Apache-2.0 license found in the\n// LICENSE file in the root directory of this source tree.\n//\n\n$css--plex: true !default;\n\n@use '@carbon/styles/scss/config' as *;\n@use '@carbon/styles/scss/theme' as *;\n@use '@carbon/styles/scss/spacing' as *;\n@use '@carbon/styles/scss/utilities' as *;\n@use '@carbon/styles/scss/components/list-box/list-box';\n@use '@carbon/styles/scss/components/multiselect/index';\n@use '@carbon/styles/scss/components/form';\n@use '@carbon/styles/scss/components/checkbox';\n@use '@carbon/styles/scss/components/tag';\n@use '@carbon/styles/scss/utilities/convert';\n@use '@carbon/styles/scss/layout' as *;\n\n:host(#{$prefix}-multi-select) {\n @include emit-layout-tokens();\n\n box-sizing: border-box;\n outline: none;\n\n .#{$prefix}--assistive-text {\n inset-block-start: -100%;\n // Hides screen reader cursor\n inset-inline-start: -100%;\n }\n\n .#{$prefix}--label[hidden] {\n display: none;\n }\n\n .#{$prefix}--list-box__menu {\n inset-block-start: 100%;\n margin-block-start: 1px;\n outline: none;\n }\n\n .#{$prefix}--text-input {\n border: none;\n padding-inline-start: 0;\n\n &:focus {\n outline: none;\n }\n }\n\n .#{$prefix}--tag--disabled {\n @extend .#{$prefix}--tag--disabled;\n\n background-color: transparent;\n color: $text-disabled;\n }\n\n .#{$prefix}--list-box__field:focus {\n @extend .#{$prefix}--multi-select--filterable--input-focused;\n }\n\n /* stylelint-disable declaration-no-important */\n .#{$prefix}--list-box__selection--multi::after {\n display: none !important;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable]) {\n .#{$prefix}--list-box__field:focus-within {\n outline: $spacing-01 solid $focus;\n outline-offset: -#{$spacing-01};\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-01;\n }\n }\n}\n:host(#{$prefix}-multi-select[filterable][has-value])\n .#{$prefix}--list-box__field\n ~ ::slotted(#{$prefix}-ai-label) {\n inset-inline-end: calc($spacing-10 + 18px);\n}\n\n:host(#{$prefix}-multi-select[direction='top']) {\n @extend .#{$prefix}--list-box--up;\n\n .#{$prefix}--list-box__menu {\n inset-block-start: auto;\n }\n}\n\n:host(#{$prefix}-multi-select[invalid]:not([disabled]):not([read-only])) {\n .#{$prefix}--form__helper-text {\n color: $text-error;\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[type='inline']) {\n @extend .#{$prefix}--list-box__wrapper--inline;\n\n grid-gap: 0 $spacing-03;\n .#{$prefix}--form__helper-text {\n grid-column: 3;\n }\n}\n\n:host(#{$prefix}-multi-select[type='inline'][warn])\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(56px);\n}\n\n:host(#{$prefix}-multi-select-item) {\n @extend .#{$prefix}--list-box__menu-item;\n\n display: block;\n\n #{$prefix}-checkbox::part(label) {\n display: inline-block;\n overflow: hidden;\n inline-size: 100%;\n padding-inline-start: rem(28px);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .#{$prefix}--list-box__menu-item__option {\n box-sizing: border-box;\n\n .#{$prefix}--checkbox-wrapper {\n display: flex;\n align-items: center;\n block-size: 100%;\n inline-size: 100%;\n }\n\n > .#{$prefix}--form-item {\n flex-direction: row;\n }\n }\n // make the checkbox element transparent to mouse events so it doesn't interfere\n #{$prefix}-checkbox {\n pointer-events: none;\n }\n}\n\n:host(#{$prefix}-multi-select-item:hover) {\n background-color: $layer-hover;\n}\n\n:host(#{$prefix}-multi-select-item[filtered]) {\n display: none;\n}\n\n:host(#{$prefix}-multi-select-item[size='sm']) {\n block-size: fit-content;\n .#{$prefix}--list-box__menu-item__option {\n block-size: $spacing-07;\n padding-block: rem(7px);\n }\n}\n\n:host(#{$prefix}-multi-select-item[size='lg']) {\n block-size: fit-content;\n .#{$prefix}--list-box__menu-item__option {\n block-size: $spacing-09;\n padding-block: rem(15px);\n }\n}\n\n:host(#{$prefix}-multi-select-item[disabled]) {\n cursor: not-allowed;\n .#{$prefix}--list-box__menu-item__option {\n color: $text-disabled;\n text-decoration: none;\n }\n}\n\n:host(#{$prefix}-multi-select-item[highlighted]) {\n @extend .#{$prefix}--list-box__menu-item--highlighted;\n}\n\n:host(#{$prefix}-multi-select-item[selected]) {\n @extend .#{$prefix}--list-box__menu-item--active;\n\n .#{$prefix}--list-box__menu-item__option {\n color: $text-primary;\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) {\n @extend .#{$prefix}--list-box__wrapper--slug;\n\n ::slotted(#{$prefix}-ai-label),\n ::slotted(#{$prefix}-slug) {\n position: absolute;\n inset-block-start: 50%;\n inset-inline-end: calc($spacing-08 + 9px);\n margin-block-start: convert.to-rem(0.5px);\n }\n\n ::slotted(#{$prefix}-ai-label:not([revert-active])),\n ::slotted(#{$prefix}-slug:not([revert-active])) {\n transform: translateY(-50%);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][warn]),\n:host(#{$prefix}-multi-select[ai-label][invalid]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: convert.to-rem(81px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) ::slotted(#{$prefix}-ai-label)::after {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: convert.to-rem(1px);\n inset-block-start: 0;\n inset-inline-end: convert.to-rem(-9px);\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][has-value]),\n:host(#{$prefix}-multi-select[filterable][invalid][has-value]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(78px);\n }\n\n .#{$prefix}--list-box__selection#clear-button::before {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: rem(1px);\n inset-inline-end: rem(27px);\n }\n}\n\n// pad space to account for text-input, placeholder and selections\n\n:host(#{$prefix}-multi-select[filterable])\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(45px);\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-01;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid]),\n:host(#{$prefix}-multi-select[filterable][warn]) {\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: 0;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-08;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-05;\n }\n }\n}\n:host(#{$prefix}-multi-select[filterable][ai-label][value='']) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-03;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(43px);\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-10;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][invalid][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-08;\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-10;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-11;\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][warn][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(55px);\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: $spacing-09;\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: $spacing-11;\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(75px);\n }\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label])\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: 0;\n}\n\n:host(#{$prefix}-multi-select[filterable][has-value]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-06;\n }\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(45px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn]) {\n ::slotted(#{$prefix}-ai-label)::before {\n position: absolute;\n display: block;\n background-color: $border-subtle-01;\n block-size: $spacing-05;\n content: '';\n inline-size: convert.to-rem(1px);\n inset-block-start: 0;\n inset-inline-end: convert.to-rem(24px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][warn]),\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn][filterable]),\n:host(#{$prefix}-multi-select[ai-label][invalid][filterable]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-07;\n }\n }\n .#{$prefix}--list-box__field .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(81px);\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(70px);\n }\n}\n\n:host(#{$prefix}-multi-select[filterable][ai-label][warn][has-value]),\n:host(#{$prefix}-multi-select[filterable][ai-label][invalid][has-value]) {\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(114px);\n }\n\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(75px);\n }\n }\n\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--text-input {\n padding-inline-end: rem(65px);\n }\n .#{$prefix}--multi-select--selected\n .#{$prefix}--list-box__field\n .#{$prefix}--list-box__invalid-icon {\n inset-inline-end: rem(114px);\n }\n}\n\n:host(#{$prefix}-multi-select[ai-label][invalid]),\n:host(#{$prefix}-multi-select[ai-label][warn]) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: rem(100px);\n }\n }\n .#{$prefix}--multi-select--selected .#{$prefix}--list-box__field {\n padding-inline-end: rem(105px);\n }\n}\n\n// When select all is turned on, the first item in the listbox\n// is always the \"Select all\" option and gets special border\n// treatment\n:host(#{$prefix}-multi-select-item[is-select-all]) {\n .#{$prefix}--list-box__menu-item__option {\n padding: 0.6875rem $spacing-05;\n margin: 0;\n border-block-end: 1px solid $border-subtle-01;\n }\n}\n\n// When select all is turned on, the second item in the list\n// has special treatment to look correct against the \"Select all\"\n// border treatment, this second item (index=1) gets a `flush-top` attribute\n// so that we can remove its top border.\n:host(#{$prefix}-multi-select-item[flush-top])\n .#{$prefix}--list-box__menu-item__option {\n border-block-start: none;\n}\n\n// remove focus outline for when the label is out of focus\n:host(#{$prefix}-multi-select)\n .#{$prefix}--list-box__field.no-focus-style:focus,\n:host(#{$prefix}-multi-select)\n .#{$prefix}--list-box__field.no-focus-style:focus-within {\n outline: none;\n}\n\n:host(#{$prefix}-multi-select[ai-label])\n .#{$prefix}--list-box__wrapper--decorator {\n @include ai-gradient;\n}\n\n:host(#{$prefix}-multi-select[item-clicked]),\n:host(#{$prefix}-multi-select[has-value]) {\n .#{$prefix}--list-box__field,\n .#{$prefix}--multi-select--invalid {\n outline: 1px solid $focus !important;\n outline-offset: -1px !important;\n }\n}\n\n:host(\n #{$prefix}-multi-select[warn]:not([invalid]):not([ai-label]):not(\n [disabled]\n ):not([read-only])\n ) {\n .#{$prefix}--form__helper-text {\n color: $text-primary;\n }\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(\n #{$prefix}-multi-select[warn][invalid]:not([ai-label]):not([disabled]):not(\n [read-only]\n )\n ) {\n .#{$prefix}--list-box {\n .#{$prefix}--list-box__field {\n padding-inline-end: $spacing-10;\n }\n }\n}\n\n:host(#{$prefix}-multi-select[disabled]) {\n .#{$prefix}--list-box__field,\n .#{$prefix}--list-box__selection {\n pointer-events: none;\n }\n .#{$prefix}--list-box__field:focus,\n .#{$prefix}--list-box__selection:focus {\n outline: none !important;\n }\n}\n\n@include emit-layout-tokens-to-shadow-host('#{$prefix}-multi-select');\n"],"mappings":""}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import CDSFloatingMenuTrigger from '../floating-menu/floating-menu-trigger';
8
8
  import { OVERFLOW_MENU_SIZE } from './defs';
9
+ import '../menu/index';
9
10
  import CDSIconButton from '../icon-button/icon-button';
10
11
  export { OVERFLOW_MENU_SIZE };
11
12
  declare const CDSOverflowMenu_base: {
@@ -31,10 +32,27 @@ declare const CDSOverflowMenu_base: {
31
32
  * @slot icon - The icon for the trigger button.
32
33
  */
33
34
  declare class CDSOverflowMenu extends CDSOverflowMenu_base implements CDSFloatingMenuTrigger {
35
+ private _menuController;
34
36
  /**
35
37
  * The menu body.
36
38
  */
37
39
  private _menuBody;
40
+ /**
41
+ * The identifier used by the popup surface.
42
+ */
43
+ private _menuId;
44
+ /**
45
+ * Ensures the deprecated-child warning only fires once.
46
+ */
47
+ private _didWarnDeprecatedChildren;
48
+ /**
49
+ * Ensures the invalid menu composition warning only fires once.
50
+ */
51
+ private _didWarnInvalidComposition;
52
+ /**
53
+ * Monotonic token used to ignore stale async menu sync callbacks.
54
+ */
55
+ private _menuSyncToken;
38
56
  /**
39
57
  * Handles user-initiated toggling of the menu.
40
58
  */
@@ -47,6 +65,14 @@ declare class CDSOverflowMenu extends CDSOverflowMenu_base implements CDSFloatin
47
65
  * Handles `keydown` event on the trigger button.
48
66
  */
49
67
  private _handleKeydownTrigger;
68
+ /**
69
+ * Prevents the trigger click from immediately re-opening the menu after blur.
70
+ */
71
+ private _handleMousedownTrigger;
72
+ /**
73
+ * Handles close requests emitted by the managed menu.
74
+ */
75
+ private _handleManagedMenuClose;
50
76
  /**
51
77
  * `true` if this tooltip is in a data table row
52
78
  */
@@ -55,10 +81,18 @@ declare class CDSOverflowMenu extends CDSOverflowMenu_base implements CDSFloatin
55
81
  * `true` if this overflow menu should be disabled.
56
82
  */
57
83
  disabled: boolean;
84
+ /**
85
+ * Enables the menu-composition OverflowMenu implementation leveraging `cds-custom-menu`.
86
+ */
87
+ enableV12Overflowmenu: boolean;
58
88
  /**
59
89
  * `true` if this overflow menu body should be flipped.
60
90
  */
61
91
  flipped: boolean;
92
+ /**
93
+ * Experimental property. Enables automatic menu placement flipping to avoid clipping.
94
+ */
95
+ autoalign: boolean;
62
96
  /**
63
97
  * `true` if the dropdown should be open.
64
98
  */
@@ -67,6 +101,15 @@ declare class CDSOverflowMenu extends CDSOverflowMenu_base implements CDSFloatin
67
101
  * Index (starting at 1) of overflow menu item to focus on open.
68
102
  */
69
103
  index: number;
104
+ /**
105
+ * A label describing the menu options. Used for the trigger tooltip and the menu's accessible label.
106
+ */
107
+ label: string;
108
+ /**
109
+ * Specify how the menu should align with the trigger button.
110
+ * Valid values: 'bottom-start', 'bottom-end', 'top-start', 'top-end'
111
+ */
112
+ menuAlignment: string;
70
113
  /**
71
114
  * Overflow menu size.
72
115
  */
@@ -84,8 +127,35 @@ declare class CDSOverflowMenu extends CDSOverflowMenu_base implements CDSFloatin
84
127
  */
85
128
  get triggerPosition(): DOMRect;
86
129
  connectedCallback(): void;
130
+ disconnectedCallback(): void;
131
+ protected _renderTooltipContent(): import("lit-html").TemplateResult<1>;
87
132
  updated(changedProperties: any): void;
88
133
  render(): import("lit-html").TemplateResult<1>;
134
+ private _getLabelText;
135
+ private _getTriggerButton;
136
+ private _isTriggerEvent;
137
+ private _isDeprecatedOverflowMenuItemEvent;
138
+ /**
139
+ * Checks whether the menu-composition path is enabled.
140
+ */
141
+ private _isMenuCompositionEnabled;
142
+ /**
143
+ * Checks whether floating styles should be driven by Floating UI.
144
+ */
145
+ private _usesDynamicFloatingStyles;
146
+ private _getMenuChild;
147
+ private _warnDeprecatedChildren;
148
+ private _warnInvalidMenuComposition;
149
+ private _syncMenuChild;
150
+ private _syncMenuChildPosition;
151
+ private _toMenuSize;
152
+ private _focusManagedMenuItem;
153
+ private _resetMenuChildFloatingStyles;
154
+ private _resetMenuFloatingStyles;
155
+ /**
156
+ * Suppresses trigger tooltip interactions while the menu is open.
157
+ */
158
+ private _syncTriggerTooltipState;
89
159
  }
90
160
  export default CDSOverflowMenu;
91
161
  //# sourceMappingURL=overflow-menu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overflow-menu.d.ts","sourceRoot":"","sources":["../../../src/components/overflow-menu/overflow-menu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,sBAAsB,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAK5C,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;;;;;;;;;;uBAHU,CAAC;;;;;;;AAKzC;;;;;GAKG;AACH,cACM,eACJ,SAAQ,oBACR,YAAW,sBAAsB;IAEjC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAoC;IAErD;;OAEG;YACW,0BAA0B;IAaxC;;OAEG;IAIH,OAAO,CAAC,mBAAmB,CAEzB;IAEF;;OAEG;IAIH,OAAO,CAAC,qBAAqB,CAK3B;IAEF;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,UAAS;IAEhB;;OAEG;IAEH,IAAI,UAAS;IAEb;;OAEG;IAEH,KAAK,SAAK;IAEV;;OAEG;IAEH,IAAI,qBAA6B;IAEjC;;OAEG;IAEH,aAAa,UAAS;IAEtB;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IACH,IAAI,eAAe,YAElB;IAED,iBAAiB;IAYjB,OAAO,CAAC,iBAAiB,KAAA;IA0DzB,MAAM;CAGP;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"overflow-menu.d.ts","sourceRoot":"","sources":["../../../src/components/overflow-menu/overflow-menu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,sBAAsB,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,eAAe,CAAC;AAQvB,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;;;;;;;;;;uBAP4B,CAAC;;;;;;;AAqC3D;;;;;GAKG;AACH,cACM,eACJ,SAAQ,oBACR,YAAW,sBAAsB;IAEjC,OAAO,CAAC,eAAe,CAAkC;IAEzD;;OAEG;IACH,OAAO,CAAC,SAAS,CAAoC;IAErD;;OAEG;IACH,OAAO,CAAC,OAAO,CAED;IAEd;;OAEG;IACH,OAAO,CAAC,0BAA0B,CAAS;IAE3C;;OAEG;IACH,OAAO,CAAC,0BAA0B,CAAS;IAE3C;;OAEG;IACH,OAAO,CAAC,cAAc,CAAK;IAE3B;;OAEG;YACW,0BAA0B;IAuBxC;;OAEG;IACH,OAAO,CAAC,mBAAmB,CAYzB;IAEF;;OAEG;IACH,OAAO,CAAC,qBAAqB,CAS3B;IAEF;;OAEG;IACH,OAAO,CAAC,uBAAuB,CAI7B;IAEF;;OAEG;IACH,OAAO,CAAC,uBAAuB,CAmB7B;IAEF;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAMH,qBAAqB,UAAS;IAE9B;;OAEG;IAEH,OAAO,UAAS;IAEhB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,IAAI,UAAS;IAEb;;OAEG;IAEH,KAAK,SAAK;IAEV;;OAEG;IAEH,KAAK,SAAM;IAEX;;;OAGG;IAEH,aAAa,EAAE,MAAM,CAAkB;IAEvC;;OAEG;IAEH,IAAI,qBAA6B;IAEjC;;OAEG;IAEH,aAAa,UAAS;IAEtB;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IACH,IAAI,eAAe,YAElB;IAED,iBAAiB;IAoBjB,oBAAoB;IAWpB,SAAS,CAAC,qBAAqB;IAc/B,OAAO,CAAC,iBAAiB,KAAA;IAkGzB,MAAM;IAIN,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kCAAkC;IAU1C;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAOjC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,uBAAuB;IAkB/B,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,cAAc;IAkFtB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,WAAW;YAeL,qBAAqB;IAsBnC,OAAO,CAAC,6BAA6B;IAerC,OAAO,CAAC,wBAAwB;IAgBhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAmBjC;AAED,eAAe,eAAe,CAAC"}
@@ -10,9 +10,13 @@ import { find } from "../../globals/internal/collection-helpers.js";
10
10
  import { carbonElement } from "../../globals/decorators/carbon-element.js";
11
11
  import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
12
12
  import FocusMixin from "../../globals/mixins/focus.js";
13
- import HostListener from "../../globals/decorators/host-listener.js";
14
13
  import HostListenerMixin from "../../globals/mixins/host-listener.js";
14
+ import FloatingController from "../../globals/controllers/floating-controller.js";
15
15
  import { OVERFLOW_MENU_SIZE } from "./defs.js";
16
+ import "../menu/defs.js";
17
+ import menu_default from "../menu/menu.js";
18
+ import "../menu/index.js";
19
+ import { isFeatureFlagEnabled } from "../feature-flags/index.js";
16
20
  import icon_button_default from "../icon-button/icon-button.scss.js";
17
21
  import overflow_menu_default$1 from "./overflow-menu.scss.js";
18
22
  import icon_button_default$1 from "../icon-button/icon-button.js";
@@ -25,6 +29,23 @@ import { property } from "lit/decorators.js";
25
29
  * This source code is licensed under the Apache-2.0 license found in the
26
30
  * LICENSE file in the root directory of this source tree.
27
31
  */
32
+ const menuItemTagPrefix = `cds-custom-menu-item`.toUpperCase();
33
+ const deprecatedOverflowMenuTagNames = new Set([`cds-custom-overflow-menu-body`.toUpperCase(), `cds-custom-overflow-menu-item`.toUpperCase()]);
34
+ const bottomFirstFallbackPlacements = [
35
+ "bottom-start",
36
+ "bottom-end",
37
+ "top-start",
38
+ "top-end"
39
+ ];
40
+ const topFirstFallbackPlacements = [
41
+ "top-start",
42
+ "top-end",
43
+ "bottom-start",
44
+ "bottom-end"
45
+ ];
46
+ const warnInDev = (message) => {
47
+ globalThis.console?.warn(message);
48
+ };
28
49
  /**
29
50
  * Overflow menu.
30
51
  *
@@ -34,21 +55,46 @@ import { property } from "lit/decorators.js";
34
55
  let CDSOverflowMenu = class CDSOverflowMenu extends HostListenerMixin(FocusMixin(icon_button_default$1)) {
35
56
  constructor(..._args) {
36
57
  super(..._args);
58
+ this._menuController = new FloatingController(this);
37
59
  this._menuBody = null;
38
- this._handleClickTrigger = async () => {
39
- this._handleUserInitiatedToggle();
60
+ this._menuId = `cds-custom-overflow-menu-${Math.random().toString(16).slice(2)}`;
61
+ this._didWarnDeprecatedChildren = false;
62
+ this._didWarnInvalidComposition = false;
63
+ this._menuSyncToken = 0;
64
+ this._handleClickTrigger = async (event) => {
65
+ if (this._isTriggerEvent(event)) {
66
+ this._handleUserInitiatedToggle();
67
+ return;
68
+ }
69
+ if (!this._isMenuCompositionEnabled() && this._isDeprecatedOverflowMenuItemEvent(event)) this.open = false;
40
70
  };
41
71
  this._handleKeydownTrigger = async (event) => {
72
+ if (!this._isTriggerEvent(event)) return;
42
73
  if (event.key === " " || event.key === "Enter") {
43
74
  this._handleUserInitiatedToggle();
44
75
  event.preventDefault();
45
76
  }
46
77
  };
78
+ this._handleMousedownTrigger = (event) => {
79
+ if (this._isMenuCompositionEnabled() && this._isTriggerEvent(event)) event.preventDefault();
80
+ };
81
+ this._handleManagedMenuClose = (event) => {
82
+ const menu = this._getMenuChild();
83
+ if (!this._isMenuCompositionEnabled() || !menu || event.composedPath()[0] !== menu) return;
84
+ this.open = false;
85
+ if (event.detail?.triggerEventType !== "focusout") requestAnimationFrame(() => {
86
+ this._getTriggerButton()?.focus();
87
+ });
88
+ };
47
89
  this.dataTable = false;
48
90
  this.disabled = false;
91
+ this.enableV12Overflowmenu = false;
49
92
  this.flipped = false;
93
+ this.autoalign = false;
50
94
  this.open = false;
51
95
  this.index = 1;
96
+ this.label = "";
97
+ this.menuAlignment = "bottom-start";
52
98
  this.size = "md";
53
99
  this.toolbarAction = false;
54
100
  this.breadcrumb = false;
@@ -57,10 +103,15 @@ let CDSOverflowMenu = class CDSOverflowMenu extends HostListenerMixin(FocusMixin
57
103
  * Handles user-initiated toggling of the menu.
58
104
  */
59
105
  async _handleUserInitiatedToggle() {
106
+ if (this.disabled) return;
60
107
  this.open = !this.open;
61
108
  const { index, open, updateComplete } = this;
62
109
  if (open) {
63
110
  await updateComplete;
111
+ if (this._isMenuCompositionEnabled()) {
112
+ await this._focusManagedMenuItem(index);
113
+ return;
114
+ }
64
115
  const { _menuBody: menuBody } = this;
65
116
  (menuBody?.querySelector(`cds-custom-overflow-menu-item:nth-of-type(${index})`))?.focus();
66
117
  }
@@ -76,24 +127,52 @@ let CDSOverflowMenu = class CDSOverflowMenu extends HostListenerMixin(FocusMixin
76
127
  if (!this.shadowRoot) this.attachShadow({ mode: "open" });
77
128
  super.connectedCallback();
78
129
  adoptStyles(this.renderRoot, [icon_button_default, overflow_menu_default$1]);
130
+ this.addEventListener(menu_default.eventOnClose, this._handleManagedMenuClose);
131
+ this.addEventListener("click", this._handleClickTrigger);
132
+ this.addEventListener("keydown", this._handleKeydownTrigger);
133
+ this.addEventListener("mousedown", this._handleMousedownTrigger);
134
+ }
135
+ disconnectedCallback() {
136
+ this.removeEventListener(menu_default.eventOnClose, this._handleManagedMenuClose);
137
+ this.removeEventListener("click", this._handleClickTrigger);
138
+ this.removeEventListener("keydown", this._handleKeydownTrigger);
139
+ this.removeEventListener("mousedown", this._handleMousedownTrigger);
140
+ super.disconnectedCallback();
141
+ }
142
+ _renderTooltipContent() {
143
+ const tooltipLabel = this._getLabelText();
144
+ if (this.label || !this.querySelector("[slot=tooltip-content]")) return html`
145
+ <cds-custom-tooltip-content ?hidden=${this.disabled || this.open}>
146
+ ${tooltipLabel}
147
+ </cds-custom-tooltip-content>
148
+ `;
149
+ return super._renderTooltipContent();
79
150
  }
80
151
  updated(changedProperties) {
152
+ super.updated(changedProperties);
153
+ const menuCompositionEnabled = this._isMenuCompositionEnabled();
81
154
  const button = this.shadowRoot?.querySelector(`cds-custom-tooltip`)?.querySelector("button");
82
155
  button?.classList.add(`cds-custom--btn--icon-only`, `cds-custom--overflow-menu`);
83
156
  if (changedProperties.has("open")) {
84
- const { open } = this;
85
- if (open && !this._menuBody) this._menuBody = find(this.childNodes, (elem) => elem.constructor.FLOATING_MENU);
86
- const { _menuBody: menuBody, size } = this;
87
- if (menuBody) {
88
- menuBody.setAttribute("breadcrumb", String(this.breadcrumb));
89
- menuBody.open = open;
90
- menuBody.size = size;
91
- const tooltipContent = this.querySelector("[slot=tooltip-content]")?.textContent;
92
- button?.setAttribute("aria-expanded", String(open));
93
- button?.setAttribute("aria-label", String(tooltipContent));
157
+ if (!menuCompositionEnabled) {
158
+ this._menuController.hostDisconnected();
159
+ this._resetMenuChildFloatingStyles();
160
+ const { open } = this;
161
+ if (open && !this._menuBody) this._menuBody = find(this.childNodes, (elem) => elem.constructor.FLOATING_MENU);
162
+ const { _menuBody: menuBody, size } = this;
163
+ if (menuBody) {
164
+ menuBody.id ||= this._menuId;
165
+ menuBody.setAttribute("breadcrumb", String(this.breadcrumb));
166
+ menuBody.open = open;
167
+ menuBody.size = size;
168
+ }
94
169
  }
95
170
  }
96
- if (changedProperties.has("dataTable")) (this.shadowRoot?.querySelector(`cds-custom-tooltip`))?.setAttribute("data-table", "");
171
+ if (changedProperties.has("enableV12Overflowmenu") && !menuCompositionEnabled) {
172
+ this._menuController.hostDisconnected();
173
+ this._resetMenuChildFloatingStyles({ closeMenu: true });
174
+ }
175
+ if (changedProperties.has("dataTable")) (this.shadowRoot?.querySelector(`cds-custom-tooltip`))?.toggleAttribute("data-table", this.dataTable);
97
176
  if (changedProperties.has("size")) {
98
177
  button?.classList.forEach((item) => {
99
178
  if (item.startsWith(`cds-custom--overflow-menu--`)) button?.classList.remove(item);
@@ -102,14 +181,160 @@ let CDSOverflowMenu = class CDSOverflowMenu extends HostListenerMixin(FocusMixin
102
181
  (this.shadowRoot?.querySelector(`cds-custom-tooltip`))?.setAttribute("size", this.size);
103
182
  }
104
183
  if (changedProperties.has("toolbarAction") && this.toolbarAction) this.shadowRoot?.querySelector(`cds-custom-tooltip`)?.setAttribute("toolbar-action", "");
105
- super.updated(changedProperties);
184
+ const labelText = this._getLabelText();
185
+ const popupId = menuCompositionEnabled ? this._getMenuChild()?.id ?? this._menuId : this._menuBody?.id;
186
+ button?.setAttribute("aria-haspopup", "menu");
187
+ button?.setAttribute("aria-expanded", String(this.open));
188
+ button?.setAttribute("aria-label", labelText);
189
+ if (this.open && popupId) button?.setAttribute("aria-controls", popupId);
190
+ else button?.removeAttribute("aria-controls");
191
+ if (menuCompositionEnabled && (changedProperties.has("open") || changedProperties.has("label") || changedProperties.has("autoalign") || changedProperties.has("menuAlignment") || changedProperties.has("size") || changedProperties.has("enableV12Overflowmenu"))) this._syncMenuChild();
192
+ if (changedProperties.has("open") || changedProperties.has("disabled")) this._syncTriggerTooltipState();
106
193
  }
107
194
  render() {
108
195
  return html`${super.render()} `;
109
196
  }
197
+ _getLabelText() {
198
+ if (this.label) return this.label;
199
+ return this.querySelector("[slot=tooltip-content]")?.textContent?.trim() || "Options";
200
+ }
201
+ _getTriggerButton() {
202
+ return this.shadowRoot?.querySelector(`cds-custom-tooltip`)?.querySelector("button");
203
+ }
204
+ _isTriggerEvent(event) {
205
+ const triggerButton = this._getTriggerButton();
206
+ return !!triggerButton && event.composedPath().includes(triggerButton);
207
+ }
208
+ _isDeprecatedOverflowMenuItemEvent(event) {
209
+ return event.composedPath().some((entry) => entry instanceof HTMLElement && deprecatedOverflowMenuTagNames.has(entry.tagName));
210
+ }
211
+ /**
212
+ * Checks whether the menu-composition path is enabled.
213
+ */
214
+ _isMenuCompositionEnabled() {
215
+ return this.enableV12Overflowmenu || isFeatureFlagEnabled("enable-v12-overflowmenu", this);
216
+ }
217
+ /**
218
+ * Checks whether floating styles should be driven by Floating UI.
219
+ */
220
+ _usesDynamicFloatingStyles() {
221
+ return this.autoalign || isFeatureFlagEnabled("enable-v12-dynamic-floating-styles", this);
222
+ }
223
+ _getMenuChild() {
224
+ return Array.from(this.children).find((child) => {
225
+ return child.tagName === `cds-custom-menu`.toUpperCase();
226
+ }) ?? null;
227
+ }
228
+ _warnDeprecatedChildren() {
229
+ if (this._didWarnDeprecatedChildren) return;
230
+ if (Array.from(this.children).some((child) => {
231
+ return deprecatedOverflowMenuTagNames.has(child.tagName);
232
+ })) {
233
+ warnInDev("`cds-custom-overflow-menu` with `enable-v12-overflowmenu` expects a direct `cds-custom-menu` child instead of the deprecated `cds-custom-overflow-menu-body` structure.");
234
+ this._didWarnDeprecatedChildren = true;
235
+ }
236
+ }
237
+ _warnInvalidMenuComposition() {
238
+ if (this._didWarnInvalidComposition) return;
239
+ const hasDirectMenuItems = Array.from(this.children).some((child) => child.tagName.startsWith(menuItemTagPrefix));
240
+ if (!!!this._getMenuChild() || hasDirectMenuItems) {
241
+ warnInDev("`cds-custom-overflow-menu` with `enable-v12-overflowmenu` expects a direct `cds-custom-menu` child. Place `cds-custom-menu-item*` descendants inside that `cds-custom-menu`.");
242
+ this._didWarnInvalidComposition = true;
243
+ }
244
+ }
245
+ _syncMenuChild() {
246
+ const menuSyncToken = ++this._menuSyncToken;
247
+ this._warnDeprecatedChildren();
248
+ this._warnInvalidMenuComposition();
249
+ const menu = this._getMenuChild();
250
+ if (!menu) return;
251
+ const menuAlignment = this.menuAlignment;
252
+ menu.id ||= this._menuId;
253
+ menu.label = this._getLabelText();
254
+ menu.menuAlignment = menuAlignment;
255
+ this._syncMenuChildPosition(menu);
256
+ menu.open = this.open;
257
+ menu.size = this._toMenuSize(this.size);
258
+ const shouldUseFloatingStyles = this._usesDynamicFloatingStyles();
259
+ if (!this.open || !shouldUseFloatingStyles) {
260
+ this._menuController.hostDisconnected();
261
+ this._resetMenuFloatingStyles(menu);
262
+ return;
263
+ }
264
+ this.updateComplete.then(async () => {
265
+ if (menuSyncToken !== this._menuSyncToken || !this.open || !this._isMenuCompositionEnabled() || this._getMenuChild() !== menu) return;
266
+ await menu.updateComplete;
267
+ if (menuSyncToken !== this._menuSyncToken || !this.open || !this._isMenuCompositionEnabled() || this._getMenuChild() !== menu) return;
268
+ const trigger = this._getTriggerButton();
269
+ if (!trigger) return;
270
+ const styleElement = menu.shadowRoot?.querySelector(`.cds-custom--menu`);
271
+ const fallbackPlacements = menuAlignment.includes("bottom") ? [...bottomFirstFallbackPlacements] : [...topFirstFallbackPlacements];
272
+ const flipArguments = this.autoalign ? { fallbackPlacements } : {
273
+ mainAxis: false,
274
+ crossAxis: false
275
+ };
276
+ this._menuController.setPlacement({
277
+ trigger,
278
+ target: menu,
279
+ alignment: menuAlignment,
280
+ styleElement,
281
+ flipArguments,
282
+ mainAxisOffset: 0,
283
+ open: this.open
284
+ });
285
+ });
286
+ }
287
+ _syncMenuChildPosition(menu) {
288
+ const trigger = this._getTriggerButton();
289
+ if (!trigger) return;
290
+ const { left, right, top, bottom } = trigger.getBoundingClientRect();
291
+ menu.x = [left, right];
292
+ menu.y = [top, bottom];
293
+ }
294
+ _toMenuSize(size) {
295
+ switch (size) {
296
+ case "xs": return "xs";
297
+ case "sm": return "sm";
298
+ case "md": return "md";
299
+ case "lg": return "lg";
300
+ default: return "md";
301
+ }
302
+ }
303
+ async _focusManagedMenuItem(index) {
304
+ const menu = this._getMenuChild();
305
+ if (!menu) return;
306
+ await menu.updateComplete;
307
+ if (!this.open || this._getMenuChild() !== menu) return;
308
+ const enabledItems = menu.activeitems.map(({ item }) => item).filter((item) => item instanceof HTMLElement && !item.hasAttribute("disabled"));
309
+ (enabledItems[index - 1] ?? enabledItems[0])?.focus();
310
+ }
311
+ _resetMenuChildFloatingStyles({ closeMenu = false } = {}) {
312
+ const menu = this._getMenuChild();
313
+ if (!menu) return;
314
+ this._resetMenuFloatingStyles(menu);
315
+ if (closeMenu) menu.open = false;
316
+ }
317
+ _resetMenuFloatingStyles(menu) {
318
+ const menuSurface = menu.shadowRoot?.querySelector(`.cds-custom--menu`);
319
+ if (!menuSurface) return;
320
+ menuSurface.style.removeProperty("left");
321
+ menuSurface.style.removeProperty("top");
322
+ menuSurface.style.removeProperty("position");
323
+ menuSurface.style.removeProperty("visibility");
324
+ menuSurface.removeAttribute("align");
325
+ }
326
+ /**
327
+ * Suppresses trigger tooltip interactions while the menu is open.
328
+ */
329
+ _syncTriggerTooltipState() {
330
+ const tooltip = this.shadowRoot?.querySelector(`cds-custom-tooltip`);
331
+ const tooltipContent = this.shadowRoot?.querySelector(`cds-custom-tooltip-content`);
332
+ if (!tooltip) return;
333
+ tooltip.keyboardOnly = this.open;
334
+ tooltipContent?.toggleAttribute("hidden", this.disabled || this.open);
335
+ if (this.open) tooltip.open = false;
336
+ }
110
337
  };
111
- __decorate([HostListener("click")], CDSOverflowMenu.prototype, "_handleClickTrigger", void 0);
112
- __decorate([HostListener("keydown")], CDSOverflowMenu.prototype, "_handleKeydownTrigger", void 0);
113
338
  __decorate([property({
114
339
  type: Boolean,
115
340
  reflect: true,
@@ -119,15 +344,29 @@ __decorate([property({
119
344
  type: Boolean,
120
345
  reflect: true
121
346
  })], CDSOverflowMenu.prototype, "disabled", void 0);
347
+ __decorate([property({
348
+ type: Boolean,
349
+ reflect: true,
350
+ attribute: "enable-v12-overflowmenu"
351
+ })], CDSOverflowMenu.prototype, "enableV12Overflowmenu", void 0);
122
352
  __decorate([property({
123
353
  type: Boolean,
124
354
  reflect: true
125
355
  })], CDSOverflowMenu.prototype, "flipped", void 0);
356
+ __decorate([property({
357
+ type: Boolean,
358
+ reflect: true
359
+ })], CDSOverflowMenu.prototype, "autoalign", void 0);
126
360
  __decorate([property({
127
361
  type: Boolean,
128
362
  reflect: true
129
363
  })], CDSOverflowMenu.prototype, "open", void 0);
130
364
  __decorate([property()], CDSOverflowMenu.prototype, "index", void 0);
365
+ __decorate([property({ type: String })], CDSOverflowMenu.prototype, "label", void 0);
366
+ __decorate([property({
367
+ type: String,
368
+ attribute: "menu-alignment"
369
+ })], CDSOverflowMenu.prototype, "menuAlignment", void 0);
131
370
  __decorate([property({ reflect: true })], CDSOverflowMenu.prototype, "size", void 0);
132
371
  __decorate([property({
133
372
  type: Boolean,
@@ -1 +1 @@
1
- {"version":3,"file":"overflow-menu.js","names":["CDSIconButton","iconButtonStyles","styles","customElement"],"sources":["../../../src/components/overflow-menu/overflow-menu.ts"],"sourcesContent":["/**\n * Copyright IBM Corp. 2019, 2026\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { adoptStyles, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { prefix } from '../../globals/settings';\nimport HostListener from '../../globals/decorators/host-listener';\nimport FocusMixin from '../../globals/mixins/focus';\nimport HostListenerMixin from '../../globals/mixins/host-listener';\nimport { find } from '../../globals/internal/collection-helpers';\nimport CDSFloatingMenuTrigger from '../floating-menu/floating-menu-trigger';\nimport { OVERFLOW_MENU_SIZE } from './defs';\nimport CDSOverflowMenuBody from './overflow-menu-body';\n\nimport iconButtonStyles from '../icon-button/icon-button.scss?lit';\nimport styles from './overflow-menu.scss?lit';\nimport CDSIconButton from '../icon-button/icon-button';\nimport { carbonElement as customElement } from '../../globals/decorators/carbon-element';\n\nexport { OVERFLOW_MENU_SIZE };\n\n/**\n * Overflow menu.\n *\n * @element cds-custom-overflow-menu\n * @slot icon - The icon for the trigger button.\n */\n@customElement(`${prefix}-overflow-menu`)\nclass CDSOverflowMenu\n extends HostListenerMixin(FocusMixin(CDSIconButton))\n implements CDSFloatingMenuTrigger\n{\n /**\n * The menu body.\n */\n private _menuBody: CDSOverflowMenuBody | null = null;\n\n /**\n * Handles user-initiated toggling of the menu.\n */\n private async _handleUserInitiatedToggle() {\n this.open = !this.open;\n const { index, open, updateComplete } = this;\n if (open) {\n await updateComplete;\n const { _menuBody: menuBody } = this;\n const menuItem = menuBody?.querySelector(\n `${prefix}-overflow-menu-item:nth-of-type(${index})`\n ) as HTMLElement;\n menuItem?.focus();\n }\n }\n\n /**\n * Handles `click` event on the trigger button.\n */\n @HostListener('click')\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- https://github.com/carbon-design-system/carbon/issues/20452\n // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to\n private _handleClickTrigger = async () => {\n this._handleUserInitiatedToggle();\n };\n\n /**\n * Handles `keydown` event on the trigger button.\n */\n @HostListener('keydown')\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- https://github.com/carbon-design-system/carbon/issues/20452\n // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to\n private _handleKeydownTrigger = async (event) => {\n if (event.key === ' ' || event.key === 'Enter') {\n this._handleUserInitiatedToggle();\n event.preventDefault();\n }\n };\n\n /**\n * `true` if this tooltip is in a data table row\n */\n @property({ type: Boolean, reflect: true, attribute: 'data-table' })\n dataTable = false;\n\n /**\n * `true` if this overflow menu should be disabled.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * `true` if this overflow menu body should be flipped.\n */\n @property({ type: Boolean, reflect: true })\n flipped = false;\n\n /**\n * `true` if the dropdown should be open.\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Index (starting at 1) of overflow menu item to focus on open.\n */\n @property()\n index = 1;\n\n /**\n * Overflow menu size.\n */\n @property({ reflect: true })\n size = OVERFLOW_MENU_SIZE.MEDIUM;\n\n /**\n * `true` if this menu is a toolbar action\n */\n @property({ type: Boolean, attribute: 'toolbar-action', reflect: true })\n toolbarAction = false;\n\n /**\n * `true` if this overflow menu use inside breadcrumb.\n */\n @property({ type: Boolean, reflect: true })\n breadcrumb = false;\n\n /**\n * @returns The position of the trigger button in the viewport.\n */\n get triggerPosition() {\n return this.getBoundingClientRect();\n }\n\n connectedCallback() {\n if (!this.hasAttribute('aria-haspopup')) {\n this.setAttribute('aria-haspopup', 'true');\n }\n if (!this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n super.connectedCallback();\n\n adoptStyles(this.renderRoot as ShadowRoot, [iconButtonStyles, styles]);\n }\n\n updated(changedProperties) {\n const button = this.shadowRoot\n ?.querySelector(`${prefix}-tooltip`)\n ?.querySelector('button');\n button?.classList.add(\n `${prefix}--btn--icon-only`,\n `${prefix}--overflow-menu`\n );\n\n if (changedProperties.has('open')) {\n const { open } = this;\n if (open && !this._menuBody) {\n this._menuBody = find(\n this.childNodes,\n (elem) =>\n (elem.constructor as typeof CDSOverflowMenuBody).FLOATING_MENU\n );\n }\n const { _menuBody: menuBody, size } = this;\n if (menuBody) {\n menuBody.setAttribute('breadcrumb', String(this.breadcrumb));\n menuBody.open = open;\n menuBody.size = size;\n\n const tooltipContent = this.querySelector(\n '[slot=tooltip-content]'\n )?.textContent;\n button?.setAttribute('aria-expanded', String(open));\n button?.setAttribute('aria-label', String(tooltipContent));\n }\n }\n\n if (changedProperties.has('dataTable')) {\n const tooltip = this.shadowRoot?.querySelector(`${prefix}-tooltip`);\n tooltip?.setAttribute('data-table', '');\n }\n\n if (changedProperties.has('size')) {\n button?.classList.forEach((item) => {\n if (item.startsWith(`${prefix}--overflow-menu--`)) {\n button?.classList.remove(item);\n }\n });\n button?.classList.add(`${prefix}--overflow-menu--${this.size}`);\n\n const tooltip = this.shadowRoot?.querySelector(`${prefix}-tooltip`);\n tooltip?.setAttribute('size', this.size);\n }\n\n if (changedProperties.has('toolbarAction') && this.toolbarAction) {\n this.shadowRoot\n ?.querySelector(`${prefix}-tooltip`)\n ?.setAttribute('toolbar-action', '');\n }\n\n super.updated(changedProperties);\n }\n\n render() {\n return html`${super.render()} `;\n }\n}\n\nexport default CDSOverflowMenu;\n"],"mappings":"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"}
1
+ {"version":3,"file":"overflow-menu.js","names":["CDSIconButton","FloatingUIController","iconButtonStyles","styles","CDSMenu","customElement"],"sources":["../../../src/components/overflow-menu/overflow-menu.ts"],"sourcesContent":["/**\n * Copyright IBM Corp. 2019, 2026\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { adoptStyles, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { prefix } from '../../globals/settings';\nimport FocusMixin from '../../globals/mixins/focus';\nimport HostListenerMixin from '../../globals/mixins/host-listener';\nimport { find } from '../../globals/internal/collection-helpers';\nimport CDSFloatingMenuTrigger from '../floating-menu/floating-menu-trigger';\nimport { OVERFLOW_MENU_SIZE } from './defs';\nimport CDSOverflowMenuBody from './overflow-menu-body';\nimport '../menu/index';\nimport CDSMenu from '../menu/menu';\nimport { MENU_SIZE } from '../menu/defs';\nimport { isFeatureFlagEnabled } from '../feature-flags/index';\nimport FloatingUIController from '../../globals/controllers/floating-controller';\n\nimport iconButtonStyles from '../icon-button/icon-button.scss?lit';\nimport styles from './overflow-menu.scss?lit';\nimport CDSIconButton from '../icon-button/icon-button';\nimport { carbonElement as customElement } from '../../globals/decorators/carbon-element';\n\nexport { OVERFLOW_MENU_SIZE };\n\nconst menuItemTagPrefix = `${prefix}-menu-item`.toUpperCase();\n\n// Migration support for existing child structure.\nconst deprecatedOverflowMenuTagNames = new Set([\n `${prefix}-overflow-menu-body`.toUpperCase(),\n `${prefix}-overflow-menu-item`.toUpperCase(),\n]);\n\nconst bottomFirstFallbackPlacements = [\n 'bottom-start',\n 'bottom-end',\n 'top-start',\n 'top-end',\n] as const;\n\nconst topFirstFallbackPlacements = [\n 'top-start',\n 'top-end',\n 'bottom-start',\n 'bottom-end',\n] as const;\n\nconst warnInDev = (message: string) => {\n if (process.env.NODE_ENV === 'development') {\n globalThis.console?.warn(message);\n }\n};\n\n/**\n * Overflow menu.\n *\n * @element cds-custom-overflow-menu\n * @slot icon - The icon for the trigger button.\n */\n@customElement(`${prefix}-overflow-menu`)\nclass CDSOverflowMenu\n extends HostListenerMixin(FocusMixin(CDSIconButton))\n implements CDSFloatingMenuTrigger\n{\n private _menuController = new FloatingUIController(this);\n\n /**\n * The menu body.\n */\n private _menuBody: CDSOverflowMenuBody | null = null;\n\n /**\n * The identifier used by the popup surface.\n */\n private _menuId = `${prefix}-overflow-menu-${Math.random()\n .toString(16)\n .slice(2)}`;\n\n /**\n * Ensures the deprecated-child warning only fires once.\n */\n private _didWarnDeprecatedChildren = false;\n\n /**\n * Ensures the invalid menu composition warning only fires once.\n */\n private _didWarnInvalidComposition = false;\n\n /**\n * Monotonic token used to ignore stale async menu sync callbacks.\n */\n private _menuSyncToken = 0;\n\n /**\n * Handles user-initiated toggling of the menu.\n */\n private async _handleUserInitiatedToggle() {\n if (this.disabled) {\n return;\n }\n\n this.open = !this.open;\n const { index, open, updateComplete } = this;\n if (open) {\n await updateComplete;\n\n if (this._isMenuCompositionEnabled()) {\n await this._focusManagedMenuItem(index);\n return;\n }\n\n const { _menuBody: menuBody } = this;\n const menuItem = menuBody?.querySelector(\n `${prefix}-overflow-menu-item:nth-of-type(${index})`\n ) as HTMLElement;\n menuItem?.focus();\n }\n }\n\n /**\n * Handles `click` event on the trigger button.\n */\n private _handleClickTrigger = async (event: MouseEvent) => {\n if (this._isTriggerEvent(event)) {\n this._handleUserInitiatedToggle();\n return;\n }\n\n if (\n !this._isMenuCompositionEnabled() &&\n this._isDeprecatedOverflowMenuItemEvent(event)\n ) {\n this.open = false;\n }\n };\n\n /**\n * Handles `keydown` event on the trigger button.\n */\n private _handleKeydownTrigger = async (event: KeyboardEvent) => {\n if (!this._isTriggerEvent(event)) {\n return;\n }\n\n if (event.key === ' ' || event.key === 'Enter') {\n this._handleUserInitiatedToggle();\n event.preventDefault();\n }\n };\n\n /**\n * Prevents the trigger click from immediately re-opening the menu after blur.\n */\n private _handleMousedownTrigger = (event: MouseEvent) => {\n if (this._isMenuCompositionEnabled() && this._isTriggerEvent(event)) {\n event.preventDefault();\n }\n };\n\n /**\n * Handles close requests emitted by the managed menu.\n */\n private _handleManagedMenuClose = (\n event: CustomEvent<{ triggerEventType?: string }>\n ) => {\n const menu = this._getMenuChild();\n if (\n !this._isMenuCompositionEnabled() ||\n !menu ||\n event.composedPath()[0] !== menu\n ) {\n return;\n }\n\n this.open = false;\n\n if (event.detail?.triggerEventType !== 'focusout') {\n requestAnimationFrame(() => {\n this._getTriggerButton()?.focus();\n });\n }\n };\n\n /**\n * `true` if this tooltip is in a data table row\n */\n @property({ type: Boolean, reflect: true, attribute: 'data-table' })\n dataTable = false;\n\n /**\n * `true` if this overflow menu should be disabled.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Enables the menu-composition OverflowMenu implementation leveraging `cds-custom-menu`.\n */\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'enable-v12-overflowmenu',\n })\n enableV12Overflowmenu = false;\n\n /**\n * `true` if this overflow menu body should be flipped.\n */\n @property({ type: Boolean, reflect: true })\n flipped = false;\n\n /**\n * Experimental property. Enables automatic menu placement flipping to avoid clipping.\n */\n @property({ type: Boolean, reflect: true })\n autoalign = false;\n\n /**\n * `true` if the dropdown should be open.\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Index (starting at 1) of overflow menu item to focus on open.\n */\n @property()\n index = 1;\n\n /**\n * A label describing the menu options. Used for the trigger tooltip and the menu's accessible label.\n */\n @property({ type: String })\n label = '';\n\n /**\n * Specify how the menu should align with the trigger button.\n * Valid values: 'bottom-start', 'bottom-end', 'top-start', 'top-end'\n */\n @property({ type: String, attribute: 'menu-alignment' })\n menuAlignment: string = 'bottom-start';\n\n /**\n * Overflow menu size.\n */\n @property({ reflect: true })\n size = OVERFLOW_MENU_SIZE.MEDIUM;\n\n /**\n * `true` if this menu is a toolbar action\n */\n @property({ type: Boolean, attribute: 'toolbar-action', reflect: true })\n toolbarAction = false;\n\n /**\n * `true` if this overflow menu use inside breadcrumb.\n */\n @property({ type: Boolean, reflect: true })\n breadcrumb = false;\n\n /**\n * @returns The position of the trigger button in the viewport.\n */\n get triggerPosition() {\n return this.getBoundingClientRect();\n }\n\n connectedCallback() {\n if (!this.hasAttribute('aria-haspopup')) {\n this.setAttribute('aria-haspopup', 'true');\n }\n if (!this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n super.connectedCallback();\n\n adoptStyles(this.renderRoot as ShadowRoot, [iconButtonStyles, styles]);\n\n this.addEventListener(\n CDSMenu.eventOnClose,\n this._handleManagedMenuClose as EventListener\n );\n this.addEventListener('click', this._handleClickTrigger);\n this.addEventListener('keydown', this._handleKeydownTrigger);\n this.addEventListener('mousedown', this._handleMousedownTrigger);\n }\n\n disconnectedCallback() {\n this.removeEventListener(\n CDSMenu.eventOnClose,\n this._handleManagedMenuClose as EventListener\n );\n this.removeEventListener('click', this._handleClickTrigger);\n this.removeEventListener('keydown', this._handleKeydownTrigger);\n this.removeEventListener('mousedown', this._handleMousedownTrigger);\n super.disconnectedCallback();\n }\n\n protected _renderTooltipContent() {\n const tooltipLabel = this._getLabelText();\n\n if (this.label || !this.querySelector('[slot=tooltip-content]')) {\n return html`\n <cds-custom-tooltip-content ?hidden=${this.disabled || this.open}>\n ${tooltipLabel}\n </cds-custom-tooltip-content>\n `;\n }\n\n return super._renderTooltipContent();\n }\n\n updated(changedProperties) {\n super.updated(changedProperties);\n const menuCompositionEnabled = this._isMenuCompositionEnabled();\n\n const button = this.shadowRoot\n ?.querySelector(`${prefix}-tooltip`)\n ?.querySelector('button');\n button?.classList.add(\n `${prefix}--btn--icon-only`,\n `${prefix}--overflow-menu`\n );\n\n if (changedProperties.has('open')) {\n if (!menuCompositionEnabled) {\n this._menuController.hostDisconnected();\n this._resetMenuChildFloatingStyles();\n const { open } = this;\n if (open && !this._menuBody) {\n this._menuBody = find(\n this.childNodes,\n (elem) =>\n (elem.constructor as typeof CDSOverflowMenuBody).FLOATING_MENU\n );\n }\n const { _menuBody: menuBody, size } = this;\n if (menuBody) {\n menuBody.id ||= this._menuId;\n menuBody.setAttribute('breadcrumb', String(this.breadcrumb));\n menuBody.open = open;\n menuBody.size = size;\n }\n }\n }\n\n if (\n changedProperties.has('enableV12Overflowmenu') &&\n !menuCompositionEnabled\n ) {\n this._menuController.hostDisconnected();\n this._resetMenuChildFloatingStyles({ closeMenu: true });\n }\n\n if (changedProperties.has('dataTable')) {\n const tooltip = this.shadowRoot?.querySelector(`${prefix}-tooltip`);\n tooltip?.toggleAttribute('data-table', this.dataTable);\n }\n\n if (changedProperties.has('size')) {\n button?.classList.forEach((item) => {\n if (item.startsWith(`${prefix}--overflow-menu--`)) {\n button?.classList.remove(item);\n }\n });\n button?.classList.add(`${prefix}--overflow-menu--${this.size}`);\n\n const tooltip = this.shadowRoot?.querySelector(`${prefix}-tooltip`);\n tooltip?.setAttribute('size', this.size);\n }\n\n if (changedProperties.has('toolbarAction') && this.toolbarAction) {\n this.shadowRoot\n ?.querySelector(`${prefix}-tooltip`)\n ?.setAttribute('toolbar-action', '');\n }\n\n const labelText = this._getLabelText();\n const popupId = menuCompositionEnabled\n ? (this._getMenuChild()?.id ?? this._menuId)\n : this._menuBody?.id;\n\n button?.setAttribute('aria-haspopup', 'menu');\n button?.setAttribute('aria-expanded', String(this.open));\n button?.setAttribute('aria-label', labelText);\n\n if (this.open && popupId) {\n button?.setAttribute('aria-controls', popupId);\n } else {\n button?.removeAttribute('aria-controls');\n }\n\n const shouldSyncMenuChild =\n menuCompositionEnabled &&\n (changedProperties.has('open') ||\n changedProperties.has('label') ||\n changedProperties.has('autoalign') ||\n changedProperties.has('menuAlignment') ||\n changedProperties.has('size') ||\n changedProperties.has('enableV12Overflowmenu'));\n\n if (shouldSyncMenuChild) {\n this._syncMenuChild();\n }\n\n if (changedProperties.has('open') || changedProperties.has('disabled')) {\n this._syncTriggerTooltipState();\n }\n }\n\n render() {\n return html`${super.render()} `;\n }\n\n private _getLabelText() {\n if (this.label) return this.label;\n\n const tooltipContent = this.querySelector(\n '[slot=tooltip-content]'\n )?.textContent?.trim();\n\n return tooltipContent || 'Options';\n }\n\n private _getTriggerButton() {\n return this.shadowRoot\n ?.querySelector(`${prefix}-tooltip`)\n ?.querySelector('button') as HTMLButtonElement | null;\n }\n\n private _isTriggerEvent(event: Event) {\n const triggerButton = this._getTriggerButton();\n\n return !!triggerButton && event.composedPath().includes(triggerButton);\n }\n\n private _isDeprecatedOverflowMenuItemEvent(event: Event) {\n return event\n .composedPath()\n .some(\n (entry) =>\n entry instanceof HTMLElement &&\n deprecatedOverflowMenuTagNames.has(entry.tagName)\n );\n }\n\n /**\n * Checks whether the menu-composition path is enabled.\n */\n private _isMenuCompositionEnabled() {\n return (\n this.enableV12Overflowmenu ||\n isFeatureFlagEnabled('enable-v12-overflowmenu', this)\n );\n }\n\n /**\n * Checks whether floating styles should be driven by Floating UI.\n */\n private _usesDynamicFloatingStyles() {\n return (\n this.autoalign ||\n isFeatureFlagEnabled('enable-v12-dynamic-floating-styles', this)\n );\n }\n\n private _getMenuChild() {\n return (Array.from(this.children).find((child) => {\n return child.tagName === `${prefix}-menu`.toUpperCase();\n }) ?? null) as CDSMenu | null;\n }\n\n private _warnDeprecatedChildren() {\n if (this._didWarnDeprecatedChildren) {\n return;\n }\n\n // Migration guard for flagged usage of deprecated overflow-menu children.\n const hasDeprecatedChildren = Array.from(this.children).some((child) => {\n return deprecatedOverflowMenuTagNames.has(child.tagName);\n });\n\n if (hasDeprecatedChildren) {\n warnInDev(\n '`cds-custom-overflow-menu` with `enable-v12-overflowmenu` expects a direct `cds-custom-menu` child instead of the deprecated `cds-custom-overflow-menu-body` structure.'\n );\n this._didWarnDeprecatedChildren = true;\n }\n }\n\n private _warnInvalidMenuComposition() {\n if (this._didWarnInvalidComposition) {\n return;\n }\n\n const hasDirectMenuItems = Array.from(this.children).some((child) =>\n child.tagName.startsWith(menuItemTagPrefix)\n );\n const hasMenuChild = !!this._getMenuChild();\n\n if (!hasMenuChild || hasDirectMenuItems) {\n warnInDev(\n '`cds-custom-overflow-menu` with `enable-v12-overflowmenu` expects a direct `cds-custom-menu` child. Place `cds-custom-menu-item*` descendants inside that `cds-custom-menu`.'\n );\n this._didWarnInvalidComposition = true;\n }\n }\n\n private _syncMenuChild() {\n const menuSyncToken = ++this._menuSyncToken;\n\n this._warnDeprecatedChildren();\n this._warnInvalidMenuComposition();\n\n const menu = this._getMenuChild();\n if (!menu) {\n return;\n }\n\n const menuAlignment = this.menuAlignment;\n\n menu.id ||= this._menuId;\n menu.label = this._getLabelText();\n menu.menuAlignment = menuAlignment;\n this._syncMenuChildPosition(menu);\n menu.open = this.open;\n menu.size = this._toMenuSize(this.size);\n\n const shouldUseFloatingStyles = this._usesDynamicFloatingStyles();\n\n if (!this.open || !shouldUseFloatingStyles) {\n this._menuController.hostDisconnected();\n this._resetMenuFloatingStyles(menu);\n return;\n }\n\n this.updateComplete.then(async () => {\n if (\n menuSyncToken !== this._menuSyncToken ||\n !this.open ||\n !this._isMenuCompositionEnabled() ||\n this._getMenuChild() !== menu\n ) {\n return;\n }\n\n await menu.updateComplete;\n if (\n menuSyncToken !== this._menuSyncToken ||\n !this.open ||\n !this._isMenuCompositionEnabled() ||\n this._getMenuChild() !== menu\n ) {\n return;\n }\n\n const trigger = this._getTriggerButton();\n if (!trigger) {\n return;\n }\n\n const styleElement = menu.shadowRoot?.querySelector(\n `.${prefix}--menu`\n ) as HTMLElement | undefined;\n\n const fallbackPlacements = menuAlignment.includes('bottom')\n ? [...bottomFirstFallbackPlacements]\n : [...topFirstFallbackPlacements];\n\n const flipArguments = this.autoalign\n ? {\n fallbackPlacements,\n }\n : {\n mainAxis: false,\n crossAxis: false,\n };\n\n this._menuController.setPlacement({\n trigger,\n target: menu,\n alignment: menuAlignment,\n styleElement,\n flipArguments,\n mainAxisOffset: 0,\n open: this.open,\n });\n });\n }\n\n private _syncMenuChildPosition(menu: CDSMenu) {\n const trigger = this._getTriggerButton();\n if (!trigger) {\n return;\n }\n\n const { left, right, top, bottom } = trigger.getBoundingClientRect();\n menu.x = [left, right];\n menu.y = [top, bottom];\n }\n\n private _toMenuSize(size: OVERFLOW_MENU_SIZE | string): CDSMenu['size'] {\n switch (size) {\n case OVERFLOW_MENU_SIZE.EXTRA_SMALL:\n return MENU_SIZE.EXTRA_SMALL;\n case OVERFLOW_MENU_SIZE.SMALL:\n return MENU_SIZE.SMALL;\n case OVERFLOW_MENU_SIZE.MEDIUM:\n return MENU_SIZE.MEDIUM;\n case OVERFLOW_MENU_SIZE.LARGE:\n return MENU_SIZE.LARGE;\n default:\n return MENU_SIZE.MEDIUM;\n }\n }\n\n private async _focusManagedMenuItem(index: number) {\n const menu = this._getMenuChild();\n if (!menu) {\n return;\n }\n\n await menu.updateComplete;\n\n if (!this.open || this._getMenuChild() !== menu) {\n return;\n }\n\n const enabledItems = menu.activeitems\n .map(({ item }) => item)\n .filter(\n (item) => item instanceof HTMLElement && !item.hasAttribute('disabled')\n );\n const focusTarget = enabledItems[index - 1] ?? enabledItems[0];\n\n focusTarget?.focus();\n }\n\n private _resetMenuChildFloatingStyles({\n closeMenu = false,\n }: { closeMenu?: boolean } = {}) {\n const menu = this._getMenuChild();\n if (!menu) {\n return;\n }\n\n this._resetMenuFloatingStyles(menu);\n\n if (closeMenu) {\n menu.open = false;\n }\n }\n\n private _resetMenuFloatingStyles(menu: CDSMenu) {\n const menuSurface = menu.shadowRoot?.querySelector(`.${prefix}--menu`) as\n | HTMLElement\n | undefined;\n\n if (!menuSurface) {\n return;\n }\n\n menuSurface.style.removeProperty('left');\n menuSurface.style.removeProperty('top');\n menuSurface.style.removeProperty('position');\n menuSurface.style.removeProperty('visibility');\n menuSurface.removeAttribute('align');\n }\n\n /**\n * Suppresses trigger tooltip interactions while the menu is open.\n */\n private _syncTriggerTooltipState() {\n const tooltip = this.shadowRoot?.querySelector(`${prefix}-tooltip`) as\n | (HTMLElement & { open?: boolean; keyboardOnly?: boolean })\n | null;\n const tooltipContent = this.shadowRoot?.querySelector(\n `${prefix}-tooltip-content`\n ) as HTMLElement | null;\n\n if (!tooltip) {\n return;\n }\n\n tooltip.keyboardOnly = this.open;\n tooltipContent?.toggleAttribute('hidden', this.disabled || this.open);\n\n if (this.open) {\n tooltip.open = false;\n }\n }\n}\n\nexport default CDSOverflowMenu;\n"],"mappings":"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"}