Skip to content

Commit

Permalink
change(popup): create custom popup for better accessibility
Browse files Browse the repository at this point in the history
- the semantic variant adds the content in a portal at the end of the body
  which makes it hard to correctly go to the next element
  • Loading branch information
ichim-david committed Mar 23, 2023
1 parent b4c4d34 commit 036aac9
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 1 deletion.
90 changes: 90 additions & 0 deletions src/ui/Popup/Popup.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';
import { createPopper } from '@popperjs/core';
import EventStack from '@semantic-ui-react/event-stack';

class Popup extends React.Component {
constructor(props) {
super(props);

this.triggerRef = React.createRef();
this.popupRef = React.createRef();

this.state = {
isOpen: false,
};

this.togglePopup = this.togglePopup.bind(this);
this.closeOnEscape = this.closeOnEscape.bind(this);
}

componentDidMount() {
this.popper = createPopper(this.triggerRef.current, this.popupRef.current, {
placement: this.props.position || 'bottom-end',
strategy: this.props.positionFixed || 'absolute',
modifiers: [
{
name: 'offset',
options: {
offset: this.props.offset || [0, 0],
},
},
...(this.props.popperModifiers || []),
],
});
}

componentWillUnmount() {
this.popper && this.popper.destroy();
}

togglePopup() {
this.setState(
(state) => {
return {
isOpen: !state.isOpen,
};
},
() => {
this.popper.forceUpdate();
},
);
}
closeOnEscape(e) {
if (e.key === 'Escape') {
this.setState((state) => {
return {
isOpen: !state.isOpen,
};
});
}
}

render() {
return (
<React.Fragment>
{this.props.trigger &&
React.cloneElement(this.props.trigger, {
onClick: this.togglePopup,
ref: this.triggerRef,
})}

<div className="popup-container" ref={this.popupRef}>
{this.state.isOpen && (
<EventStack name="keydown" on={this.closeOnEscape} />
)}
<React.Fragment>
<div
className={`ui bottom center small popup transition ${
this.props.className ? this.props.className : ''
} ${this.state.isOpen ? 'visible' : ''}`}
>
{this.props.content}
</div>
</React.Fragment>
</div>
</React.Fragment>
);
}
}

export default Popup;
5 changes: 4 additions & 1 deletion src/ui/Popup/Popup.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { React } from 'react';
import { Button, Segment, Popup, Image, Icon } from 'semantic-ui-react';
import { Button, Segment, Image, Icon } from 'semantic-ui-react';

import Popup from './Popup';

import EUflag from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/europe-flag.svg';

export default {
Expand Down

0 comments on commit 036aac9

Please sign in to comment.