@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
255 lines (254 loc) • 8.15 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.HelpButtonInlineContent = void 0;
var _react = require("react");
var _clsx = require("clsx");
var _HelpButtonInstance = _interopRequireDefault(require("./HelpButtonInstance.js"));
var _HeightAnimation = _interopRequireDefault(require("../HeightAnimation.js"));
var _useSharedState = require("../../shared/helpers/useSharedState.js");
var _componentHelper = require("../../shared/component-helper.js");
var _useId = _interopRequireDefault(require("../../shared/helpers/useId.js"));
var _Section = _interopRequireDefault(require("../Section.js"));
var _index = require("../../elements/index.js");
var _Flex = _interopRequireDefault(require("../Flex.js"));
var _CardContext = _interopRequireDefault(require("../card/CardContext.js"));
var _Dialog = _interopRequireDefault(require("../Dialog.js"));
var _index2 = require("../../icons/index.js");
var _IconTransition = require("../icon/IconTransition.js");
var _IconPrimary = _interopRequireDefault(require("../icon-primary/IconPrimary.js"));
var _withComponentMarkers = _interopRequireDefault(require("../../shared/helpers/withComponentMarkers.js"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const helpButtonIcon = (0, _IconTransition.transition)({
question: _index2.question,
close: _index2.close
});
function HelpButtonInlineComponent(props) {
var _help$open;
const {
contentId,
size,
help,
focusOnOpen,
className,
children,
...rest
} = props;
const controlId = (0, _useId.default)(contentId);
const {
data,
update
} = (0, _useSharedState.useSharedState)(controlId, {
isOpen: (_help$open = help?.open) !== null && _help$open !== void 0 ? _help$open : false
});
const {
isOpen,
isUserIntent
} = data || {};
const wasOpenRef = (0, _react.useRef)(null);
const buttonRef = (0, _react.useRef)(null);
const toggleOpen = (0, _react.useCallback)(() => {
update({
isOpen: !isOpen,
isUserIntent: !isOpen,
buttonRef,
focusOnOpen
});
wasOpenRef.current = !isOpen;
}, [focusOnOpen, isOpen, update]);
if (isUserIntent === undefined && !isOpen) {
wasOpenRef.current = undefined;
}
const onClickHandler = (0, _react.useCallback)(({
event
}) => {
event.preventDefault();
toggleOpen();
}, [toggleOpen]);
const onKeyDownHandler = (0, _react.useCallback)(event => {
if (event.currentTarget === event.target) {
switch (event.key) {
case 'Escape':
if (isOpen) {
event.preventDefault();
event.stopPropagation();
window.requestAnimationFrame(() => {
toggleOpen();
});
}
break;
}
}
}, [isOpen, toggleOpen]);
const titleString = (0, _componentHelper.convertJsxToString)(help?.title);
return (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [(0, _jsxRuntime.jsx)(_HelpButtonInstance.default, {
bounding: true,
size: size !== null && size !== void 0 ? size : 'small',
icon: (0, _jsxRuntime.jsx)(_IconPrimary.default, {
icon: helpButtonIcon,
transitionState: isOpen ? 'close' : 'question'
}),
title: !isOpen && !wasOpenRef.current ? help?.title : undefined,
...rest,
id: controlId,
className: (0, _clsx.clsx)('dnb-help-button__inline', isUserIntent !== undefined && 'dnb-help-button__inline--user-intent', className),
selected: isOpen,
"aria-controls": `${controlId}-content`,
"aria-expanded": isOpen,
"aria-label": titleString || undefined,
onClick: onClickHandler,
onKeyDown: onKeyDownHandler,
ref: buttonRef
}), !contentId && (0, _jsxRuntime.jsx)(HelpButtonInlineContent, {
contentId: controlId,
help: help,
focusOnOpen: focusOnOpen,
children: children
})]
});
}
function HelpButtonInlineContentComponent(props) {
var _ref;
const {
contentId,
className,
element,
children,
help: helpProp,
breakout = true,
outset = false,
roundedCorner,
focusOnOpen: focusOnOpenProp,
...rest
} = props;
const {
data,
update,
extend
} = (0, _useSharedState.useSharedState)(contentId);
const {
isOpen,
focusOnOpen = focusOnOpenProp,
isUserIntent,
buttonRef
} = data || {};
const {
open,
title,
content,
renderAs,
noAnimation,
breakout: breakoutProp = true,
outset: outsetProp = true
} = helpProp || {};
const contentRef = (0, _react.useRef)(null);
const cardContext = (0, _react.useContext)(_CardContext.default);
const breakoutFromLayout = Boolean(cardContext) && breakout && breakoutProp;
const outsetFromLayout = outset && outsetProp;
(0, _react.useEffect)(() => {
if (isOpen && isUserIntent && focusOnOpen) {
window.requestAnimationFrame(() => {
contentRef.current?.focus({
preventScroll: true
});
});
}
}, [focusOnOpen, isOpen, isUserIntent]);
const onClose = (0, _react.useCallback)(() => {
update({
isOpen: false,
isUserIntent: false
});
}, [update]);
const onKeyDown = (0, _react.useCallback)(event => {
if (event.currentTarget === event.target) {
switch (event.key) {
case 'Enter':
case ' ':
case 'Escape':
event.preventDefault();
event.stopPropagation();
window.requestAnimationFrame(() => {
onClose();
buttonRef?.current?.focus({
preventScroll: true
});
});
break;
}
}
}, [buttonRef, onClose]);
const onAnimationEnd = (0, _react.useCallback)(() => {
extend({
isUserIntent: undefined
});
}, [extend]);
if (renderAs === 'dialog') {
return (0, _jsxRuntime.jsxs)(_Dialog.default, {
title: title,
omitTriggerButton: true,
open: isOpen !== null && isOpen !== void 0 ? isOpen : open,
onClose: onClose,
noAnimation: noAnimation,
children: [content, children]
});
}
const focusParams = focusOnOpen ? {
'aria-label': (0, _componentHelper.convertJsxToString)(title) || undefined,
className: 'dnb-no-focus',
tabIndex: -1,
onKeyDown
} : {
'aria-live': 'polite',
'aria-atomic': 'true'
};
return (0, _jsxRuntime.jsx)(_HeightAnimation.default, {
element: element,
className: (0, _clsx.clsx)('dnb-help-button__content', className),
open: (_ref = isOpen !== null && isOpen !== void 0 ? isOpen : open) !== null && _ref !== void 0 ? _ref : false,
onAnimationEnd: onAnimationEnd,
children: (0, _jsxRuntime.jsxs)(_Section.default, {
id: `${contentId}-content`,
...focusParams,
ref: contentRef,
outset: outsetFromLayout,
breakout: breakoutFromLayout,
roundedCorner: roundedCorner !== null && roundedCorner !== void 0 ? roundedCorner : !breakoutFromLayout,
innerSpace: breakoutFromLayout ? {
top: 'small',
bottom: 'medium'
} : {
top: 'small',
bottom: 'medium',
left: 'medium',
right: 'x-small'
},
...rest,
children: [(0, _jsxRuntime.jsxs)(_Flex.default.Vertical, {
gap: "x-small",
children: [title && (0, _jsxRuntime.jsx)(_index.P, {
weight: "medium",
element: "div",
children: title
}), content && (0, _jsxRuntime.jsx)(_index.P, {
element: "div",
children: content
})]
}), children]
})
});
}
const HelpButtonInline = (0, _react.memo)(HelpButtonInlineComponent);
var _default = exports.default = HelpButtonInline;
const HelpButtonInlineContent = exports.HelpButtonInlineContent = (0, _react.memo)(HelpButtonInlineContentComponent);
(0, _withComponentMarkers.default)(HelpButtonInline, {
_supportsSpacingProps: true
});
(0, _withComponentMarkers.default)(HelpButtonInlineContent, {
_supportsSpacingProps: true
});
//# sourceMappingURL=HelpButtonInline.js.map