@zendeskgarden/react-modals
Version:
Components relating to modals in the Garden Design System
1,141 lines (1,089 loc) • 43 kB
JavaScript
/**
* Copyright Zendesk, Inc.
*
* Use of this source code is governed under the Apache License, Version 2.0
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/
;
var React = require('react');
var ReactDOM = require('react-dom');
var styled = require('styled-components');
var PropTypes = require('prop-types');
var reactTheming = require('@zendeskgarden/react-theming');
var containerModal = require('@zendeskgarden/container-modal');
var reactMergeRefs = require('react-merge-refs');
var isWindow = require('dom-helpers/isWindow');
var ownerDocument = require('dom-helpers/ownerDocument');
var ownerWindow = require('dom-helpers/ownerWindow');
var css = require('dom-helpers/css');
var getScrollbarSize = require('dom-helpers/scrollbarSize');
var reactButtons = require('@zendeskgarden/react-buttons');
var reactTransitionGroup = require('react-transition-group');
var reactDom = require('@floating-ui/react-dom');
var activeElement = require('dom-helpers/activeElement');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespace(React);
var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
var styled__default = /*#__PURE__*/_interopDefault(styled);
var PropTypes__default = /*#__PURE__*/_interopDefault(PropTypes);
var isWindow__default = /*#__PURE__*/_interopDefault(isWindow);
var ownerDocument__default = /*#__PURE__*/_interopDefault(ownerDocument);
var ownerWindow__default = /*#__PURE__*/_interopDefault(ownerWindow);
var css__default = /*#__PURE__*/_interopDefault(css);
var getScrollbarSize__default = /*#__PURE__*/_interopDefault(getScrollbarSize);
var activeElement__default = /*#__PURE__*/_interopDefault(activeElement);
const COMPONENT_ID$j = 'modals.backdrop';
const animationName$1 = styled.keyframes(["0%{opacity:0;}100%{opacity:1;}"]);
const animationStyles$1 = props => {
if (props.$isAnimated) {
return styled.css(["animation:", " 0.15s ease-in;"], animationName$1);
}
return '';
};
const StyledBackdrop = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$j,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledBackdrop",
componentId: "sc-mzdjpo-0"
})(["display:flex;position:fixed;inset:0;align-items:", ";justify-content:", ";z-index:400;background-color:", ";overflow:auto;-webkit-overflow-scrolling:touch;font-family:", ";direction:", ";", ";", ";"], props => props.$isCentered && 'center', props => props.$isCentered && 'center', _ref => {
let {
theme
} = _ref;
return reactTheming.getColor({
theme,
hue: 'neutralHue',
transparency: theme.opacity[1000],
light: {
shade: 900
},
dark: {
shade: 1200
}
});
}, props => props.theme.fonts.system, props => props.theme.rtl && 'rtl', animationStyles$1, reactTheming.componentStyles);
StyledBackdrop.propTypes = {
$isCentered: PropTypes__default.default.bool,
$isAnimated: PropTypes__default.default.bool
};
const COMPONENT_ID$i = 'modals.body';
const StyledBody = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$i,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledBody",
componentId: "sc-14rzecg-0"
})(["display:block;margin:0;padding:", ";height:100%;overflow:auto;line-height:", ";color-scheme:only ", ";color:", ";font-size:", ";", ";"], props => `${props.theme.space.base * 5}px ${props.theme.space.base * 10}px`, props => reactTheming.getLineHeight(props.theme.lineHeights.md, props.theme.fontSizes.md), p => p.theme.colors.base, _ref => {
let {
theme
} = _ref;
return reactTheming.getColor({
theme,
variable: 'foreground.default'
});
}, props => props.theme.fontSizes.md, reactTheming.componentStyles);
const COMPONENT_ID$h = 'modals.close';
const BASE_MULTIPLIERS$1 = {
top: 2.5,
side: 6.5,
size: 10
};
const StyledClose = styled__default.default(reactButtons.IconButton).attrs({
'data-garden-id': COMPONENT_ID$h,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledClose",
componentId: "sc-iseudj-0"
})(["position:absolute;top:", "px;", ":", ";", ";"], props => props.theme.space.base * BASE_MULTIPLIERS$1.top, props => props.theme.rtl ? 'left' : 'right', props => `${props.theme.space.base * BASE_MULTIPLIERS$1.side}px`, reactTheming.componentStyles);
const COMPONENT_ID$g = 'modals.footer';
const StyledFooter = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$g,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledFooter",
componentId: "sc-d8pfdu-0"
})(["display:flex;flex-shrink:0;align-items:center;justify-content:flex-end;border-top:", ";padding:", ";", ";"], props => props.$isLarge && `${props.theme.borders.sm} ${reactTheming.getColor({
theme: props.theme,
variable: 'border.default'
})}`, props => props.$isLarge ? `${props.theme.space.base * 8}px ${props.theme.space.base * 10}px` : `${props.theme.space.base * 5}px ${props.theme.space.base * 10}px ${props.theme.space.base * 8}px`, reactTheming.componentStyles);
const COMPONENT_ID$f = 'modals.footer_item';
const StyledFooterItem = styled__default.default.span.attrs({
'data-garden-id': COMPONENT_ID$f,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledFooterItem",
componentId: "sc-1mb76hl-0"
})(["display:flex;margin-", ":", "px;min-width:0;&:first-child{margin-", ":0;}", ";"], props => props.theme.rtl ? 'right' : 'left', props => props.theme.space.base * 5, props => props.theme.rtl ? 'right' : 'left', reactTheming.componentStyles);
const COMPONENT_ID$e = 'modals.header';
const colorStyles$2 = _ref => {
let {
$isDanger,
theme
} = _ref;
const bottomBorderColor = reactTheming.getColor({
theme,
variable: 'border.subtle'
});
const color = reactTheming.getColor({
theme,
variable: $isDanger ? 'foreground.danger' : 'foreground.default'
});
return styled.css(["border-bottom-color:", ";color:", ";"], bottomBorderColor, color);
};
const StyledHeader = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$e,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledHeader",
componentId: "sc-1787r9v-0"
})(["display:block;position:", ";margin:0;border-bottom:", ";padding:", ";", " line-height:", ";font-size:", ";font-weight:", ";", ";", ";"], props => props.$isDanger && 'relative', props => props.theme.borders.sm, props => `${props.theme.space.base * 5}px ${props.theme.space.base * 10}px`, props => props.$isCloseButtonPresent && `padding-${props.theme.rtl ? 'left' : 'right'}: ${props.theme.space.base * (BASE_MULTIPLIERS$1.size + BASE_MULTIPLIERS$1.side + 2)}px;`, props => reactTheming.getLineHeight(props.theme.lineHeights.md, props.theme.fontSizes.md), props => props.theme.fontSizes.md, props => props.theme.fontWeights.semibold, colorStyles$2, reactTheming.componentStyles);
var _g, _circle;
function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
var SvgAlertErrorStroke = function SvgAlertErrorStroke(props) {
return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
xmlns: "http://www.w3.org/2000/svg",
width: 16,
height: 16,
focusable: "false",
viewBox: "0 0 16 16",
"aria-hidden": "true"
}, props), _g || (_g = /*#__PURE__*/React__namespace.createElement("g", {
fill: "none",
stroke: "currentColor"
}, /*#__PURE__*/React__namespace.createElement("circle", {
cx: 7.5,
cy: 8.5,
r: 7
}), /*#__PURE__*/React__namespace.createElement("path", {
strokeLinecap: "round",
d: "M7.5 4.5V9"
}))), _circle || (_circle = /*#__PURE__*/React__namespace.createElement("circle", {
cx: 7.5,
cy: 12,
r: 1,
fill: "currentColor"
})));
};
const StyledDangerIcon = styled__default.default(SvgAlertErrorStroke).withConfig({
displayName: "StyledDangerIcon",
componentId: "sc-1kwbb39-0"
})(["position:absolute;top:", "px;", ":", ";"], props => props.theme.space.base * 5.5, props => props.theme.rtl ? 'right' : 'left', props => `${props.theme.space.base * 4}px`);
const COMPONENT_ID$d = 'modals.modal';
const animationName = styled.keyframes(["0%{transform:scale(0);opacity:0;}50%{transform:scale(1.05);}100%{opacity:1;}"]);
const animationStyles = props => {
if (props.$isAnimated) {
return styled.css(["animation:", " 0.3s ease-in;"], animationName);
}
return '';
};
const colorStyles$1 = _ref => {
let {
theme
} = _ref;
const offsetY = `${theme.space.base * 5}px`;
const blurRadius = `${theme.space.base * 7}px`;
const shadowColor = reactTheming.getColor({
variable: 'shadow.large',
theme
});
const shadow = theme.shadows.lg(offsetY, blurRadius, shadowColor);
const borderColor = reactTheming.getColor({
theme,
variable: 'border.default'
});
const backgroundColor = reactTheming.getColor({
theme,
variable: 'background.raised'
});
return styled.css(["border-color:", ";box-shadow:", ";background-color:", ";"], borderColor, shadow, backgroundColor);
};
const sizeStyles$2 = props => {
return styled.css(["", "{width:", ";}"], reactTheming.mediaQuery('up', props.$isLarge ? 'md' : 'sm', props.theme), props.$isLarge ? props.theme.breakpoints.md : props.theme.breakpoints.sm);
};
const StyledModal = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$d,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledModal",
componentId: "sc-1pe1axu-0"
})(["display:flex;position:fixed;flex-direction:column;animation-delay:0.01s;margin:", ";border:", ";border-radius:", ";min-height:60px;max-height:calc(100vh - ", "px);overflow:auto;direction:", ";", ";", ";", ";&:focus{outline:none;}@media (max-height:399px){top:", "px;bottom:auto;margin-bottom:", "px;max-height:calc(100vh - ", "px);}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){right:", ";bottom:", ";transform:", ";}", ";"], props => props.$isCentered ? '0' : `${props.theme.space.base * 12}px`, props => props.theme.borders.sm, props => props.theme.borderRadii.md, props => props.theme.space.base * 24, props => props.theme.rtl && 'rtl', animationStyles, sizeStyles$2, colorStyles$1, props => props.theme.space.base * 6, props => props.theme.space.base * 6, props => props.theme.space.base * 12, props => props.$isCentered && '50%', props => props.$isCentered && '50%', props => props.$isCentered && 'translate(50%, 50%)', reactTheming.componentStyles);
StyledModal.propTypes = {
$isLarge: PropTypes__default.default.bool,
$isAnimated: PropTypes__default.default.bool
};
const COMPONENT_ID$c = 'modals.tooltip_dialog.backdrop';
const StyledTooltipDialogBackdrop = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$c,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogBackdrop",
componentId: "sc-zrk625-0"
})(["position:fixed;inset:0;z-index:400;overflow:hidden;-webkit-overflow-scrolling:touch;font-family:", ";direction:", ";&.garden-tooltip-modal-transition-exit-active{pointer-events:none;}&.garden-tooltip-modal-transition-exit-active div{transition:opacity 200ms;opacity:0;}", ";"], props => props.theme.fonts.system, props => props.theme.rtl && 'rtl', reactTheming.componentStyles);
const StyledTooltipWrapper = styled__default.default.div.attrs(props => ({
className: props.$isAnimated ? 'is-animated' : undefined
})).withConfig({
displayName: "StyledTooltipWrapper",
componentId: "sc-1xk05kf-0"
})(["top:0;left:0;", ";"], props => reactTheming.menuStyles(reactTheming.getMenuPosition(props.$placement), {
theme: props.theme,
hidden: false,
zIndex: props.$zIndex,
animationModifier: '.is-animated'
}));
const COMPONENT_ID$b = 'modals.tooltip_dialog.close';
const StyledTooltipDialogClose = styled__default.default(StyledClose).attrs({
'data-garden-id': COMPONENT_ID$b,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogClose",
componentId: "sc-18xlgfi-0"
})(["top:", "px;", ":", ";", ";"], props => props.theme.space.base * 3.5, props => props.theme.rtl ? 'left' : 'right', props => `${props.theme.space.base * 3}px`, reactTheming.componentStyles);
const COMPONENT_ID$a = 'modals.tooltip_dialog';
const sizeStyles$1 = props => `
padding: ${props.theme.space.base * 5}px;
width: 400px;
&:has(${StyledTooltipDialogClose}) > :first-child {
padding-${props.theme.rtl ? 'left' : 'right'}: ${props.theme.space.base * 8}px;
}
`;
const StyledTooltipDialog = styled__default.default.div.attrs(props => ({
'data-garden-id': COMPONENT_ID$a,
'data-garden-version': '9.11.3',
className: props.$isAnimated ? 'is-animated' : undefined
})).withConfig({
displayName: "StyledTooltipDialog",
componentId: "sc-iv3db-0"
})(["", ";", " ", ";"], props => {
const computedArrowStyles = reactTheming.arrowStyles(reactTheming.getArrowPosition(props.theme, props.$placement), {
size: `${props.theme.space.base * 2}px`,
inset: '1px',
animationModifier: '.is-animated'
});
if (props.$isAnimated) {
return props.$hasArrow && props.$transitionState === 'entered' && computedArrowStyles;
}
return props.$hasArrow && computedArrowStyles;
}, sizeStyles$1, reactTheming.componentStyles);
const COMPONENT_ID$9 = 'modals.tooltip_dialog.title';
const sizeStyles = props => `
/* stylelint-disable-next-line property-no-unknown */
line-height: ${reactTheming.getLineHeight(props.theme.lineHeights.md, props.theme.fontSizes.md)};
font-size: ${props.theme.fontSizes.md};
`;
const StyledTooltipDialogTitle = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$9,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogTitle",
componentId: "sc-1rceixg-0"
})(["margin:0;color:", ";font-weight:", ";", ";", ";"], _ref => {
let {
theme
} = _ref;
return reactTheming.getColor({
variable: 'foreground.default',
theme
});
}, props => props.theme.fontWeights.semibold, props => sizeStyles(props), reactTheming.componentStyles);
const COMPONENT_ID$8 = 'modals.tooltip_dialog.body';
const StyledTooltipDialogBody = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$8,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogBody",
componentId: "sc-132lcoq-0"
})(["display:block;margin:0;padding-top:", "px;line-height:", ";color-scheme:only ", ";color:", ";font-size:", ";", ";"], props => props.theme.space.base * 1.5, props => reactTheming.getLineHeight(props.theme.lineHeights.md, props.theme.fontSizes.md), p => p.theme.colors.base, _ref => {
let {
theme
} = _ref;
return reactTheming.getColor({
variable: 'foreground.default',
theme
});
}, props => props.theme.fontSizes.md, reactTheming.componentStyles);
const COMPONENT_ID$7 = 'modals.tooltip_dialog.footer';
const StyledTooltipDialogFooter = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$7,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogFooter",
componentId: "sc-kjomsm-0"
})(["display:flex;flex-shrink:0;align-items:center;justify-content:flex-end;padding-top:", "px;", ";"], p => p.theme.space.base * 5, reactTheming.componentStyles);
const COMPONENT_ID$6 = 'modals.tooltip_dialog.footer_item';
const StyledTooltipDialogFooterItem = styled__default.default(StyledFooterItem).attrs({
'data-garden-id': COMPONENT_ID$6,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledTooltipDialogFooterItem",
componentId: "sc-u2rmo8-0"
})(["", ";"], reactTheming.componentStyles);
const COMPONENT_ID$5 = 'modals.drawer_modal';
const DRAWER_WIDTH = 380;
const colorStyles = _ref => {
let {
theme
} = _ref;
const offsetY = `${theme.space.base * 5}px`;
const blurRadius = `${theme.space.base * 7}px`;
const shadowColor = reactTheming.getColor({
variable: 'shadow.large',
theme
});
const shadow = theme.shadows.lg(offsetY, blurRadius, shadowColor);
const borderColor = reactTheming.getColor({
theme,
variable: 'border.default'
});
const backgroundColor = reactTheming.getColor({
theme,
variable: 'background.raised'
});
return styled.css(["border-color:", ";box-shadow:", ";background-color:", ";"], borderColor, shadow, backgroundColor);
};
const StyledDrawer = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$5,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawer",
componentId: "sc-zp66t3-0"
})(["display:flex;position:fixed;top:0;", ":0;flex-direction:column;z-index:500;", ":", ";width:", "px;height:100%;overflow:auto;-webkit-overflow-scrolling:touch;font-family:", ";direction:", ";&.garden-drawer-transition-enter{transform:translateX(", "px);}&.garden-drawer-transition-enter-active{transform:translateX(0);transition:transform 0.25s ease-in-out;}&.garden-drawer-transition-exit-active{transform:translateX(", "px);transition:transform 0.25s ease-in-out;}&:focus{outline:none;}", " ", ";"], props => props.theme.rtl ? 'left' : 'right', props => props.theme.rtl ? 'border-right' : 'border-left', props => props.theme.borders.sm, DRAWER_WIDTH, props => props.theme.fonts.system, props => props.theme.rtl && 'rtl', props => props.theme.rtl ? -DRAWER_WIDTH : DRAWER_WIDTH, props => props.theme.rtl ? -DRAWER_WIDTH : DRAWER_WIDTH, colorStyles, reactTheming.componentStyles);
const COMPONENT_ID$4 = 'modals.drawer_modal.close';
const BASE_MULTIPLIERS = {
top: BASE_MULTIPLIERS$1.top,
side: 2,
size: BASE_MULTIPLIERS$1.size
};
const StyledDrawerClose = styled__default.default(StyledClose).attrs({
'data-garden-id': COMPONENT_ID$4,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawerClose",
componentId: "sc-1a0xt3x-0"
})(["", ":", ";", ";"], props => props.theme.rtl ? 'left' : 'right', props => `${props.theme.space.base * BASE_MULTIPLIERS.side}px`, reactTheming.componentStyles);
const COMPONENT_ID$3 = 'modals.drawer_modal.header';
const StyledDrawerHeader = styled__default.default(StyledHeader).attrs({
'data-garden-id': COMPONENT_ID$3,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawerHeader",
componentId: "sc-y4mgkj-0"
})(["padding:", "px;", " ", ";"], props => props.theme.space.base * 5, props => props.$isCloseButtonPresent && `padding-${props.theme.rtl ? 'left' : 'right'}: ${props.theme.space.base * (BASE_MULTIPLIERS.size + BASE_MULTIPLIERS.side + 2)}px;`, reactTheming.componentStyles);
const COMPONENT_ID$2 = 'modals.drawer_modal.body';
const StyledDrawerBody = styled__default.default(StyledBody).attrs({
'data-garden-id': COMPONENT_ID$2,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawerBody",
componentId: "sc-13qufyn-0"
})(["padding:", "px;color-scheme:only ", ";", ";"], props => props.theme.space.base * 5, p => p.theme.colors.base, reactTheming.componentStyles);
const COMPONENT_ID$1 = 'modals.drawer_modal.footer';
const StyledDrawerFooter = styled__default.default.div.attrs({
'data-garden-id': COMPONENT_ID$1,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawerFooter",
componentId: "sc-kc7e6p-0"
})(["display:flex;flex-shrink:0;justify-content:flex-end;border-top:", ";padding:", "px;", ";"], _ref => {
let {
theme
} = _ref;
return `${theme.borders.sm} ${reactTheming.getColor({
theme,
variable: 'border.subtle'
})}`;
}, props => props.theme.space.base * 5, reactTheming.componentStyles);
const COMPONENT_ID = 'modals.drawer_modal.footer_item';
const StyledDrawerFooterItem = styled__default.default(StyledFooterItem).attrs({
'data-garden-id': COMPONENT_ID,
'data-garden-version': '9.11.3'
}).withConfig({
displayName: "StyledDrawerFooterItem",
componentId: "sc-m2yul4-0"
})(["", ";"], reactTheming.componentStyles);
const ModalsContext = React.createContext(undefined);
const useModalContext = () => {
const context = React.useContext(ModalsContext);
if (context === undefined) {
throw new Error('useModalContext must be used within a ModalsContext.Provider');
}
return context;
};
const Body$2 = React.forwardRef((props, ref) => {
const {
getContentProps
} = useModalContext();
return React__namespace.default.createElement(StyledBody, Object.assign({}, getContentProps(props), {
ref: ref
}));
});
Body$2.displayName = 'Modal.Body';
var _path;
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
var SvgXStroke = function SvgXStroke(props) {
return /*#__PURE__*/React__namespace.createElement("svg", _extends({
xmlns: "http://www.w3.org/2000/svg",
width: 16,
height: 16,
focusable: "false",
viewBox: "0 0 16 16",
"aria-hidden": "true"
}, props), _path || (_path = /*#__PURE__*/React__namespace.createElement("path", {
stroke: "currentColor",
strokeLinecap: "round",
d: "M3 13L13 3m0 10L3 3"
})));
};
const Close$2 = React.forwardRef((props, ref) => {
const {
getCloseProps,
setIsCloseButtonPresent
} = useModalContext();
React.useEffect(() => {
setIsCloseButtonPresent(true);
return () => setIsCloseButtonPresent(false);
});
const ariaLabel = reactTheming.useText(Close$2, props, 'aria-label', 'Close modal', props['aria-describedby'] === undefined );
return React__namespace.default.createElement(StyledClose, Object.assign({}, getCloseProps({
...props,
'aria-label': ariaLabel
}), {
ref: ref
}), React__namespace.default.createElement(SvgXStroke, null));
});
Close$2.displayName = 'Modal.Close';
const Footer$2 = React__namespace.default.forwardRef((props, ref) => {
const {
isLarge
} = useModalContext();
return React__namespace.default.createElement(StyledFooter, Object.assign({
ref: ref,
$isLarge: isLarge
}, props));
});
Footer$2.displayName = 'Modal.Footer';
const FooterItem$2 = React__namespace.default.forwardRef((props, ref) => React__namespace.default.createElement(StyledFooterItem, Object.assign({
ref: ref
}, props)));
FooterItem$2.displayName = 'Modal.FooterItem';
const Header$1 = React.forwardRef((_ref, ref) => {
let {
children,
isDanger,
tag = 'div',
...other
} = _ref;
const {
isCloseButtonPresent,
hasHeader,
setHasHeader,
getTitleProps
} = useModalContext();
React.useEffect(() => {
if (!hasHeader && setHasHeader) {
setHasHeader(true);
}
return () => {
if (hasHeader && setHasHeader) {
setHasHeader(false);
}
};
}, [hasHeader, setHasHeader]);
return React__namespace.default.createElement(StyledHeader, Object.assign({}, getTitleProps(other), {
as: tag,
$isCloseButtonPresent: isCloseButtonPresent,
$isDanger: isDanger,
ref: ref
}), !!isDanger && React__namespace.default.createElement(StyledDangerIcon, null), children);
});
Header$1.displayName = 'Modal.Header';
Header$1.propTypes = {
isDanger: PropTypes__default.default.bool,
tag: PropTypes__default.default.any
};
const isOverflowing = element => {
const doc = ownerDocument__default.default(element);
const win = ownerWindow__default.default(doc);
const isBody = element && element.tagName.toLowerCase() === 'body';
if (!isWindow__default.default(doc) && !isBody) {
return element.scrollHeight > element.clientHeight;
}
const style = win.getComputedStyle(doc.body);
const marginLeft = parseInt(style.getPropertyValue('margin-left'), 10);
const marginRight = parseInt(style.getPropertyValue('margin-right'), 10);
return marginLeft + doc.body.clientWidth + marginRight < win.innerWidth;
};
const ModalComponent = React.forwardRef((_ref, ref) => {
let {
backdropProps,
children,
onClose,
isLarge,
isCentered = true,
isAnimated = true,
id,
appendToNode,
focusOnMount,
restoreFocus,
...modalProps
} = _ref;
const theme = React.useContext(styled.ThemeContext);
const modalRef = React.useRef(null);
const environment = reactTheming.useDocument(theme);
const [isCloseButtonPresent, setIsCloseButtonPresent] = React.useState(false);
const [hasHeader, setHasHeader] = React.useState(false);
const {
getBackdropProps,
getModalProps,
getTitleProps,
getContentProps,
getCloseProps
} = containerModal.useModal({
idPrefix: id,
onClose,
modalRef,
focusOnMount,
restoreFocus
});
React.useEffect(() => {
if (!environment) {
return undefined;
}
const htmlElement = environment.querySelector('html');
const bodyElement = environment.querySelector('body');
let previousHtmlOverflow;
let previousBodyPaddingRight;
if (bodyElement) {
if (isOverflowing(bodyElement)) {
const scrollbarSize = getScrollbarSize__default.default();
const bodyPaddingRight = parseInt(css__default.default(bodyElement, 'paddingRight') || '0', 10);
previousBodyPaddingRight = bodyElement.style.paddingRight;
bodyElement.style.paddingRight = `${bodyPaddingRight + scrollbarSize}px`;
}
if (htmlElement) {
previousHtmlOverflow = htmlElement.style.overflow;
htmlElement.style.overflow = 'hidden';
}
return () => {
if (htmlElement) {
htmlElement.style.overflow = previousHtmlOverflow;
}
bodyElement.style.paddingRight = previousBodyPaddingRight;
};
}
return undefined;
}, [environment]);
const rootNode = React.useMemo(() => {
if (appendToNode) {
return appendToNode;
}
if (environment) {
return environment.body;
}
return undefined;
}, [appendToNode, environment]);
const value = React.useMemo(() => ({
isLarge,
isCloseButtonPresent,
hasHeader,
setHasHeader,
getTitleProps,
getContentProps,
getCloseProps,
setIsCloseButtonPresent
}), [isLarge, hasHeader, isCloseButtonPresent, getTitleProps, getContentProps, getCloseProps]);
const modalContainerProps = getModalProps({
'aria-describedby': undefined,
...(hasHeader ? {} : {
'aria-labelledby': undefined
})
});
const attribute = hasHeader ? 'aria-labelledby' : 'aria-label';
const defaultValue = hasHeader ? modalContainerProps['aria-labelledby'] : 'Modal dialog';
const labelValue = hasHeader ? modalContainerProps['aria-labelledby'] : modalProps['aria-label'];
const ariaProps = {
[attribute]: reactTheming.useText(ModalComponent, {
[attribute]: labelValue
}, attribute, defaultValue, modalRef.current !== null )
};
if (!rootNode) {
return null;
}
return ReactDOM.createPortal(React__namespace.default.createElement(ModalsContext.Provider, {
value: value
}, React__namespace.default.createElement(StyledBackdrop, Object.assign({
$isCentered: isCentered,
$isAnimated: isAnimated
}, getBackdropProps(backdropProps)), React__namespace.default.createElement(StyledModal, Object.assign({
$isCentered: isCentered,
$isAnimated: isAnimated,
$isLarge: isLarge
}, modalContainerProps, ariaProps, modalProps, {
ref: reactMergeRefs.mergeRefs([ref, modalRef])
}), children))), rootNode);
});
ModalComponent.displayName = 'Modal';
ModalComponent.propTypes = {
backdropProps: PropTypes__default.default.object,
isLarge: PropTypes__default.default.bool,
isAnimated: PropTypes__default.default.bool,
isCentered: PropTypes__default.default.bool,
focusOnMount: PropTypes__default.default.bool,
restoreFocus: PropTypes__default.default.bool,
onClose: PropTypes__default.default.func,
appendToNode: PropTypes__default.default.any
};
const Modal = ModalComponent;
Modal.Body = Body$2;
Modal.Close = Close$2;
Modal.Footer = Footer$2;
Modal.FooterItem = FooterItem$2;
Modal.Header = Header$1;
const TooltipDialogContext = React.createContext(undefined);
const useTooltipDialogContext = () => {
const context = React.useContext(TooltipDialogContext);
if (context === undefined) {
throw new Error('Element must be used within a TooltipDialog component.');
}
return context;
};
const PLACEMENT = ['auto', ...reactTheming.PLACEMENT];
const TitleComponent = React.forwardRef((_ref, ref) => {
let {
children,
tag = 'div',
...other
} = _ref;
const {
getTitleProps,
hasTitle,
setHasTitle
} = useTooltipDialogContext();
React.useEffect(() => {
if (!hasTitle && setHasTitle) {
setHasTitle(true);
}
return () => {
if (hasTitle && setHasTitle) {
setHasTitle(false);
}
};
}, [hasTitle, setHasTitle]);
return React__namespace.default.createElement(StyledTooltipDialogTitle, Object.assign({}, getTitleProps(other), {
as: tag,
ref: ref
}), children);
});
TitleComponent.displayName = 'TooltipDialog.Title';
TitleComponent.propTypes = {
tag: PropTypes__default.default.any
};
const Title = TitleComponent;
const BodyComponent$1 = React.forwardRef((props, ref) => {
const {
getContentProps
} = useTooltipDialogContext();
return React__namespace.default.createElement(StyledTooltipDialogBody, Object.assign({}, getContentProps(props), {
ref: ref
}));
});
BodyComponent$1.displayName = 'TooltipDialog.Body';
const Body$1 = BodyComponent$1;
const CloseComponent$1 = React.forwardRef((props, ref) => {
const {
getCloseProps
} = useTooltipDialogContext();
const ariaLabel = reactTheming.useText(CloseComponent$1, props, 'aria-label', 'Close tooltip', props['aria-describedby'] === undefined );
return React__namespace.default.createElement(StyledTooltipDialogClose, Object.assign({}, getCloseProps({
...props,
'aria-label': ariaLabel
}), {
ref: ref,
size: "small"
}), React__namespace.default.createElement(SvgXStroke, null));
});
CloseComponent$1.displayName = 'TooltipDialog.Close';
const Close$1 = CloseComponent$1;
const FooterComponent$1 = React.forwardRef((props, ref) => React__namespace.default.createElement(StyledTooltipDialogFooter, Object.assign({
ref: ref
}, props)));
FooterComponent$1.displayName = 'TooltipDialog.Footer';
const Footer$1 = FooterComponent$1;
const FooterItemComponent$1 = React.forwardRef((props, ref) => React__namespace.default.createElement(StyledTooltipDialogFooterItem, Object.assign({
ref: ref
}, props)));
FooterItemComponent$1.displayName = 'TooltipDialog.FooterItem';
const FooterItem$1 = FooterItemComponent$1;
const PLACEMENT_DEFAULT = 'top';
const TooltipDialogComponent = React__namespace.default.forwardRef((_ref, ref) => {
let {
appendToNode,
referenceElement,
placement: _placement = 'auto',
fallbackPlacements: _fallbackPlacements,
offset: _offset,
onClose,
hasArrow = true,
isAnimated,
zIndex,
backdropProps,
focusOnMount = true,
restoreFocus = true,
id,
...props
} = _ref;
const theme = React.useContext(styled.ThemeContext) || reactTheming.DEFAULT_THEME;
const previousReferenceElementRef = React.useRef();
const modalRef = React.useRef(null);
const transitionRef = React.useRef(null);
const [floatingElement, setFloatingElement] = React.useState();
const [hasTitle, setHasTitle] = React.useState(false);
const {
getTitleProps,
getCloseProps,
getContentProps,
getBackdropProps,
getModalProps
} = containerModal.useModal({
idPrefix: id,
onClose,
modalRef,
focusOnMount,
restoreFocus: false
});
const [floatingPlacement, fallbackPlacements] = reactTheming.getFloatingPlacements(theme, _placement === 'auto' ? PLACEMENT_DEFAULT : _placement, _fallbackPlacements);
const {
refs,
placement,
update,
floatingStyles: {
transform
}
} = reactDom.useFloating({
platform: {
...reactDom.platform,
isRTL: () => theme.rtl
},
elements: {
reference: referenceElement,
floating: floatingElement
},
placement: floatingPlacement,
middleware: [reactDom.offset(_offset === undefined ? theme.space.base * 3 : _offset), _placement === 'auto' ? reactDom.autoPlacement() : reactDom.flip({
fallbackPlacements
})]
});
React.useEffect(() => {
let cleanup;
if (referenceElement && floatingElement && refs.reference.current && refs.floating.current) {
cleanup = reactDom.autoUpdate(refs.reference.current, refs.floating.current, update, {
elementResize: typeof ResizeObserver === 'function'
});
}
return () => cleanup && cleanup();
}, [referenceElement, floatingElement, refs.reference, refs.floating, update]);
React.useEffect(() => {
if (!referenceElement && previousReferenceElementRef.current && restoreFocus) {
previousReferenceElementRef.current.focus();
}
previousReferenceElementRef.current = referenceElement;
}, [referenceElement, restoreFocus]);
const modalProps = getModalProps({
'aria-describedby': undefined,
...(hasTitle ? {} : {
'aria-labelledby': undefined
})
});
const attribute = hasTitle ? 'aria-labelledby' : 'aria-label';
const defaultValue = hasTitle ? modalProps['aria-labelledby'] : 'Modal dialog';
const labelValue = hasTitle ? modalProps['aria-labelledby'] : props['aria-label'];
const ariaProps = {
[attribute]: reactTheming.useText(TooltipDialogComponent, {
[attribute]: labelValue
}, attribute, defaultValue, modalRef.current !== null )
};
const value = {
hasTitle,
setHasTitle,
getTitleProps,
getContentProps,
getCloseProps
};
const Node = React__namespace.default.createElement(reactTransitionGroup.CSSTransition, {
unmountOnExit: true,
timeout: isAnimated ? 200 : 0,
in: Boolean(referenceElement),
classNames: isAnimated ? 'garden-tooltip-modal-transition' : '',
nodeRef: transitionRef
}, transitionState => {
return React__namespace.default.createElement(TooltipDialogContext.Provider, {
value: value
}, React__namespace.default.createElement(StyledTooltipDialogBackdrop, Object.assign({}, getBackdropProps(), backdropProps, {
ref: transitionRef
}), React__namespace.default.createElement(StyledTooltipWrapper, {
ref: setFloatingElement,
style: {
transform
},
$placement: placement,
$zIndex: zIndex,
$isAnimated: isAnimated
}, React__namespace.default.createElement(StyledTooltipDialog, Object.assign({
$transitionState: transitionState,
$placement: placement,
$hasArrow: hasArrow,
$isAnimated: isAnimated
}, modalProps, ariaProps, props, {
ref: reactMergeRefs.mergeRefs([modalRef, ref])
})))));
});
return appendToNode ? ReactDOM.createPortal(Node, appendToNode) : Node;
});
TooltipDialogComponent.displayName = 'TooltipDialog';
TooltipDialogComponent.propTypes = {
appendToNode: PropTypes__default.default.any,
referenceElement: PropTypes__default.default.any,
placement: PropTypes__default.default.any,
fallbackPlacements: PropTypes__default.default.arrayOf(PropTypes__default.default.oneOf(PLACEMENT.filter(placement => placement !== 'auto'))),
isAnimated: PropTypes__default.default.bool,
hasArrow: PropTypes__default.default.bool,
zIndex: PropTypes__default.default.number,
onClose: PropTypes__default.default.func,
backdropProps: PropTypes__default.default.any,
focusOnMount: PropTypes__default.default.bool,
restoreFocus: PropTypes__default.default.bool
};
const TooltipDialog = TooltipDialogComponent;
TooltipDialog.Body = Body$1;
TooltipDialog.Close = Close$1;
TooltipDialog.Footer = Footer$1;
TooltipDialog.FooterItem = FooterItem$1;
TooltipDialog.Title = Title;
const HeaderComponent = React.forwardRef((_ref, ref) => {
let {
tag = 'div',
...other
} = _ref;
const {
isCloseButtonPresent,
hasHeader,
setHasHeader,
getTitleProps
} = useModalContext();
React.useEffect(() => {
if (!hasHeader && setHasHeader) {
setHasHeader(true);
}
return () => {
if (hasHeader && setHasHeader) {
setHasHeader(false);
}
};
}, [hasHeader, setHasHeader]);
return React__namespace.default.createElement(StyledDrawerHeader, Object.assign({}, getTitleProps(other), {
as: tag,
$isCloseButtonPresent: isCloseButtonPresent,
ref: ref
}));
});
HeaderComponent.displayName = 'Drawer.Header';
HeaderComponent.propTypes = {
tag: PropTypes__default.default.any
};
const Header = HeaderComponent;
const BodyComponent = React.forwardRef((props, ref) => {
const {
getContentProps
} = useModalContext();
return React__namespace.default.createElement(StyledDrawerBody, Object.assign({}, getContentProps(props), {
ref: ref
}), props.children);
});
BodyComponent.displayName = 'Drawer.Body';
const Body = BodyComponent;
const CloseComponent = React.forwardRef((props, ref) => {
const {
getCloseProps,
setIsCloseButtonPresent
} = useModalContext();
React.useEffect(() => {
setIsCloseButtonPresent(true);
return () => setIsCloseButtonPresent(false);
});
const ariaLabel = reactTheming.useText(CloseComponent, props, 'aria-label', 'Close drawer', props['aria-describedby'] === undefined );
return React__namespace.default.createElement(StyledDrawerClose, Object.assign({}, getCloseProps({
...props,
'aria-label': ariaLabel
}), {
ref: ref
}), React__namespace.default.createElement(SvgXStroke, null));
});
CloseComponent.displayName = 'Drawer.Close';
const Close = CloseComponent;
const FooterComponent = React.forwardRef((props, ref) => React__namespace.default.createElement(StyledDrawerFooter, Object.assign({
ref: ref
}, props)));
FooterComponent.displayName = 'Drawer.Footer';
const Footer = FooterComponent;
const FooterItemComponent = React.forwardRef((props, ref) => React__namespace.default.createElement(StyledDrawerFooterItem, Object.assign({
ref: ref
}, props)));
FooterItemComponent.displayName = 'Drawer.FooterItem';
const FooterItem = FooterItemComponent;
const DrawerComponent = React.forwardRef((_ref, ref) => {
let {
id,
isOpen,
onClose,
backdropProps,
appendToNode,
focusOnMount = true,
restoreFocus = true,
...props
} = _ref;
const modalRef = React.useRef(null);
const transitionRef = React.useRef(null);
const triggerRef = React.useRef(null);
const theme = React.useContext(styled.ThemeContext);
const environment = reactTheming.useDocument(theme);
const [isCloseButtonPresent, setIsCloseButtonPresent] = React.useState(false);
const [hasHeader, setHasHeader] = React.useState(false);
const {
getTitleProps,
getCloseProps,
getContentProps,
getBackdropProps,
getModalProps
} = containerModal.useModal({
idPrefix: id,
modalRef,
focusOnMount: false ,
restoreFocus: false ,
environment,
onClose
});
React.useEffect(() => {
if (environment) {
if (isOpen && modalRef.current) {
if (restoreFocus) {
triggerRef.current = activeElement__default.default(environment);
}
if (focusOnMount) {
modalRef.current.focus();
}
}
if (!isOpen && triggerRef.current) {
triggerRef.current.focus();
}
}
return () => {
if (!(restoreFocus && isOpen)) {
triggerRef.current = null;
}
};
}, [environment, restoreFocus, focusOnMount, isOpen]);
React.useEffect(() => {
if (!environment) {
return undefined;
}
const htmlElement = environment.querySelector('html');
let previousHtmlOverflow;
if (htmlElement && isOpen) {
previousHtmlOverflow = htmlElement.style.overflow;
htmlElement.style.overflow = 'hidden';
}
return () => {
if (htmlElement && isOpen) {
htmlElement.style.overflow = previousHtmlOverflow;
}
};
}, [environment, isOpen]);
const rootNode = React.useMemo(() => {
if (appendToNode) {
return appendToNode;
}
if (environment) {
return environment.body;
}
return undefined;
}, [appendToNode, environment]);
const value = React.useMemo(() => ({
isCloseButtonPresent,
hasHeader,
setHasHeader,
getTitleProps,
getContentProps,
getCloseProps,
setIsCloseButtonPresent
}), [isCloseButtonPresent, hasHeader, getTitleProps, getContentProps, getCloseProps]);
const modalProps = getModalProps({
'aria-describedby': undefined,
...(hasHeader ? {} : {
'aria-labelledby': undefined
})
});
const attribute = hasHeader ? 'aria-labelledby' : 'aria-label';
const defaultValue = hasHeader ? modalProps['aria-labelledby'] : 'Modal dialog';
const labelValue = hasHeader ? modalProps['aria-labelledby'] : props['aria-label'];
const ariaProps = {
[attribute]: reactTheming.useText(DrawerComponent, {
[attribute]: labelValue
}, attribute, defaultValue, modalRef.current !== null )
};
if (!rootNode) {
return null;
}
return ReactDOM__default.default.createPortal(React__namespace.default.createElement(ModalsContext.Provider, {
value: value
}, React__namespace.default.createElement(reactTransitionGroup.CSSTransition, {
in: isOpen,
timeout: 250,
unmountOnExit: true,
classNames: "garden-drawer-transition",
nodeRef: transitionRef
}, React__namespace.default.createElement(StyledBackdrop, Object.assign({
$isAnimated: true
}, getBackdropProps(backdropProps)), React__namespace.default.createElement(StyledDrawer, Object.assign({}, modalProps, ariaProps, props, {
ref: reactMergeRefs.mergeRefs([ref, modalRef, transitionRef])
}))))), rootNode);
});
DrawerComponent.displayName = 'Drawer';
DrawerComponent.propTypes = {
backdropProps: PropTypes__default.default.object,
focusOnMount: PropTypes__default.default.bool,
restoreFocus: PropTypes__default.default.bool,
onClose: PropTypes__default.default.func,
appendToNode: PropTypes__default.default.any,
isOpen: PropTypes__default.default.bool
};
const Drawer = DrawerComponent;
Drawer.Body = Body;
Drawer.Close = Close;
Drawer.Footer = Footer;
Drawer.FooterItem = FooterItem;
Drawer.Header = Header;
exports.Body = Body$2;
exports.Close = Close$2;
exports.Drawer = Drawer;
exports.Footer = Footer$2;
exports.FooterItem = FooterItem$2;
exports.Header = Header$1;
exports.Modal = Modal;
exports.PLACEMENT = PLACEMENT;
exports.TooltipDialog = TooltipDialog;