Skip to content

Commit

Permalink
Added autoFocus option to EuiTabbedContent
Browse files Browse the repository at this point in the history
  • Loading branch information
cchaos committed Jun 19, 2019
1 parent 35f0931 commit 5191547
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 6 deletions.
1 change: 1 addition & 0 deletions src-docs/src/views/tabs/tabbed_content.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class EuiTabsExample extends Component {
<EuiTabbedContent
tabs={this.tabs}
initialSelectedTab={this.tabs[1]}
autoFocus="selected"
onTabClick={tab => {
console.log('clicked tab', tab);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function EuiDatePopoverContent({
<EuiTabbedContent
className="euiDatePopoverContent"
tabs={renderTabs()}
autoFocus="selected"
initialSelectedTab={{ id: getDateMode(value) }}
onTabClick={onTabClick}
size="s"
Expand Down
3 changes: 3 additions & 0 deletions src/components/tabs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ declare module '@elastic/eui' {
content: ReactNode;
}

type TABBED_CONTENT_AUTOFOCUS = 'initial' | 'selected';

interface EuiTabbedContentProps {
tabs: EuiTabbedContentTab[];
onTabClick?: (tab: EuiTabbedContentTab) => void;
Expand All @@ -37,6 +39,7 @@ declare module '@elastic/eui' {
size?: TAB_SIZES;
display?: TAB_DISPLAYS;
expand?: boolean;
autoFocus?: TABBED_CONTENT_AUTOFOCUS;
}

export const EuiTab: FunctionComponent<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ exports[`EuiTabbedContent behavior when selected tab state isn't controlled by t

exports[`EuiTabbedContent behavior when uncontrolled, the selected tab should update if it receives new content 1`] = `
<EuiTabbedContent
autoFocus="initial"
tabs={
Array [
Object {
Expand All @@ -70,7 +71,10 @@ exports[`EuiTabbedContent behavior when uncontrolled, the selected tab should up
]
}
>
<div>
<div
onBlur={[Function]}
onFocus={[Function]}
>
<EuiTabs
display="default"
expand={false}
Expand Down
50 changes: 45 additions & 5 deletions src/components/tabs/tabbed_content/tabbed_content.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { EuiTab } from '../tab';

const makeId = htmlIdGenerator();

export const AUTOFOCUS = ['initial', 'selected'];

export class EuiTabbedContent extends Component {
static propTypes = {
className: PropTypes.string,
Expand All @@ -29,6 +31,12 @@ export class EuiTabbedContent extends Component {
* Use this prop if you want to control selection state within the owner component
*/
selectedTab: PropTypes.object,
/**
* When tabbing to into the tabs, set the focus on `initial` for the first tab,
* or `selected` for the currently selected tab. Best use case is for inside of
* overlay content like popovers or flyouts.
*/
autoFocus: PropTypes.oneOf(AUTOFOCUS),
size: PropTypes.oneOf(SIZES),
/**
* Each tab needs id and content properties, so we can associate it with its panel for accessibility.
Expand All @@ -51,14 +59,37 @@ export class EuiTabbedContent extends Component {
this.rootId = makeId();

// Only track selection state if it's not controlled externally.
let selectedTabId;
if (!selectedTab) {
this.state = {
selectedTabId:
(initialSelectedTab && initialSelectedTab.id) || tabs[0].id,
};
selectedTabId =
(initialSelectedTab && initialSelectedTab.id) || tabs[0].id;
}

this.state = {
selectedTabId,
inFocus: false,
};
}

initializeFocus = () => {
console.log('THE FOCUS HAPPENED', this.state.inFocus, this.props.autoFocus);

if (!this.state.inFocus && this.props.autoFocus === 'selected') {
console.log('Focusing tab');
document.getElementById(this.state.selectedTabId).focus();
}

this.setState({
inFocus: true,
});
};

removeFocus = () => {
this.setState({
inFocus: false,
});
};

onTabClick = selectedTab => {
const { onTabClick, selectedTab: externalSelectedTab } = this.props;

Expand All @@ -82,6 +113,7 @@ export class EuiTabbedContent extends Component {
selectedTab: externalSelectedTab,
size,
tabs,
autoFocus,
...rest
} = this.props;

Expand All @@ -93,7 +125,11 @@ export class EuiTabbedContent extends Component {
const { content: selectedTabContent, id: selectedTabId } = selectedTab;

return (
<div className={className} {...rest}>
<div
className={className}
{...rest}
onFocus={this.initializeFocus}
onBlur={this.removeFocus}>
<EuiTabs expand={expand} display={display} size={size}>
{tabs.map(tab => {
const {
Expand Down Expand Up @@ -125,3 +161,7 @@ export class EuiTabbedContent extends Component {
);
}
}

EuiTabbedContent.defaultProps = {
autoFocus: 'initial',
};

0 comments on commit 5191547

Please sign in to comment.