Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(floating-menu): add focus wrap element to components #3652

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
47e6aaa
feat(vanilla): remove global hidden input
Aug 5, 2019
ff5325f
feat(floating-menu): support focus wrap within component
Aug 5, 2019
41c4025
feat(modal): update demo with inline focus wrap
Aug 5, 2019
42a5ee5
feat(overflow-menu): inline focus wrap
Aug 5, 2019
e4e3d4a
feat(tooltip): inline focus wrap
Aug 5, 2019
562d94c
Merge branch 'master' of github.com:carbon-design-system/carbon into …
Aug 7, 2019
f824b39
fix(modal): remove need for extra div
Aug 7, 2019
53c9f79
Merge branch 'master' of github.com:carbon-design-system/carbon into …
Aug 8, 2019
1a634f5
fix(floating-menu): support inline focus wrap
Aug 8, 2019
9c235c5
fix(overflow-menu): uses inline focus element
Aug 8, 2019
6c5f857
fix(tooltip): uses inline focus element
Aug 8, 2019
fb23775
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 8, 2019
45b4fce
Merge branch 'master' of github.com:carbon-design-system/carbon into …
Aug 12, 2019
d325877
fix(floating-menu): update test selectors
Aug 12, 2019
9c69195
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 12, 2019
b790e14
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 13, 2019
092bc7c
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 15, 2019
0cfdc79
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 15, 2019
48d72bc
Merge branch 'master' into feature/floating-menu-focus-wrap
Aug 26, 2019
0c5b828
Merge branch 'master' into feature/floating-menu-focus-wrap
tw15egan Aug 26, 2019
3bb9e4c
Merge branch 'master' into feature/floating-menu-focus-wrap
elizabethsjudd Aug 29, 2019
47e60d8
Merge branch 'master' into feature/floating-menu-focus-wrap
elizabethsjudd Sep 4, 2019
41360ff
Merge branch 'master' into feature/floating-menu-focus-wrap
tw15egan Sep 4, 2019
d5b347b
Merge branch 'master' into feature/floating-menu-focus-wrap
tw15egan Sep 4, 2019
abf3402
Merge branch 'master' into feature/floating-menu-focus-wrap
joshblack Sep 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions packages/components/demo/views/layouts/preview.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
{{{yield}}}
</div>

<!-- Pseudo element to demonstrate focus-wrap behavior (focus trap) -->
<input aria-label="inpute-text-offleft" type="text" class="offleft" />

