box-ui-elements 23.3.0-beta.7 → 23.3.0-beta.8
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.
- package/dist/explorer.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/sidebar.js +1 -1
- package/es/components/flyout/Flyout.js +3 -2
- package/es/components/flyout/Flyout.js.flow +3 -2
- package/es/components/flyout/Flyout.js.map +1 -1
- package/package.json +1 -1
- package/src/components/flyout/Flyout.js +3 -2
- package/src/components/flyout/__tests__/Flyout.test.js +31 -20
|
@@ -154,8 +154,9 @@ class Flyout extends React.Component {
|
|
|
154
154
|
}, openOnHoverDelayTimeout);
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
|
-
_defineProperty(this, "handleKeyPress",
|
|
158
|
-
if (KEYS.enter) {
|
|
157
|
+
_defineProperty(this, "handleKeyPress", event => {
|
|
158
|
+
if (event.key === KEYS.enter) {
|
|
159
|
+
event.preventDefault();
|
|
159
160
|
this.openOverlay();
|
|
160
161
|
this.focusButton();
|
|
161
162
|
}
|
|
@@ -305,8 +305,9 @@ class Flyout extends React.Component<Props, State> {
|
|
|
305
305
|
}
|
|
306
306
|
};
|
|
307
307
|
|
|
308
|
-
handleKeyPress = () => {
|
|
309
|
-
if (KEYS.enter) {
|
|
308
|
+
handleKeyPress = (event: SyntheticKeyboardEvent<>) => {
|
|
309
|
+
if (event.key === KEYS.enter) {
|
|
310
|
+
event.preventDefault();
|
|
310
311
|
this.openOverlay();
|
|
311
312
|
this.focusButton();
|
|
312
313
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Flyout.js","names":["React","classNames","TetherComponent","uniqueId","KEYS","FlyoutContext","BOTTOM_CENTER","BOTTOM_LEFT","BOTTOM_RIGHT","MIDDLE_LEFT","MIDDLE_RIGHT","TOP_CENTER","TOP_LEFT","TOP_RIGHT","positions","attachment","targetAttachment","OVERLAY_ROLE","hasClickableAncestor","rootNode","targetNode","currentNode","Node","parentNode","nodeName","toUpperCase","hasClassAncestor","targetEl","className","el","HTMLElement","classList","contains","Flyout","Component","constructor","props","_defineProperty","event","overlayNode","document","getElementById","overlayID","closeOnClick","closeOnClickPredicate","target","handleOverlayClose","isVisible","state","closeOverlay","openOverlay","isButtonClicked","isTrusted","setState","preventDefault","openOnHover","openOnHoverDelayTimeout","clearTimeout","hoverDelay","setTimeout","enter","focusButton","onOpen","onClose","buttonEl","overlayButtonID","focus","portaledClasses","closeOnClickOutside","closeOnWindowBlur","buttonNode","isInsideToggleButton","isInsideOverlay","isInside","some","isVisibleByDefault","componentDidUpdate","prevProps","prevState","addEventListener","handleDocumentClickOrWindowBlur","window","removeEventListener","componentWillUnmount","render","children","constrainToScrollParent","constrainToWindow","constrainToWindowWithPin","isResponsive","offset","position","shouldDefaultFocus","elements","Children","toArray","tetherPosition","length","Error","overlayButton","overlayContent","overlayButtonProps","id","key","onClick","handleButtonClick","onKeyPress","handleKeyPress","onMouseEnter","handleButtonHover","onMouseLeave","handleButtonHoverLeave","role","tabIndex","overlayProps","handleOverlayClick","constraints","push","to","pin","tetherProps","classPrefix","enabled","classes","element","createElement","cloneElement","Provider","value"],"sources":["../../../src/components/flyout/Flyout.js"],"sourcesContent":["// @flow\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport TetherComponent from 'react-tether';\nimport uniqueId from 'lodash/uniqueId';\nimport { KEYS } from '../../constants';\n\nimport FlyoutContext from './FlyoutContext';\n\nimport './Flyout.scss';\n\nconst BOTTOM_CENTER = 'bottom-center';\nconst BOTTOM_LEFT = 'bottom-left';\nconst BOTTOM_RIGHT = 'bottom-right';\nconst MIDDLE_LEFT = 'middle-left';\nconst MIDDLE_RIGHT = 'middle-right';\nconst TOP_CENTER = 'top-center';\nconst TOP_LEFT = 'top-left';\nconst TOP_RIGHT = 'top-right';\n\nconst positions = {\n [BOTTOM_CENTER]: {\n attachment: 'top center',\n targetAttachment: 'bottom center',\n },\n [BOTTOM_LEFT]: {\n attachment: 'top right',\n targetAttachment: 'bottom right',\n },\n [BOTTOM_RIGHT]: {\n attachment: 'top left',\n targetAttachment: 'bottom left',\n },\n [MIDDLE_LEFT]: {\n attachment: 'middle right',\n targetAttachment: 'middle left',\n },\n [MIDDLE_RIGHT]: {\n attachment: 'middle left',\n targetAttachment: 'middle right',\n },\n [TOP_CENTER]: {\n attachment: 'bottom center',\n targetAttachment: 'top center',\n },\n [TOP_LEFT]: {\n attachment: 'bottom right',\n targetAttachment: 'top right',\n },\n [TOP_RIGHT]: {\n attachment: 'bottom left',\n targetAttachment: 'top left',\n },\n};\n\nconst OVERLAY_ROLE = 'dialog';\n\n/**\n * Checks if there is a clickable ancestor or self\n * @param {Node} rootNode The base node we should stop at\n * @param {Node} targetNode The target node of the event\n * @returns {boolean}\n */\nconst hasClickableAncestor = (rootNode, targetNode) => {\n // Check if the element or any of the ancestors are click-able (stopping at the component boundary)\n let currentNode = targetNode;\n while (currentNode && currentNode instanceof Node && currentNode.parentNode && currentNode !== rootNode) {\n const nodeName = currentNode.nodeName.toUpperCase();\n if (nodeName === 'A' || nodeName === 'BUTTON') {\n return true;\n }\n currentNode = currentNode.parentNode;\n }\n return false;\n};\n\n/**\n * Checks if the target element is inside an element with the given CSS class.\n * @param {HTMLElement} targetEl The target element\n * @param {string} className A CSS class on the element to check for\n */\nconst hasClassAncestor = (targetEl, className) => {\n let el = targetEl;\n while (el && el instanceof HTMLElement) {\n if (el.classList.contains(className)) {\n return true;\n }\n el = el.parentNode;\n }\n return false;\n};\n\nexport type FlyoutProps = {\n children: React.Node,\n /**\n * Set className to the overlay wrapper\n */\n className?: string,\n /**\n * If set to true, closes the overlay on clicking buttons/links inside\n * of it\n */\n closeOnClick?: boolean,\n /**\n * If set to true, closes the overlay on clicking outside of it\n */\n closeOnClickOutside?: boolean,\n /**\n * Function that will interrogate the click event to determine whether or not to close the overlay if closeOnClick is enabled\n */\n closeOnClickPredicate?: Function,\n /**\n * If set to true, closes the overlay when window loses focus\n */\n closeOnWindowBlur?: boolean,\n /**\n * Sets tether constrain to scrollParent\n */\n constrainToScrollParent?: boolean,\n /**\n * Sets tether constrain to window\n */\n constrainToWindow?: boolean,\n /**\n * Sets tether constrain to window with pin\n */\n constrainToWindowWithPin?: boolean,\n /**\n * Toggles responsive behavior\n */\n isResponsive?: boolean,\n /**\n * Whether overlay should be visible by default\n */\n isVisibleByDefault: boolean,\n /**\n * Will fire this callback when the flyout should open\n */\n offset?: string,\n /**\n * Will fire this callback when the flyout should close\n */\n onClose?: Function,\n /**\n * Adjusts placement of the overlay (SEE http://tether.io/#options)\n */\n onOpen?: Function,\n /**\n * Whether overlay should open on hover\n */\n openOnHover?: boolean,\n /**\n * Time in milliseconds that the button should wait before opening and closing the flyout\n */\n openOnHoverDelayTimeout?: number,\n /** An array of CSS classes for portaled elements in the overlay, used to check whether a click is inside the overlay */\n portaledClasses: Array<string>,\n /**\n * Position of the overlay\n */\n position:\n | 'bottom-center'\n | 'bottom-left'\n | 'bottom-right'\n | 'middle-left'\n | 'middle-right'\n | 'top-center'\n | 'top-left'\n | 'top-right',\n /**\n * Prop whether to focus first focusable element or not\n */\n shouldDefaultFocus?: boolean,\n};\n\ntype State = {\n isButtonClicked: boolean,\n isVisible: boolean,\n};\n\ntype Props = FlyoutProps;\n\nclass Flyout extends React.Component<Props, State> {\n static defaultProps = {\n className: '',\n closeOnClick: true,\n closeOnClickOutside: true,\n closeOnWindowBlur: false,\n constrainToScrollParent: true,\n constrainToWindow: false,\n isResponsive: false,\n isVisibleByDefault: false,\n openOnHover: false,\n openOnHoverDelayTimeout: 300,\n portaledClasses: [],\n position: BOTTOM_RIGHT,\n };\n\n constructor(props: Props) {\n super(props);\n\n this.overlayID = uniqueId('overlay');\n this.overlayButtonID = uniqueId('flyoutbutton');\n this.state = {\n isVisible: props.isVisibleByDefault,\n isButtonClicked: false,\n };\n }\n\n componentDidUpdate(prevProps: Props, prevState: State) {\n if (!prevState.isVisible && this.state.isVisible) {\n const { closeOnClickOutside, closeOnWindowBlur } = this.props;\n // When overlay is being opened\n if (closeOnClickOutside) {\n document.addEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n document.addEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n }\n if (closeOnWindowBlur) {\n window.addEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n } else if (prevState.isVisible && !this.state.isVisible) {\n // When overlay is being closed\n document.removeEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n document.removeEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n window.removeEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n }\n\n componentWillUnmount() {\n if (this.state.isVisible) {\n // Clean-up global click handlers\n document.removeEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n document.removeEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n window.removeEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n\n if (this.props.openOnHover && this.hoverDelay) {\n clearTimeout(this.hoverDelay);\n }\n }\n\n overlayButtonID: string;\n\n overlayID: string;\n\n handleOverlayClick = (event: SyntheticEvent<>) => {\n const overlayNode = document.getElementById(this.overlayID);\n const { closeOnClick, closeOnClickPredicate } = this.props;\n if (!closeOnClick || !hasClickableAncestor(overlayNode, event.target)) {\n return;\n }\n if (closeOnClickPredicate && !closeOnClickPredicate(event)) {\n return;\n }\n\n this.handleOverlayClose();\n };\n\n handleButtonClick = (event: SyntheticUIEvent<>) => {\n const { isVisible } = this.state;\n if (isVisible) {\n this.closeOverlay();\n } else {\n this.openOverlay();\n }\n\n // In at least one place, .click() is called programmatically\n // src/features/presence/Presence.js\n // In the programmatic case, the event is not supposed to trigger\n // autofocus of the content (TBD if this is truly correct behavior).\n // This line was using \"event.detail > 0\"\n // to detect if a click event was from a user, but that made keyboard\n // triggers of the button click behave differently than the mouse.\n // So, we use \"isTrusted\" instead. Note: React polyfills for IE11.\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted\n // https://reactjs.org/docs/events.html\n\n const isButtonClicked = event.isTrusted;\n\n this.setState({ isButtonClicked });\n\n event.preventDefault();\n };\n\n hoverDelay: TimeoutID | void;\n\n handleButtonHover = () => {\n const { openOnHover, openOnHoverDelayTimeout } = this.props;\n if (openOnHover) {\n clearTimeout(this.hoverDelay);\n this.hoverDelay = setTimeout(() => {\n this.openOverlay();\n }, openOnHoverDelayTimeout);\n }\n };\n\n handleButtonHoverLeave = () => {\n const { openOnHover, openOnHoverDelayTimeout } = this.props;\n if (openOnHover) {\n clearTimeout(this.hoverDelay);\n\n this.hoverDelay = setTimeout(() => {\n this.closeOverlay();\n }, openOnHoverDelayTimeout);\n }\n };\n\n handleKeyPress = () => {\n if (KEYS.enter) {\n this.openOverlay();\n this.focusButton();\n }\n };\n\n openOverlay = () => {\n this.setState({\n isVisible: true,\n });\n\n const { onOpen } = this.props;\n if (onOpen) {\n onOpen();\n }\n };\n\n closeOverlay = () => {\n this.setState({\n isVisible: false,\n });\n\n const { onClose } = this.props;\n if (onClose) {\n onClose();\n }\n };\n\n focusButton = () => {\n const buttonEl = document.getElementById(this.overlayButtonID);\n if (buttonEl) {\n buttonEl.focus();\n }\n };\n\n handleOverlayClose = () => {\n this.focusButton();\n this.closeOverlay();\n };\n\n handleDocumentClickOrWindowBlur = (event: MouseEvent | FocusEvent) => {\n const { portaledClasses, closeOnClickOutside, closeOnWindowBlur } = this.props;\n const { isVisible } = this.state;\n\n if (!isVisible || !(closeOnClickOutside || closeOnWindowBlur)) {\n return;\n }\n\n const overlayNode = document.getElementById(this.overlayID);\n const buttonNode = document.getElementById(this.overlayButtonID);\n\n const isInsideToggleButton =\n (buttonNode && event.target instanceof Node && buttonNode.contains(event.target)) ||\n buttonNode === event.target;\n const isInsideOverlay =\n (overlayNode && event.target instanceof Node && overlayNode.contains(event.target)) ||\n overlayNode === event.target;\n const isInside = isInsideToggleButton || isInsideOverlay;\n\n if (isInside || portaledClasses.some(className => hasClassAncestor(event.target, className))) {\n return;\n }\n\n // Only close overlay when the click is outside of the flyout or window loses focus\n this.closeOverlay();\n };\n\n render() {\n const {\n children,\n className = '',\n constrainToScrollParent,\n constrainToWindow,\n constrainToWindowWithPin,\n isResponsive,\n offset,\n openOnHover,\n position,\n shouldDefaultFocus,\n } = this.props;\n const { isButtonClicked, isVisible } = this.state;\n const elements = React.Children.toArray(children);\n const tetherPosition = positions[position];\n\n if (elements.length !== 2) {\n throw new Error('Flyout must have exactly two children: A button component and a <Overlay>');\n }\n\n const overlayButton = elements[0];\n const overlayContent = elements[1];\n\n const overlayButtonProps: Object = {\n id: this.overlayButtonID,\n key: this.overlayButtonID,\n onClick: this.handleButtonClick,\n onKeyPress: this.handleKeyPress,\n onMouseEnter: this.handleButtonHover,\n onMouseLeave: this.handleButtonHoverLeave,\n role: 'button',\n tabIndex: '0',\n 'aria-haspopup': OVERLAY_ROLE,\n 'aria-expanded': isVisible ? 'true' : 'false',\n };\n\n if (isVisible) {\n overlayButtonProps['aria-controls'] = this.overlayID;\n }\n\n const overlayProps = {\n id: this.overlayID,\n key: this.overlayID,\n role: OVERLAY_ROLE,\n onClick: this.handleOverlayClick,\n onClose: this.handleOverlayClose,\n onMouseEnter: this.handleButtonHover,\n onMouseLeave: this.handleButtonHoverLeave,\n shouldDefaultFocus: shouldDefaultFocus || (!isButtonClicked && !openOnHover),\n 'aria-labelledby': this.overlayButtonID,\n };\n\n const constraints = [];\n\n if (constrainToScrollParent) {\n constraints.push({\n to: 'scrollParent',\n attachment: 'together',\n });\n }\n\n if (constrainToWindow) {\n constraints.push({\n to: 'window',\n attachment: 'together',\n });\n }\n\n if (constrainToWindowWithPin) {\n constraints.push({\n to: 'window',\n attachment: 'together',\n pin: true,\n });\n }\n\n const tetherProps: Object = {\n classPrefix: 'flyout-overlay',\n attachment: tetherPosition.attachment,\n targetAttachment: tetherPosition.targetAttachment,\n enabled: isVisible,\n classes: {\n element: classNames('flyout-overlay', { 'bdl-Flyout--responsive': isResponsive }, className),\n },\n constraints,\n };\n\n if (offset) {\n tetherProps.offset = offset;\n } else {\n switch (position) {\n case BOTTOM_CENTER:\n case BOTTOM_LEFT:\n case BOTTOM_RIGHT:\n tetherProps.offset = '-10px 0';\n break;\n case TOP_CENTER:\n case TOP_LEFT:\n case TOP_RIGHT:\n tetherProps.offset = '10px 0';\n break;\n case MIDDLE_LEFT:\n tetherProps.offset = '0 10px';\n break;\n case MIDDLE_RIGHT:\n tetherProps.offset = '0 -10px';\n break;\n default:\n // no default\n }\n }\n\n return (\n <TetherComponent {...tetherProps}>\n {React.cloneElement(overlayButton, overlayButtonProps)}\n {isVisible && (\n <FlyoutContext.Provider value={{ closeOverlay: this.closeOverlay }}>\n {React.cloneElement(overlayContent, overlayProps)}\n </FlyoutContext.Provider>\n )}\n </TetherComponent>\n );\n }\n}\n\nexport default Flyout;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Flyout.js","names":["React","classNames","TetherComponent","uniqueId","KEYS","FlyoutContext","BOTTOM_CENTER","BOTTOM_LEFT","BOTTOM_RIGHT","MIDDLE_LEFT","MIDDLE_RIGHT","TOP_CENTER","TOP_LEFT","TOP_RIGHT","positions","attachment","targetAttachment","OVERLAY_ROLE","hasClickableAncestor","rootNode","targetNode","currentNode","Node","parentNode","nodeName","toUpperCase","hasClassAncestor","targetEl","className","el","HTMLElement","classList","contains","Flyout","Component","constructor","props","_defineProperty","event","overlayNode","document","getElementById","overlayID","closeOnClick","closeOnClickPredicate","target","handleOverlayClose","isVisible","state","closeOverlay","openOverlay","isButtonClicked","isTrusted","setState","preventDefault","openOnHover","openOnHoverDelayTimeout","clearTimeout","hoverDelay","setTimeout","key","enter","focusButton","onOpen","onClose","buttonEl","overlayButtonID","focus","portaledClasses","closeOnClickOutside","closeOnWindowBlur","buttonNode","isInsideToggleButton","isInsideOverlay","isInside","some","isVisibleByDefault","componentDidUpdate","prevProps","prevState","addEventListener","handleDocumentClickOrWindowBlur","window","removeEventListener","componentWillUnmount","render","children","constrainToScrollParent","constrainToWindow","constrainToWindowWithPin","isResponsive","offset","position","shouldDefaultFocus","elements","Children","toArray","tetherPosition","length","Error","overlayButton","overlayContent","overlayButtonProps","id","onClick","handleButtonClick","onKeyPress","handleKeyPress","onMouseEnter","handleButtonHover","onMouseLeave","handleButtonHoverLeave","role","tabIndex","overlayProps","handleOverlayClick","constraints","push","to","pin","tetherProps","classPrefix","enabled","classes","element","createElement","cloneElement","Provider","value"],"sources":["../../../src/components/flyout/Flyout.js"],"sourcesContent":["// @flow\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport TetherComponent from 'react-tether';\nimport uniqueId from 'lodash/uniqueId';\nimport { KEYS } from '../../constants';\n\nimport FlyoutContext from './FlyoutContext';\n\nimport './Flyout.scss';\n\nconst BOTTOM_CENTER = 'bottom-center';\nconst BOTTOM_LEFT = 'bottom-left';\nconst BOTTOM_RIGHT = 'bottom-right';\nconst MIDDLE_LEFT = 'middle-left';\nconst MIDDLE_RIGHT = 'middle-right';\nconst TOP_CENTER = 'top-center';\nconst TOP_LEFT = 'top-left';\nconst TOP_RIGHT = 'top-right';\n\nconst positions = {\n [BOTTOM_CENTER]: {\n attachment: 'top center',\n targetAttachment: 'bottom center',\n },\n [BOTTOM_LEFT]: {\n attachment: 'top right',\n targetAttachment: 'bottom right',\n },\n [BOTTOM_RIGHT]: {\n attachment: 'top left',\n targetAttachment: 'bottom left',\n },\n [MIDDLE_LEFT]: {\n attachment: 'middle right',\n targetAttachment: 'middle left',\n },\n [MIDDLE_RIGHT]: {\n attachment: 'middle left',\n targetAttachment: 'middle right',\n },\n [TOP_CENTER]: {\n attachment: 'bottom center',\n targetAttachment: 'top center',\n },\n [TOP_LEFT]: {\n attachment: 'bottom right',\n targetAttachment: 'top right',\n },\n [TOP_RIGHT]: {\n attachment: 'bottom left',\n targetAttachment: 'top left',\n },\n};\n\nconst OVERLAY_ROLE = 'dialog';\n\n/**\n * Checks if there is a clickable ancestor or self\n * @param {Node} rootNode The base node we should stop at\n * @param {Node} targetNode The target node of the event\n * @returns {boolean}\n */\nconst hasClickableAncestor = (rootNode, targetNode) => {\n // Check if the element or any of the ancestors are click-able (stopping at the component boundary)\n let currentNode = targetNode;\n while (currentNode && currentNode instanceof Node && currentNode.parentNode && currentNode !== rootNode) {\n const nodeName = currentNode.nodeName.toUpperCase();\n if (nodeName === 'A' || nodeName === 'BUTTON') {\n return true;\n }\n currentNode = currentNode.parentNode;\n }\n return false;\n};\n\n/**\n * Checks if the target element is inside an element with the given CSS class.\n * @param {HTMLElement} targetEl The target element\n * @param {string} className A CSS class on the element to check for\n */\nconst hasClassAncestor = (targetEl, className) => {\n let el = targetEl;\n while (el && el instanceof HTMLElement) {\n if (el.classList.contains(className)) {\n return true;\n }\n el = el.parentNode;\n }\n return false;\n};\n\nexport type FlyoutProps = {\n children: React.Node,\n /**\n * Set className to the overlay wrapper\n */\n className?: string,\n /**\n * If set to true, closes the overlay on clicking buttons/links inside\n * of it\n */\n closeOnClick?: boolean,\n /**\n * If set to true, closes the overlay on clicking outside of it\n */\n closeOnClickOutside?: boolean,\n /**\n * Function that will interrogate the click event to determine whether or not to close the overlay if closeOnClick is enabled\n */\n closeOnClickPredicate?: Function,\n /**\n * If set to true, closes the overlay when window loses focus\n */\n closeOnWindowBlur?: boolean,\n /**\n * Sets tether constrain to scrollParent\n */\n constrainToScrollParent?: boolean,\n /**\n * Sets tether constrain to window\n */\n constrainToWindow?: boolean,\n /**\n * Sets tether constrain to window with pin\n */\n constrainToWindowWithPin?: boolean,\n /**\n * Toggles responsive behavior\n */\n isResponsive?: boolean,\n /**\n * Whether overlay should be visible by default\n */\n isVisibleByDefault: boolean,\n /**\n * Will fire this callback when the flyout should open\n */\n offset?: string,\n /**\n * Will fire this callback when the flyout should close\n */\n onClose?: Function,\n /**\n * Adjusts placement of the overlay (SEE http://tether.io/#options)\n */\n onOpen?: Function,\n /**\n * Whether overlay should open on hover\n */\n openOnHover?: boolean,\n /**\n * Time in milliseconds that the button should wait before opening and closing the flyout\n */\n openOnHoverDelayTimeout?: number,\n /** An array of CSS classes for portaled elements in the overlay, used to check whether a click is inside the overlay */\n portaledClasses: Array<string>,\n /**\n * Position of the overlay\n */\n position:\n | 'bottom-center'\n | 'bottom-left'\n | 'bottom-right'\n | 'middle-left'\n | 'middle-right'\n | 'top-center'\n | 'top-left'\n | 'top-right',\n /**\n * Prop whether to focus first focusable element or not\n */\n shouldDefaultFocus?: boolean,\n};\n\ntype State = {\n isButtonClicked: boolean,\n isVisible: boolean,\n};\n\ntype Props = FlyoutProps;\n\nclass Flyout extends React.Component<Props, State> {\n static defaultProps = {\n className: '',\n closeOnClick: true,\n closeOnClickOutside: true,\n closeOnWindowBlur: false,\n constrainToScrollParent: true,\n constrainToWindow: false,\n isResponsive: false,\n isVisibleByDefault: false,\n openOnHover: false,\n openOnHoverDelayTimeout: 300,\n portaledClasses: [],\n position: BOTTOM_RIGHT,\n };\n\n constructor(props: Props) {\n super(props);\n\n this.overlayID = uniqueId('overlay');\n this.overlayButtonID = uniqueId('flyoutbutton');\n this.state = {\n isVisible: props.isVisibleByDefault,\n isButtonClicked: false,\n };\n }\n\n componentDidUpdate(prevProps: Props, prevState: State) {\n if (!prevState.isVisible && this.state.isVisible) {\n const { closeOnClickOutside, closeOnWindowBlur } = this.props;\n // When overlay is being opened\n if (closeOnClickOutside) {\n document.addEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n document.addEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n }\n if (closeOnWindowBlur) {\n window.addEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n } else if (prevState.isVisible && !this.state.isVisible) {\n // When overlay is being closed\n document.removeEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n document.removeEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n window.removeEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n }\n\n componentWillUnmount() {\n if (this.state.isVisible) {\n // Clean-up global click handlers\n document.removeEventListener('contextmenu', this.handleDocumentClickOrWindowBlur, true);\n document.removeEventListener('click', this.handleDocumentClickOrWindowBlur, true);\n window.removeEventListener('blur', this.handleDocumentClickOrWindowBlur, true);\n }\n\n if (this.props.openOnHover && this.hoverDelay) {\n clearTimeout(this.hoverDelay);\n }\n }\n\n overlayButtonID: string;\n\n overlayID: string;\n\n handleOverlayClick = (event: SyntheticEvent<>) => {\n const overlayNode = document.getElementById(this.overlayID);\n const { closeOnClick, closeOnClickPredicate } = this.props;\n if (!closeOnClick || !hasClickableAncestor(overlayNode, event.target)) {\n return;\n }\n if (closeOnClickPredicate && !closeOnClickPredicate(event)) {\n return;\n }\n\n this.handleOverlayClose();\n };\n\n handleButtonClick = (event: SyntheticUIEvent<>) => {\n const { isVisible } = this.state;\n if (isVisible) {\n this.closeOverlay();\n } else {\n this.openOverlay();\n }\n\n // In at least one place, .click() is called programmatically\n // src/features/presence/Presence.js\n // In the programmatic case, the event is not supposed to trigger\n // autofocus of the content (TBD if this is truly correct behavior).\n // This line was using \"event.detail > 0\"\n // to detect if a click event was from a user, but that made keyboard\n // triggers of the button click behave differently than the mouse.\n // So, we use \"isTrusted\" instead. Note: React polyfills for IE11.\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted\n // https://reactjs.org/docs/events.html\n\n const isButtonClicked = event.isTrusted;\n\n this.setState({ isButtonClicked });\n\n event.preventDefault();\n };\n\n hoverDelay: TimeoutID | void;\n\n handleButtonHover = () => {\n const { openOnHover, openOnHoverDelayTimeout } = this.props;\n if (openOnHover) {\n clearTimeout(this.hoverDelay);\n this.hoverDelay = setTimeout(() => {\n this.openOverlay();\n }, openOnHoverDelayTimeout);\n }\n };\n\n handleButtonHoverLeave = () => {\n const { openOnHover, openOnHoverDelayTimeout } = this.props;\n if (openOnHover) {\n clearTimeout(this.hoverDelay);\n\n this.hoverDelay = setTimeout(() => {\n this.closeOverlay();\n }, openOnHoverDelayTimeout);\n }\n };\n\n handleKeyPress = (event: SyntheticKeyboardEvent<>) => {\n if (event.key === KEYS.enter) {\n event.preventDefault();\n this.openOverlay();\n this.focusButton();\n }\n };\n\n openOverlay = () => {\n this.setState({\n isVisible: true,\n });\n\n const { onOpen } = this.props;\n if (onOpen) {\n onOpen();\n }\n };\n\n closeOverlay = () => {\n this.setState({\n isVisible: false,\n });\n\n const { onClose } = this.props;\n if (onClose) {\n onClose();\n }\n };\n\n focusButton = () => {\n const buttonEl = document.getElementById(this.overlayButtonID);\n if (buttonEl) {\n buttonEl.focus();\n }\n };\n\n handleOverlayClose = () => {\n this.focusButton();\n this.closeOverlay();\n };\n\n handleDocumentClickOrWindowBlur = (event: MouseEvent | FocusEvent) => {\n const { portaledClasses, closeOnClickOutside, closeOnWindowBlur } = this.props;\n const { isVisible } = this.state;\n\n if (!isVisible || !(closeOnClickOutside || closeOnWindowBlur)) {\n return;\n }\n\n const overlayNode = document.getElementById(this.overlayID);\n const buttonNode = document.getElementById(this.overlayButtonID);\n\n const isInsideToggleButton =\n (buttonNode && event.target instanceof Node && buttonNode.contains(event.target)) ||\n buttonNode === event.target;\n const isInsideOverlay =\n (overlayNode && event.target instanceof Node && overlayNode.contains(event.target)) ||\n overlayNode === event.target;\n const isInside = isInsideToggleButton || isInsideOverlay;\n\n if (isInside || portaledClasses.some(className => hasClassAncestor(event.target, className))) {\n return;\n }\n\n // Only close overlay when the click is outside of the flyout or window loses focus\n this.closeOverlay();\n };\n\n render() {\n const {\n children,\n className = '',\n constrainToScrollParent,\n constrainToWindow,\n constrainToWindowWithPin,\n isResponsive,\n offset,\n openOnHover,\n position,\n shouldDefaultFocus,\n } = this.props;\n const { isButtonClicked, isVisible } = this.state;\n const elements = React.Children.toArray(children);\n const tetherPosition = positions[position];\n\n if (elements.length !== 2) {\n throw new Error('Flyout must have exactly two children: A button component and a <Overlay>');\n }\n\n const overlayButton = elements[0];\n const overlayContent = elements[1];\n\n const overlayButtonProps: Object = {\n id: this.overlayButtonID,\n key: this.overlayButtonID,\n onClick: this.handleButtonClick,\n onKeyPress: this.handleKeyPress,\n onMouseEnter: this.handleButtonHover,\n onMouseLeave: this.handleButtonHoverLeave,\n role: 'button',\n tabIndex: '0',\n 'aria-haspopup': OVERLAY_ROLE,\n 'aria-expanded': isVisible ? 'true' : 'false',\n };\n\n if (isVisible) {\n overlayButtonProps['aria-controls'] = this.overlayID;\n }\n\n const overlayProps = {\n id: this.overlayID,\n key: this.overlayID,\n role: OVERLAY_ROLE,\n onClick: this.handleOverlayClick,\n onClose: this.handleOverlayClose,\n onMouseEnter: this.handleButtonHover,\n onMouseLeave: this.handleButtonHoverLeave,\n shouldDefaultFocus: shouldDefaultFocus || (!isButtonClicked && !openOnHover),\n 'aria-labelledby': this.overlayButtonID,\n };\n\n const constraints = [];\n\n if (constrainToScrollParent) {\n constraints.push({\n to: 'scrollParent',\n attachment: 'together',\n });\n }\n\n if (constrainToWindow) {\n constraints.push({\n to: 'window',\n attachment: 'together',\n });\n }\n\n if (constrainToWindowWithPin) {\n constraints.push({\n to: 'window',\n attachment: 'together',\n pin: true,\n });\n }\n\n const tetherProps: Object = {\n classPrefix: 'flyout-overlay',\n attachment: tetherPosition.attachment,\n targetAttachment: tetherPosition.targetAttachment,\n enabled: isVisible,\n classes: {\n element: classNames('flyout-overlay', { 'bdl-Flyout--responsive': isResponsive }, className),\n },\n constraints,\n };\n\n if (offset) {\n tetherProps.offset = offset;\n } else {\n switch (position) {\n case BOTTOM_CENTER:\n case BOTTOM_LEFT:\n case BOTTOM_RIGHT:\n tetherProps.offset = '-10px 0';\n break;\n case TOP_CENTER:\n case TOP_LEFT:\n case TOP_RIGHT:\n tetherProps.offset = '10px 0';\n break;\n case MIDDLE_LEFT:\n tetherProps.offset = '0 10px';\n break;\n case MIDDLE_RIGHT:\n tetherProps.offset = '0 -10px';\n break;\n default:\n // no default\n }\n }\n\n return (\n <TetherComponent {...tetherProps}>\n {React.cloneElement(overlayButton, overlayButtonProps)}\n {isVisible && (\n <FlyoutContext.Provider value={{ closeOverlay: this.closeOverlay }}>\n {React.cloneElement(overlayContent, overlayProps)}\n </FlyoutContext.Provider>\n )}\n </TetherComponent>\n );\n }\n}\n\nexport default Flyout;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -305,8 +305,9 @@ class Flyout extends React.Component<Props, State> {
|
|
|
305
305
|
}
|
|
306
306
|
};
|
|
307
307
|
|
|
308
|
-
handleKeyPress = () => {
|
|
309
|
-
if (KEYS.enter) {
|
|
308
|
+
handleKeyPress = (event: SyntheticKeyboardEvent<>) => {
|
|
309
|
+
if (event.key === KEYS.enter) {
|
|
310
|
+
event.preventDefault();
|
|
310
311
|
this.openOverlay();
|
|
311
312
|
this.focusButton();
|
|
312
313
|
}
|
|
@@ -336,10 +336,7 @@ describe('components/flyout/Flyout', () => {
|
|
|
336
336
|
if (shouldCloseOverlay) {
|
|
337
337
|
sandbox.mock(instance).expects('handleOverlayClose');
|
|
338
338
|
} else {
|
|
339
|
-
sandbox
|
|
340
|
-
.mock(instance)
|
|
341
|
-
.expects('handleOverlayClose')
|
|
342
|
-
.never();
|
|
339
|
+
sandbox.mock(instance).expects('handleOverlayClose').never();
|
|
343
340
|
}
|
|
344
341
|
act(() => {
|
|
345
342
|
instance.handleOverlayClick(event);
|
|
@@ -432,10 +429,7 @@ describe('components/flyout/Flyout', () => {
|
|
|
432
429
|
|
|
433
430
|
const instance = wrapper.instance();
|
|
434
431
|
setTimeout(() => {
|
|
435
|
-
sandbox
|
|
436
|
-
.mock(instance)
|
|
437
|
-
.expects('openOverlay')
|
|
438
|
-
.never();
|
|
432
|
+
sandbox.mock(instance).expects('openOverlay').never();
|
|
439
433
|
}, 310); // default timeout is 300ms
|
|
440
434
|
|
|
441
435
|
instance.handleButtonHover(event);
|
|
@@ -452,10 +446,7 @@ describe('components/flyout/Flyout', () => {
|
|
|
452
446
|
|
|
453
447
|
const instance = wrapper.instance();
|
|
454
448
|
setTimeout(() => {
|
|
455
|
-
sandbox
|
|
456
|
-
.mock(instance)
|
|
457
|
-
.expects('openOverlay')
|
|
458
|
-
.never();
|
|
449
|
+
sandbox.mock(instance).expects('openOverlay').never();
|
|
459
450
|
}, timeout - 10);
|
|
460
451
|
|
|
461
452
|
setTimeout(() => {
|
|
@@ -485,6 +476,32 @@ describe('components/flyout/Flyout', () => {
|
|
|
485
476
|
});
|
|
486
477
|
});
|
|
487
478
|
|
|
479
|
+
describe('handleKeyPress()', () => {
|
|
480
|
+
test('should call openOverlay() and focusButton() when enter key is pressed', () => {
|
|
481
|
+
const wrapper = shallow(
|
|
482
|
+
<Flyout>
|
|
483
|
+
<FakeButton />
|
|
484
|
+
<FakeOverlay />
|
|
485
|
+
</Flyout>,
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
const instance = wrapper.instance();
|
|
489
|
+
const openOverlaySpy = sandbox.spy(instance, 'openOverlay');
|
|
490
|
+
const focusButtonSpy = sandbox.spy(instance, 'focusButton');
|
|
491
|
+
|
|
492
|
+
const event = {
|
|
493
|
+
key: 'Enter',
|
|
494
|
+
preventDefault: sandbox.spy(),
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
instance.handleKeyPress(event);
|
|
498
|
+
|
|
499
|
+
expect(openOverlaySpy.calledOnce).toBe(true);
|
|
500
|
+
expect(focusButtonSpy.calledOnce).toBe(true);
|
|
501
|
+
expect(event.preventDefault.calledOnce).toBe(true);
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
|
|
488
505
|
describe('closeOverlay()', () => {
|
|
489
506
|
[
|
|
490
507
|
{
|
|
@@ -803,10 +820,7 @@ describe('components/flyout/Flyout', () => {
|
|
|
803
820
|
if (shouldCallCloseOverlay) {
|
|
804
821
|
sandbox.mock(instance).expects('closeOverlay');
|
|
805
822
|
} else {
|
|
806
|
-
sandbox
|
|
807
|
-
.mock(instance)
|
|
808
|
-
.expects('closeOverlay')
|
|
809
|
-
.never();
|
|
823
|
+
sandbox.mock(instance).expects('closeOverlay').never();
|
|
810
824
|
}
|
|
811
825
|
|
|
812
826
|
if (isInsideToggleButton) {
|
|
@@ -833,10 +847,7 @@ describe('components/flyout/Flyout', () => {
|
|
|
833
847
|
const el = document.createElement('div');
|
|
834
848
|
el.innerHTML = '<div class="class"><div class="target"></div></div>';
|
|
835
849
|
|
|
836
|
-
sandbox
|
|
837
|
-
.mock(instance)
|
|
838
|
-
.expects('closeOverlay')
|
|
839
|
-
.never();
|
|
850
|
+
sandbox.mock(instance).expects('closeOverlay').never();
|
|
840
851
|
|
|
841
852
|
instance.handleDocumentClickOrWindowBlur({
|
|
842
853
|
target: el.querySelector('.target'),
|