diff --git a/components/button/src/split-button/split-button.js b/components/button/src/split-button/split-button.js
index 95290477be..fadbc21a92 100644
--- a/components/button/src/split-button/split-button.js
+++ b/components/button/src/split-button/split-button.js
@@ -7,6 +7,7 @@ import PropTypes from 'prop-types'
import React, { Component } from 'react'
import css from 'styled-jsx/css'
import { Button } from '../index.js'
+import i18n from '../locales/index.js'
const rightButton = css.resolve`
button {
@@ -18,8 +19,25 @@ class SplitButton extends Component {
state = {
open: false,
}
+
anchorRef = React.createRef()
+ componentDidMount() {
+ document.addEventListener('keydown', this.handleKeyDown)
+ }
+
+ componentWillUnmount() {
+ document.removeEventListener('keydown', this.handleKeyDown)
+ }
+ handleKeyDown = (event) => {
+ event.preventDefault()
+ if (event.key === 'Escape' && this.state.open) {
+ event.stopPropagation()
+ this.setState({ open: false })
+ this.anchorRef.current && this.anchorRef.current.focus()
+ }
+ }
+
onClick = (payload, event) => {
if (this.props.onClick) {
this.props.onClick(
@@ -33,7 +51,9 @@ class SplitButton extends Component {
}
}
- onToggle = () => this.setState({ open: !this.state.open })
+ onToggle = () => {
+ this.setState((prevState) => ({ open: !prevState.open }))
+ }
render() {
const { open } = this.state
@@ -94,6 +114,8 @@ class SplitButton extends Component {
tabIndex={tabIndex}
className={cx(className, rightButton.className)}
dataTest={`${dataTest}-toggle`}
+ title={i18n.t('Toggle dropdown')}
+ aria-label={i18n.t('Toggle dropdown')}
>
{arrow}
diff --git a/components/button/src/split-button/split-button.test.js b/components/button/src/split-button/split-button.test.js
new file mode 100644
index 0000000000..d7c8ef2027
--- /dev/null
+++ b/components/button/src/split-button/split-button.test.js
@@ -0,0 +1,85 @@
+import { render, fireEvent, cleanup, waitFor } from '@testing-library/react'
+import React from 'react'
+import '@testing-library/jest-dom/extend-expect'
+import { SplitButton } from './split-button.js'
+
+describe('SplitButton', () => {
+ afterEach(cleanup)
+
+ it('renders button with children', () => {
+ const { getByText } = render(Click me)
+ expect(getByText('Click me')).toBeInTheDocument()
+ })
+
+ it('toggles dropdown when left button is clicked', () => {
+ const { getByTestId, queryByTestId } = render()
+ const toggleButton = getByTestId('dhis2-uicore-splitbutton-toggle')
+
+ fireEvent.click(toggleButton)
+ expect(
+ queryByTestId('dhis2-uicore-splitbutton-menu')
+ ).toBeInTheDocument()
+
+ fireEvent.click(toggleButton)
+ expect(
+ queryByTestId('dhis2-uicore-splitbutton-menu')
+ ).not.toBeInTheDocument()
+ })
+
+ it('renders dropdown content when open is true', () => {
+ const { getByTestId } = render(
+ Dropdown Content} />
+ )
+
+ const toggleButton = getByTestId('dhis2-uicore-splitbutton-toggle')
+ fireEvent.click(toggleButton)
+
+ expect(getByTestId('dhis2-uicore-splitbutton-menu')).toBeInTheDocument()
+ })
+
+ it("does not close dropdown 'Enter' key is pressed", async () => {
+ const { getByTestId } = render(
+ Dropdown Content} />
+ )
+
+ const toggleButton = getByTestId('dhis2-uicore-splitbutton-toggle')
+ fireEvent.click(toggleButton)
+ expect(getByTestId('dhis2-uicore-splitbutton-menu')).toBeInTheDocument()
+
+ fireEvent.keyDown(document, { key: 'Enter' })
+
+ // Use waitFor to wait for the DOM to update
+ await waitFor(() => {
+ expect(
+ getByTestId('dhis2-uicore-splitbutton-menu')
+ ).toBeInTheDocument()
+ })
+ })
+
+ it('closes dropdown when escape key is pressed', async () => {
+ const { getByTestId, queryByTestId } = render(
+ Dropdown Content} />
+ )
+
+ const toggleButton = getByTestId('dhis2-uicore-splitbutton-toggle')
+ fireEvent.click(toggleButton)
+ expect(getByTestId('dhis2-uicore-splitbutton-menu')).toBeInTheDocument()
+
+ fireEvent.keyDown(document, { key: 'Escape' })
+
+ // Use waitFor to wait for the DOM to update
+ await waitFor(() => {
+ expect(
+ queryByTestId('dhis2-uicore-splitbutton-menu')
+ ).not.toBeInTheDocument()
+ })
+ })
+
+ it('adds title and aria-label attributes to the right button', () => {
+ const { getByTestId } = render()
+ const toggleButton = getByTestId('dhis2-uicore-splitbutton-toggle')
+
+ expect(toggleButton).toHaveAttribute('title', 'Toggle dropdown')
+ expect(toggleButton).toHaveAttribute('aria-label', 'Toggle dropdown')
+ })
+})