<!-- Scripts -->
<!-- <script src="/carbon-components.min.js"></script> -->
<script src="/demo{{#if minify}}.min{{/if}}.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@ class FloatingMenu extends mixin(
this._place();
});
}
this._getContainer().appendChild(this.element);
this._getContainer().appendChild(
this.options.wrapperNode || this.element
);
this._place();
// IE11 puts focus on elements with `.focus()`, even ones without `tabindex` attribute
if (!this.element.hasAttribute(this.options.attribAvoidFocusOnOpen)) {
Expand Down
65 changes: 36 additions & 29 deletions packages/components/src/components/modal/modal.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,43 @@
<button class="{{@root.prefix}}--btn {{classPrimaryButton}}" type="button" data-modal-target="#modal-{{idSuffix}}">Show
modal</button>

<div data-modal id="modal-{{idSuffix}}" class="{{@root.prefix}}--modal {{classModalSupplemental}}" role="dialog"
aria-modal="true" aria-labelledby="modal-{{idSuffix}}-label" aria-describedby="modal-{{idSuffix}}-heading" tabindex="-1">
<div class="{{@root.prefix}}--modal-container">
<div class="{{@root.prefix}}--modal-header">
<p class="{{@root.prefix}}--modal-header__label {{@root.prefix}}--type-delta" id="modal-{{idSuffix}}-label">Optional label</p>
<p class="{{@root.prefix}}--modal-header__heading {{@root.prefix}}--type-beta" id="modal-{{idSuffix}}-heading">Modal heading</p>
<button class="{{@root.prefix}}--modal-close" type="button" data-modal-close aria-label="close modal" {{#unless hasFooter}} data-modal-primary-focus{{/unless}}>
{{ carbon-icon 'Close16' class=(add @root.prefix '--modal-close__icon') }}
</button>
</div>
<div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you put additional <div> rather than simply adding focus trap element to the last? Note that no user-visible focusable element should be put outside <div class="bx--modal-container">.

<div data-modal id="modal-{{idSuffix}}" class="{{@root.prefix}}--modal {{classModalSupplemental}}" role="dialog"
aria-modal="true" aria-labelledby="modal-{{idSuffix}}-label" aria-describedby="modal-{{idSuffix}}-heading" tabindex="-1">
<div class="{{@root.prefix}}--modal-container">
<div class="{{@root.prefix}}--modal-header">
<p class="{{@root.prefix}}--modal-header__label {{@root.prefix}}--type-delta" id="modal-{{idSuffix}}-label">Optional label</p>
<p class="{{@root.prefix}}--modal-header__heading {{@root.prefix}}--type-beta" id="modal-{{idSuffix}}-heading">Modal heading</p>
<button class="{{@root.prefix}}--modal-close" type="button" data-modal-close aria-label="close modal" {{#unless hasFooter}} data-modal-primary-focus{{/unless}}>
{{ carbon-icon 'Close16' class=(add @root.prefix '--modal-close__icon') }}
</button>
</div>

<div class="{{@root.prefix}}--modal-content">
{{#if hasInput}}
<div class="{{@root.prefix}}--form-item">
<label for="text-input-{{idSuffix}}" class="{{@root.prefix}}--label">Text Input label</label>
<input id="text-input-{{idSuffix}}" type="text" class="{{@root.prefix}}--text-input" placeholder="Optional placeholder text"
data-modal-primary-focus>
<div class="{{@root.prefix}}--modal-content">
{{#if hasInput}}
<div class="{{@root.prefix}}--form-item">
<label for="text-input-{{idSuffix}}" class="{{@root.prefix}}--label">Text Input label</label>
<input id="text-input-{{idSuffix}}" type="text" class="{{@root.prefix}}--text-input" placeholder="Optional placeholder text"
data-modal-primary-focus>
</div>
{{else}}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id accumsan augue. Phasellus consequat augue
vitae
tellus tincidunt posuere. Curabitur justo urna, consectetur vel elit iaculis, ultrices condimentum risus. Nulla
facilisi.
Etiam venenatis molestie tellus. Quisque consectetur non risus eu rutrum. </p>
{{/if}}
</div>

{{#if hasFooter}}
<div class="{{@root.prefix}}--modal-footer">
<button class="{{@root.prefix}}--btn {{classCloseButton}}" type="button" data-modal-close>Secondary button</button>
<button class="{{@root.prefix}}--btn {{classPrimaryButton}}" type="button" {{#if labelPrimaryButton}} aria-label="{{labelPrimaryButton}}"
{{/if}} {{#unless hasInput}} data-modal-primary-focus{{/unless}}>Primary button</button>
</div>
{{else}}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id accumsan augue. Phasellus consequat augue
vitae
tellus tincidunt posuere. Curabitur justo urna, consectetur vel elit iaculis, ultrices condimentum risus. Nulla
facilisi.
Etiam venenatis molestie tellus. Quisque consectetur non risus eu rutrum. </p>
{{/if}}
</div>

{{#if hasFooter}}
<div class="{{@root.prefix}}--modal-footer">
<button class="{{@root.prefix}}--btn {{classCloseButton}}" type="button" data-modal-close>Secondary button</button>
<button class="{{@root.prefix}}--btn {{classPrimaryButton}}" type="button" {{#if labelPrimaryButton}} aria-label="{{labelPrimaryButton}}"
{{/if}} {{#unless hasInput}} data-modal-primary-focus{{/unless}}>Primary button</button> </div> {{/if}} </div>
</div>
</div>
<!-- Note: focusable span allows for focus wrap feature within Modals -->
<span tabindex="0"></span>
</div>
102 changes: 56 additions & 46 deletions packages/components/src/components/overflow-menu/overflow-menu.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@
<span class="{{@root.prefix}}--assistive-text">Overflow</span>
{{ carbon-icon 'OverflowMenuVertical16' class=(add @root.prefix '--overflow-menu__icon') }}
</button>
<ul class="{{@root.prefix}}--overflow-menu-options" tabindex="-1" role="menu"
aria-labelledby="{{idSuffix.default}}-trigger" data-floating-menu-direction="{{direction}}"
id="{{idSuffix.default}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option {{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled {{/if}} {{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger {{/if}}">
<button class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}} title="{{title}}"
{{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus {{/if}} {{#if disabled}} disabled {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</button>
</li>
{{/each}}
</ul>
<div class="{{@root.prefix}}--overflow-menu-wrapper">
asudoh marked this conversation as resolved.
Show resolved Hide resolved
<ul class="{{@root.prefix}}--overflow-menu-options" tabindex="-1" role="menu"
aria-labelledby="{{idSuffix.default}}-trigger" data-floating-menu-direction="{{direction}}"
id="{{idSuffix.default}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option {{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled {{/if}} {{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger {{/if}}">
<button class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}} title="{{title}}"
{{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus {{/if}} {{#if disabled}} disabled {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</button>
</li>
{{/each}}
</ul>
<!-- Note: focusable span allows for focus wrap feature within Overflow Menus -->
<span tabindex="0"></span>
</div>
</div>

<div data-overflow-menu class="{{@root.prefix}}--overflow-menu">
Expand All @@ -35,21 +39,24 @@
<span class="{{@root.prefix}}--assistive-text">Overflow</span>
{{ carbon-icon 'OverflowMenuVertical16' class=(add @root.prefix '--overflow-menu__icon') }}
</button>
<ul class="{{@root.prefix}}--overflow-menu-options {{@root.prefix}}--overflow-menu--flip" tabindex="-1"
data-floating-menu-direction="{{direction}}" role="menu" aria-labelledby="{{idSuffix.flip}}-trigger"
id="{{idSuffix.flip}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option {{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled {{/if}} {{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger {{/if}}">
<button class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}} title="{{title}}"
{{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus {{/if}} {{#if disabled}} disabled {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</button>
</li>
{{/each}}
</ul>
<div class="{{@root.prefix}}--overflow-menu-wrapper">
<ul class="{{@root.prefix}}--overflow-menu-options {{@root.prefix}}--overflow-menu--flip" tabindex="-1"
data-floating-menu-direction="{{direction}}" role="menu" aria-labelledby="{{idSuffix.flip}}-trigger"
id="{{idSuffix.flip}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option {{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled {{/if}} {{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger {{/if}}">
<button class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}} title="{{title}}"
{{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus {{/if}} {{#if disabled}} disabled {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</button>
</li>
{{/each}}
</ul>
<span tabindex="0"></span>
</div>
</div>

<div data-overflow-menu class="{{@root.prefix}}--overflow-menu">
Expand All @@ -59,20 +66,23 @@
<span class="{{@root.prefix}}--assistive-text">Overflow</span>
{{ carbon-icon 'OverflowMenuVertical16' class=(add @root.prefix '--overflow-menu__icon') }}
</button>
<ul class="{{@root.prefix}}--overflow-menu-options {{@root.prefix}}--overflow-menu--flip" tabindex="-1"
data-floating-menu-direction="{{direction}}" role="menu" aria-labelledby="{{idSuffix.link}}-trigger"
id="{{idSuffix.link}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option{{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled{{/if}}{{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger{{/if}}">
<a href="https://www.ibm.com" class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}}
title="{{title}}" {{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus{{/if}}{{#if disabled}}
tabindex="-1" aria-disabled="true" {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</a>
</li>
{{/each}}
</ul>
<div class="{{@root.prefix}}--overflow-menu-wrapper">
asudoh marked this conversation as resolved.
Show resolved Hide resolved
<ul class="{{@root.prefix}}--overflow-menu-options {{@root.prefix}}--overflow-menu--flip" tabindex="-1"
data-floating-menu-direction="{{direction}}" role="menu" aria-labelledby="{{idSuffix.link}}-trigger"
id="{{idSuffix.link}}">
{{#each items}}
<li
class="{{@root.prefix}}--overflow-menu-options__option{{#if disabled}} {{@root.prefix}}--overflow-menu-options__option--disabled{{/if}}{{#if danger}} {{@root.prefix}}--overflow-menu-options__option--danger{{/if}}">
<a href="https://www.ibm.com" class="{{@root.prefix}}--overflow-menu-options__btn" role="menuitem" {{#if title}}
title="{{title}}" {{/if}} {{#if primaryFocus}} data-floating-menu-primary-focus{{/if}}{{#if disabled}}
tabindex="-1" aria-disabled="true" {{/if}}>
<span class="{{@root.prefix}}--overflow-menu-options__option-content">
{{label}}
</span>
</a>
</li>
{{/each}}
</ul>
<span tabindex="0"></span>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class OverflowMenu extends mixin(
classRefShown: this.options.classShown,
offset: this.options.objMenuOffset,
triggerNode: this.triggerNode,
wrapperNode: this.element.querySelector(this.options.selectorWrapper),
});
this.children.push(this.optionMenu);
}
Expand Down Expand Up @@ -345,6 +346,7 @@ class OverflowMenu extends mixin(
selectorInit: '[data-overflow-menu]',
selectorOptionMenu: `.${prefix}--overflow-menu-options`,
selectorTrigger: 'button[aria-haspopup]',
selectorWrapper: `.${prefix}--overflow-menu-wrapper`,
selectorItem: `
.${prefix}--overflow-menu-options--open >
.${prefix}--overflow-menu-options__option:not(.${prefix}--overflow-menu-options__option--disabled) >
Expand Down
79 changes: 45 additions & 34 deletions packages/components/src/components/tooltip/tooltip.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@
{{ carbon-icon 'Information16' }}
</div>
</div>
{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{noHeading.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{noHeading.idSuffix}}-body" aria-labelledby="{{noHeading.idSuffix}}-label">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<p id="{{noHeading.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
<div class="{{@root.prefix}}--tooltip-wrapper">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question to overflow menu - Would you put the trap element next to <div class="bx--tooltip__footer">?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asudoh the trap element needs to be outside of the content area of the tooltip not a sibling within it. Currently with the way that the trap element works, it can not be a direct sibling of the content area which in the case of tooltips content is any direct child of .bx--tooltip

Current structure of tooltip

<bx--tooltip>
  <bx--tooltip__caret/>
  <p>Tooltip content</p>
  <bx--tooltip__footer/>
  <!-- trap element is a sibling of content if placed here and doesn't work -->
  <trap-element>
</bx--tooltip>

There are a couple different options:

1. Scope the content area

We could add a div within the tooltip around any of the content including the footer and update the event listener to watch the new div instead of the tooltip element

<bx--tooltip>
  <bx--tooltip__caret/>
  <div>
    <p>Tooltip content</p>
    <bx--tooltip__footer/>
  </div>
  <trap-element>
</bx--tooltip>

2. Add a unique selector to the trap element

We could give a unique selector to the trap element and watch for it to get focus and when it gets focus, immediate move it. If that's the case we can keep the original HTML structure.

<bx--tooltip>
  <bx--tooltip__caret/>
  <p>Tooltip content</p>
  <bx--tooltip__footer/>
  <span tabindex="0" class="bx--focus-trap"></span>
</bx--tooltip>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies, I seems to have missed this comment. I think 1. makes sense. BTW instead of wrapper node ref, let's move the root node up to the wrapper as above structure tells. If we need to refer to where the root node used to be, we can introduce options.selectorContent. Thanks!

{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{noHeading.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{noHeading.idSuffix}}-body" aria-labelledby="{{noHeading.idSuffix}}-label">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<p id="{{noHeading.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
</div>
</div>
<!-- Note: focusable span allows for focus wrap feature within Tooltips -->
<span tabindex="0"></span>
</div>


{{!-- Tooltip with visible label within tooltip --}}
<div id="{{heading.idSuffix}}-label" class="{{@root.prefix}}--tooltip__label">
Tooltip label
Expand All @@ -39,19 +44,22 @@
{{ carbon-icon 'Information16' }}
</div>
</div>
{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{heading.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{heading.idSuffix}}-body" aria-labelledby="{{heading.idSuffix}}-heading">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<h4 id="{{heading.idSuffix}}-heading">Heading within a Tooltip</h4>
<p id="{{heading.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
<div class="{{@root.prefix}}--tooltip-wrapper">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some question as another instance of tooltip body.

{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{heading.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{heading.idSuffix}}-body" aria-labelledby="{{heading.idSuffix}}-heading">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<h4 id="{{heading.idSuffix}}-heading">Heading within a Tooltip</h4>
<p id="{{heading.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
</div>
</div>
<span tabindex="0"></span>
</div>

{{!-- Tooltip without visible label (not recommended for WCAG 2.1) --}}
Expand All @@ -64,16 +72,19 @@
{{ carbon-icon 'Information16' }}
</div>
</div>
{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{label.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{label.idSuffix}}-body" aria-label="Tooltip label">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<p id="{{label.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
<div class="{{@root.prefix}}--tooltip-wrapper">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some question as another instance of tooltip body.

{{!-- @todo add aria-hidden once JavaScript can toggle it --}}
<div id="{{label.idSuffix}}" data-floating-menu-direction="bottom" class="{{@root.prefix}}--tooltip"
data-avoid-focus-on-open role="dialog" aria-describedby="{{label.idSuffix}}-body" aria-label="Tooltip label">
<span class="{{@root.prefix}}--tooltip__caret"></span>
<p id="{{label.idSuffix}}-body" >This is some tooltip text. This box shows the maximum amount of text that should appear inside. If more room is
needed
please use a modal instead.</p>
<div class="{{@root.prefix}}--tooltip__footer">
<a href="#" class="{{@root.prefix}}--link">Learn More</a>
<button class="{{@root.prefix}}--btn {{@root.prefix}}--btn--primary {{@root.prefix}}--btn--sm"
type="button">Create</button>
</div>
</div>
<span tabindex="0"></span>
</div>
8 changes: 8 additions & 0 deletions packages/components/src/components/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,18 @@ class Tooltip extends mixin(
throw new Error('Cannot find the target tooltip.');
}

const wrapperNode = tooltip.parentNode.matches(
this.options.selectorWrapper
)
? tooltip.parentNode
: null;

// Lazily create a component instance for tooltip
this.tooltip = FloatingMenu.create(tooltip, {
refNode: this.element,
classShown: this.options.classShown,
offset: this.options.objMenuOffset,
wrapperNode,
});
this._hookOn(tooltip);
this.children.push(this.tooltip);
Expand Down Expand Up @@ -222,6 +229,7 @@ class Tooltip extends mixin(
const { prefix } = settings;
return {
selectorInit: '[data-tooltip-trigger]',
selectorWrapper: `.${prefix}--tooltip-wrapper`,
classShown: `${prefix}--tooltip--shown`,
attribTooltipTarget: 'data-tooltip-target',
objMenuOffset: getMenuOffset,
Expand Down