carbon-react 110.10.0 → 110.10.1

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.
Files changed (34) hide show
  1. package/esm/components/advanced-color-picker/advanced-color-picker.style.js +3 -3
  2. package/esm/components/dialog/dialog.component.js +9 -5
  3. package/esm/components/dialog/dialog.style.d.ts +9 -7
  4. package/esm/components/dialog/dialog.style.js +12 -14
  5. package/esm/components/dialog-full-screen/content.style.js +5 -1
  6. package/esm/components/dialog-full-screen/dialog-full-screen.component.js +5 -2
  7. package/esm/components/form/__internal__/form-summary.component.d.ts +14 -0
  8. package/esm/components/form/__internal__/form-summary.style.d.ts +3 -0
  9. package/esm/components/form/form.component.d.ts +21 -0
  10. package/esm/components/form/form.component.js +6 -3
  11. package/esm/components/form/form.style.js +14 -4
  12. package/esm/components/sidebar/sidebar.component.js +3 -1
  13. package/esm/hooks/__internal__/useIsStickyFooterForm/index.d.ts +1 -0
  14. package/esm/hooks/__internal__/useIsStickyFooterForm/index.js +1 -0
  15. package/esm/hooks/__internal__/useIsStickyFooterForm/useIsStickyFooterForm.d.ts +3 -0
  16. package/esm/hooks/__internal__/useIsStickyFooterForm/useIsStickyFooterForm.js +10 -0
  17. package/lib/components/advanced-color-picker/advanced-color-picker.style.js +2 -2
  18. package/lib/components/dialog/dialog.component.js +8 -3
  19. package/lib/components/dialog/dialog.style.d.ts +9 -7
  20. package/lib/components/dialog/dialog.style.js +16 -18
  21. package/lib/components/dialog-full-screen/content.style.js +5 -1
  22. package/lib/components/dialog-full-screen/dialog-full-screen.component.js +6 -2
  23. package/lib/components/form/__internal__/form-summary.component.d.ts +14 -0
  24. package/lib/components/form/__internal__/form-summary.style.d.ts +3 -0
  25. package/lib/components/form/form.component.d.ts +21 -0
  26. package/lib/components/form/form.component.js +7 -4
  27. package/lib/components/form/form.style.js +14 -4
  28. package/lib/components/sidebar/sidebar.component.js +4 -1
  29. package/lib/hooks/__internal__/useIsStickyFooterForm/index.d.ts +1 -0
  30. package/lib/hooks/__internal__/useIsStickyFooterForm/index.js +15 -0
  31. package/lib/hooks/__internal__/useIsStickyFooterForm/package.json +6 -0
  32. package/lib/hooks/__internal__/useIsStickyFooterForm/useIsStickyFooterForm.d.ts +3 -0
  33. package/lib/hooks/__internal__/useIsStickyFooterForm/useIsStickyFooterForm.js +27 -0
  34. package/package.json +2 -4
@@ -3,7 +3,7 @@ import { margin } from "styled-system";
3
3
  import StyledAdvancedColorPickerCell from "./advanced-color-picker-cell.style";
4
4
  import { StyledColorOptions } from "../simple-color-picker/simple-color-picker.style";
5
5
  import StyledSimpleColor from "../simple-color-picker/simple-color/simple-color.style";
6
- import { DialogContentStyle, DialogInnerContentStyle } from "../dialog/dialog.style";
6
+ import { StyledDialogContent, StyledDialogInnerContent } from "../dialog/dialog.style";
7
7
  import Dialog from "../dialog/dialog.component";
8
8
  import StyledIconButton from "../icon-button/icon-button.style";
9
9
  import checkerBoardSvg from "../simple-color-picker/color-sample-box/checker-board.svg";
@@ -40,11 +40,11 @@ const StyledAdvancedColorPickerPreview = styled.div`
40
40
  }
41
41
  `;
42
42
  const DialogStyle = styled(Dialog)`
43
- ${DialogContentStyle} {
43
+ ${StyledDialogContent} {
44
44
  padding: var(--spacing200);
45
45
  }
46
46
 
47
- ${DialogInnerContentStyle} {
47
+ ${StyledDialogInnerContent} {
48
48
  padding: 0;
49
49
  }
50
50
 
@@ -1,17 +1,18 @@
1
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
- import React, { useRef, useEffect, useLayoutEffect, useCallback } from "react";
3
+ import React, { useCallback, useEffect, useLayoutEffect, useRef } from "react";
4
4
  import PropTypes from "prop-types";
5
5
  import createGuid from "../../__internal__/utils/helpers/guid";
6
6
  import Modal from "../modal";
7
7
  import Heading from "../heading";
8
8
  import useResizeObserver from "../../hooks/__internal__/useResizeObserver";
9
- import { DialogStyle, DialogTitleStyle, DialogContentStyle, DialogInnerContentStyle } from "./dialog.style";
9
+ import { StyledDialog, StyledDialogTitle, StyledDialogContent, StyledDialogInnerContent } from "./dialog.style";
10
10
  import FocusTrap from "../../__internal__/focus-trap";
11
11
  import IconButton from "../icon-button";
12
12
  import Icon from "../icon";
13
13
  import { TOP_MARGIN } from "./dialog.config";
14
14
  import useLocale from "../../hooks/__internal__/useLocale";
15
+ import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
16
 
16
17
  const Dialog = ({
17
18
  className,
@@ -45,6 +46,7 @@ const Dialog = ({
45
46
  const {
46
47
  current: subtitleId
47
48
  } = useRef(createGuid());
49
+ const hasStickyFooter = useIsStickyFooterForm(children);
48
50
  const centerDialog = useCallback(() => {
49
51
  /* istanbul ignore if */
50
52
  if (!dialogRef.current) {
@@ -118,7 +120,7 @@ const Dialog = ({
118
120
 
119
121
  const dialogTitle = () => {
120
122
  if (!title) return null;
121
- return /*#__PURE__*/React.createElement(DialogTitleStyle, {
123
+ return /*#__PURE__*/React.createElement(StyledDialogTitle, {
122
124
  showCloseIcon: showCloseIcon,
123
125
  hasSubtitle: !!subtitle,
124
126
  ref: titleRef
@@ -164,7 +166,7 @@ const Dialog = ({
164
166
  wrapperRef: dialogRef,
165
167
  isOpen: open,
166
168
  additionalWrapperRefs: focusableContainers
167
- }, /*#__PURE__*/React.createElement(DialogStyle, _extends({
169
+ }, /*#__PURE__*/React.createElement(StyledDialog, _extends({
168
170
  "aria-modal": true,
169
171
  ref: dialogRef,
170
172
  topMargin: TOP_MARGIN
@@ -173,7 +175,9 @@ const Dialog = ({
173
175
  "data-element": "dialog",
174
176
  "data-role": rest["data-role"],
175
177
  role: role
176
- }, contentPadding), dialogTitle(), closeIcon(), /*#__PURE__*/React.createElement(DialogContentStyle, contentPadding, /*#__PURE__*/React.createElement(DialogInnerContentStyle, _extends({
178
+ }, contentPadding), dialogTitle(), closeIcon(), /*#__PURE__*/React.createElement(StyledDialogContent, _extends({}, contentPadding, {
179
+ hasStickyFooter: hasStickyFooter
180
+ }), /*#__PURE__*/React.createElement(StyledDialogInnerContent, _extends({
177
181
  ref: innerContentRef
178
182
  }, contentPadding), children)))));
179
183
  };
@@ -9,17 +9,19 @@ declare const dialogSizes: {
9
9
  large: string;
10
10
  "extra-large": string;
11
11
  };
12
- declare type DialogStyleProps = {
12
+ declare type StyledDialogProps = {
13
13
  topMargin: number;
14
14
  size?: keyof typeof dialogSizes;
15
15
  dialogHeight?: string;
16
16
  };
17
- declare const DialogStyle: import("styled-components").StyledComponent<"div", any, DialogStyleProps & ContentPaddingInterface, never>;
18
- declare type DialogTitleStyleProps = {
17
+ declare const StyledDialog: import("styled-components").StyledComponent<"div", any, StyledDialogProps & ContentPaddingInterface, never>;
18
+ declare type StyledDialogTitleProps = {
19
19
  showCloseIcon?: boolean;
20
20
  hasSubtitle?: boolean;
21
21
  };
22
- declare const DialogTitleStyle: import("styled-components").StyledComponent<"div", any, DialogTitleStyleProps, never>;
23
- declare const DialogContentStyle: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
24
- declare const DialogInnerContentStyle: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
25
- export { DialogStyle, DialogTitleStyle, DialogContentStyle, DialogInnerContentStyle, };
22
+ declare const StyledDialogTitle: import("styled-components").StyledComponent<"div", any, StyledDialogTitleProps, never>;
23
+ declare const StyledDialogContent: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface & {
24
+ hasStickyFooter: boolean;
25
+ }, never>;
26
+ declare const StyledDialogInnerContent: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
27
+ export { StyledDialog, StyledDialogTitle, StyledDialogContent, StyledDialogInnerContent, };
@@ -63,7 +63,7 @@ const calculatePaddingTopInnerContent = ({
63
63
  p
64
64
  }) => [py, p].some(padding => padding !== undefined) ? 0 : `${CONTENT_TOP_PADDING}px`;
65
65
 
66
- const DialogStyle = styled.div`
66
+ const StyledDialog = styled.div`
67
67
  background-color: var(--colorsUtilityMajor025);
68
68
  box-shadow: var(--boxShadow300);
69
69
  display: flex;
@@ -85,12 +85,6 @@ const DialogStyle = styled.div`
85
85
  size
86
86
  }) => size && css`
87
87
  width: ${dialogSizes[size]};
88
-
89
- // IE10+ fix (caters for scrollbar width)
90
- @media screen and (-ms-high-contrast: active),
91
- screen and (-ms-high-contrast: none) {
92
- width: $size - 16;
93
- }
94
88
  `}
95
89
 
96
90
  ${({
@@ -125,7 +119,7 @@ const DialogStyle = styled.div`
125
119
  }
126
120
  }
127
121
  `;
128
- const DialogTitleStyle = styled.div`
122
+ const StyledDialogTitle = styled.div`
129
123
  padding: 23px ${HORIZONTAL_PADDING}px 0;
130
124
  border-bottom: 1px solid #ccd6db;
131
125
  ${({
@@ -150,25 +144,29 @@ const DialogTitleStyle = styled.div`
150
144
  }
151
145
  }
152
146
  `;
153
- const DialogContentStyle = styled.div`
147
+ const StyledDialogContent = styled.div`
154
148
  box-sizing: border-box;
155
149
  display: flex;
156
150
  flex-direction: column;
157
- overflow-y: auto;
151
+ ${({
152
+ hasStickyFooter
153
+ }) => !hasStickyFooter && css`
154
+ overflow-y: auto;
155
+ `}
158
156
  width: 100%;
159
157
  flex: 1;
160
158
  padding: 0px ${HORIZONTAL_PADDING}px ${CONTENT_BOTTOM_PADDING}px;
161
159
  ${paddingFn}
162
160
  `;
163
- const DialogInnerContentStyle = styled.div`
161
+ const StyledDialogInnerContent = styled.div`
164
162
  position: relative;
165
163
  flex: 1;
166
164
  padding-top: ${calculatePaddingTopInnerContent};
167
165
  `;
168
- DialogStyle.defaultProps = {
166
+ StyledDialog.defaultProps = {
169
167
  theme: baseTheme
170
168
  };
171
- DialogContentStyle.defaultProps = {
169
+ StyledDialogContent.defaultProps = {
172
170
  theme: baseTheme
173
171
  };
174
- export { DialogStyle, DialogTitleStyle, DialogContentStyle, DialogInnerContentStyle };
172
+ export { StyledDialog, StyledDialogTitle, StyledDialogContent, StyledDialogInnerContent };
@@ -1,7 +1,11 @@
1
1
  import styled, { css } from "styled-components";
2
2
  import { StyledFormFooter, StyledFormContent } from "../form/form.style";
3
3
  const StyledContent = styled.div`
4
- overflow-y: auto;
4
+ ${({
5
+ hasStickyFooter
6
+ }) => !hasStickyFooter && css`
7
+ overflow-y: auto;
8
+ `}
5
9
  padding: 0 16px;
6
10
  flex: 1;
7
11
 
@@ -12,6 +12,7 @@ import FocusTrap from "../../__internal__/focus-trap";
12
12
  import IconButton from "../icon-button";
13
13
  import Icon from "../icon";
14
14
  import useLocale from "../../hooks/__internal__/useLocale";
15
+ import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
16
 
16
17
  const DialogFullScreen = ({
17
18
  "aria-describedby": ariaDescribedBy,
@@ -44,6 +45,7 @@ const DialogFullScreen = ({
44
45
  const {
45
46
  current: subtitleId
46
47
  } = useRef(createGuid());
48
+ const hasStickyFooter = useIsStickyFooterForm(children);
47
49
 
48
50
  const closeIcon = () => {
49
51
  if (!showCloseIcon || !onCancel) return null;
@@ -57,7 +59,7 @@ const DialogFullScreen = ({
57
59
  };
58
60
 
59
61
  const dialogTitle = () => /*#__PURE__*/React.createElement(FullScreenHeading, {
60
- hasContent: title,
62
+ hasContent: !!title,
61
63
  ref: headingRef
62
64
  }, typeof title === "string" ? /*#__PURE__*/React.createElement(Heading, {
63
65
  "data-element": "dialog-title",
@@ -100,7 +102,8 @@ const DialogFullScreen = ({
100
102
  hasHeader: title !== undefined,
101
103
  "data-element": "content",
102
104
  ref: contentRef,
103
- disableContentPadding: disableContentPadding
105
+ disableContentPadding: disableContentPadding,
106
+ hasStickyFooter: hasStickyFooter
104
107
  }, children))));
105
108
  };
106
109
 
@@ -0,0 +1,14 @@
1
+ export default FormSummary;
2
+ declare function FormSummary({ fullWidth, ...props }: {
3
+ [x: string]: any;
4
+ fullWidth: any;
5
+ }): JSX.Element;
6
+ declare namespace FormSummary {
7
+ namespace propTypes {
8
+ const children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
9
+ const errors: PropTypes.Requireable<number>;
10
+ const warnings: PropTypes.Requireable<number>;
11
+ const fullWidth: PropTypes.Requireable<boolean>;
12
+ }
13
+ }
14
+ import PropTypes from "prop-types";
@@ -0,0 +1,3 @@
1
+ export const StyledFormSummary: import("styled-components").StyledComponent<"div", any, {}, never>;
2
+ export const StyledMessagePrefix: import("styled-components").StyledComponent<"div", any, {}, never>;
3
+ export const StyledInternalSummary: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,21 @@
1
+ export default Form;
2
+ declare function Form({ children, saveButton, leftSideButtons, rightSideButtons, errorCount, warningCount, onSubmit, buttonAlignment, stickyFooter, fieldSpacing, noValidate, height, fullWidthButtons, ...rest }: {
3
+ [x: string]: any;
4
+ children: any;
5
+ saveButton: any;
6
+ leftSideButtons: any;
7
+ rightSideButtons: any;
8
+ errorCount: any;
9
+ warningCount: any;
10
+ onSubmit: any;
11
+ buttonAlignment?: string | undefined;
12
+ stickyFooter: any;
13
+ fieldSpacing?: number | undefined;
14
+ noValidate?: boolean | undefined;
15
+ height: any;
16
+ fullWidthButtons?: boolean | undefined;
17
+ }): JSX.Element;
18
+ declare namespace Form {
19
+ const propTypes: any;
20
+ const displayName: string;
21
+ }
@@ -3,8 +3,8 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
3
3
  import React, { useRef, useContext } from "react";
4
4
  import PropTypes from "prop-types";
5
5
  import styledSystemPropTypes from "@styled-system/prop-types";
6
- import { ModalContext } from "../modal/modal.component";
7
6
  import { SidebarContext } from "../sidebar/sidebar.component";
7
+ import { ModalContext } from "../modal/modal.component";
8
8
  import FormSummary from "./__internal__/form-summary.component";
9
9
  import { StyledForm, StyledFormContent, StyledFormFooter, StyledLeftButtons, StyledRightButtons, StyledFullWidthButtons } from "./form.style";
10
10
 
@@ -41,7 +41,8 @@ const Form = ({
41
41
  fieldSpacing: fieldSpacing,
42
42
  noValidate: noValidate,
43
43
  isInSidebar: isInSidebar,
44
- height: height
44
+ height: height,
45
+ isInModal: isInModal
45
46
  }, rest), /*#__PURE__*/React.createElement(StyledFormContent, {
46
47
  "data-element": "form-content",
47
48
  className: stickyFooter ? "sticky" : "",
@@ -52,7 +53,8 @@ const Form = ({
52
53
  className: stickyFooter ? "sticky" : "",
53
54
  ref: formFooterRef,
54
55
  stickyFooter: stickyFooter,
55
- buttonAlignment: buttonAlignment
56
+ buttonAlignment: buttonAlignment,
57
+ isInModal: isInModal
56
58
  }, leftSideButtons && /*#__PURE__*/React.createElement(StyledLeftButtons, {
57
59
  buttonAlignment: buttonAlignment
58
60
  }, leftSideButtons), /*#__PURE__*/React.createElement(FormSummary, {
@@ -119,4 +121,5 @@ Form.propTypes = { ...styledSystemPropTypes.space,
119
121
  /** Applies styling for full width buttons. Please note that you will still need to pass the `fullWidth` prop to the button you compose */
120
122
  fullWidthButtons: PropTypes.bool
121
123
  };
124
+ Form.displayName = "Form";
122
125
  export default Form;
@@ -16,7 +16,7 @@ export const StyledFormContent = styled.div`
16
16
  isInModal
17
17
  }) => css`
18
18
  ${stickyFooter && css`
19
- overflow-y: ${isInModal ? "visible" : "inherit"};
19
+ overflow-y: ${isInModal ? "auto" : "inherit"};
20
20
  flex: 1;
21
21
  `}
22
22
  `}
@@ -33,7 +33,8 @@ export const StyledFormFooter = styled.div`
33
33
 
34
34
  ${({
35
35
  stickyFooter,
36
- fullWidthButtons
36
+ fullWidthButtons,
37
+ isInModal
37
38
  }) => css`
38
39
  ${!stickyFooter && css`
39
40
  margin-top: 48px;
@@ -46,7 +47,9 @@ export const StyledFormFooter = styled.div`
46
47
  padding: 16px 32px;
47
48
  width: 100%;
48
49
  z-index: 1000;
49
- position: sticky;
50
+ ${!isInModal && css`
51
+ position: sticky;
52
+ `}
50
53
  bottom: 0;
51
54
  `}
52
55
 
@@ -65,8 +68,10 @@ const formBottomMargins = fieldSpacing => ({
65
68
  4: "var(--spacing400)",
66
69
  5: "var(--spacing500)",
67
70
  7: "var(--spacing700)"
68
- })[fieldSpacing];
71
+ })[fieldSpacing]; // Accounts for height of the header of Modal parent, the height form footer and some additional spacing
69
72
 
73
+
74
+ const HEIGHT_SPACING = 216;
70
75
  export const StyledForm = styled.form`
71
76
  ${space}
72
77
 
@@ -109,12 +114,17 @@ export const StyledForm = styled.form`
109
114
 
110
115
  ${({
111
116
  stickyFooter,
117
+ isInModal,
112
118
  isInSidebar
113
119
  }) => stickyFooter && css`
114
120
  display: flex;
115
121
  flex-direction: column;
116
122
  position: relative;
117
123
 
124
+ ${isInModal && css`
125
+ max-height: calc(100vh - ${HEIGHT_SPACING}px);
126
+ `}
127
+
118
128
  ${isInSidebar && css`
119
129
  min-height: 100%;
120
130
  ${StyledFormContent}.sticky {
@@ -12,6 +12,7 @@ import Box from "../box";
12
12
  import createGuid from "../../__internal__/utils/helpers/guid";
13
13
  import useLocale from "../../hooks/__internal__/useLocale";
14
14
  import { filterStyledSystemPaddingProps } from "../../style/utils";
15
+ import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
16
  export const SidebarContext = /*#__PURE__*/React.createContext({});
16
17
  const Sidebar = /*#__PURE__*/React.forwardRef(({
17
18
  "aria-describedby": ariaDescribedBy,
@@ -33,6 +34,7 @@ const Sidebar = /*#__PURE__*/React.forwardRef(({
33
34
  const {
34
35
  current: titleId
35
36
  } = useRef(createGuid());
37
+ const hasStickyFooter = useIsStickyFooterForm(children);
36
38
  const sidebarRef = useRef(null);
37
39
  const setRefs = useCallback(reference => {
38
40
  sidebarRef.current = reference;
@@ -77,7 +79,7 @@ const Sidebar = /*#__PURE__*/React.forwardRef(({
77
79
  px: "var(--spacing400)"
78
80
  }, filterStyledSystemPaddingProps(rest), {
79
81
  scrollVariant: "light",
80
- overflow: "auto",
82
+ overflow: hasStickyFooter ? undefined : "auto",
81
83
  flex: "1"
82
84
  }), /*#__PURE__*/React.createElement(SidebarContext.Provider, {
83
85
  value: {
@@ -0,0 +1 @@
1
+ export { default } from "./useIsStickyFooterForm";
@@ -0,0 +1 @@
1
+ export { default } from "./useIsStickyFooterForm";
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const _default: (children?: React.ReactNode) => boolean;
3
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import React, { useMemo } from "react";
2
+ import Form from "../../../components/form/form.component";
3
+ export default (children => {
4
+ const isStickyFooterForm = useMemo(() => React.Children.toArray(children).some(child => {
5
+ var _child$type;
6
+
7
+ return /*#__PURE__*/React.isValidElement(child) && ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type.displayName) === Form.displayName && child.props.stickyFooter;
8
+ }), [children]);
9
+ return isStickyFooterForm;
10
+ });
@@ -71,11 +71,11 @@ const StyledAdvancedColorPickerPreview = _styledComponents.default.div`
71
71
  `;
72
72
  exports.StyledAdvancedColorPickerPreview = StyledAdvancedColorPickerPreview;
73
73
  const DialogStyle = (0, _styledComponents.default)(_dialog2.default)`
74
- ${_dialog.DialogContentStyle} {
74
+ ${_dialog.StyledDialogContent} {
75
75
  padding: var(--spacing200);
76
76
  }
77
77
 
78
- ${_dialog.DialogInnerContentStyle} {
78
+ ${_dialog.StyledDialogInnerContent} {
79
79
  padding: 0;
80
80
  }
81
81
 
@@ -29,6 +29,8 @@ var _dialog2 = require("./dialog.config");
29
29
 
30
30
  var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
31
31
 
32
+ var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -69,6 +71,7 @@ const Dialog = ({
69
71
  const {
70
72
  current: subtitleId
71
73
  } = (0, _react.useRef)((0, _guid.default)());
74
+ const hasStickyFooter = (0, _useIsStickyFooterForm.default)(children);
72
75
  const centerDialog = (0, _react.useCallback)(() => {
73
76
  /* istanbul ignore if */
74
77
  if (!dialogRef.current) {
@@ -142,7 +145,7 @@ const Dialog = ({
142
145
 
143
146
  const dialogTitle = () => {
144
147
  if (!title) return null;
145
- return /*#__PURE__*/_react.default.createElement(_dialog.DialogTitleStyle, {
148
+ return /*#__PURE__*/_react.default.createElement(_dialog.StyledDialogTitle, {
146
149
  showCloseIcon: showCloseIcon,
147
150
  hasSubtitle: !!subtitle,
148
151
  ref: titleRef
@@ -188,7 +191,7 @@ const Dialog = ({
188
191
  wrapperRef: dialogRef,
189
192
  isOpen: open,
190
193
  additionalWrapperRefs: focusableContainers
191
- }, /*#__PURE__*/_react.default.createElement(_dialog.DialogStyle, _extends({
194
+ }, /*#__PURE__*/_react.default.createElement(_dialog.StyledDialog, _extends({
192
195
  "aria-modal": true,
193
196
  ref: dialogRef,
194
197
  topMargin: _dialog2.TOP_MARGIN
@@ -197,7 +200,9 @@ const Dialog = ({
197
200
  "data-element": "dialog",
198
201
  "data-role": rest["data-role"],
199
202
  role: role
200
- }, contentPadding), dialogTitle(), closeIcon(), /*#__PURE__*/_react.default.createElement(_dialog.DialogContentStyle, contentPadding, /*#__PURE__*/_react.default.createElement(_dialog.DialogInnerContentStyle, _extends({
203
+ }, contentPadding), dialogTitle(), closeIcon(), /*#__PURE__*/_react.default.createElement(_dialog.StyledDialogContent, _extends({}, contentPadding, {
204
+ hasStickyFooter: hasStickyFooter
205
+ }), /*#__PURE__*/_react.default.createElement(_dialog.StyledDialogInnerContent, _extends({
201
206
  ref: innerContentRef
202
207
  }, contentPadding), children)))));
203
208
  };
@@ -9,17 +9,19 @@ declare const dialogSizes: {
9
9
  large: string;
10
10
  "extra-large": string;
11
11
  };
12
- declare type DialogStyleProps = {
12
+ declare type StyledDialogProps = {
13
13
  topMargin: number;
14
14
  size?: keyof typeof dialogSizes;
15
15
  dialogHeight?: string;
16
16
  };
17
- declare const DialogStyle: import("styled-components").StyledComponent<"div", any, DialogStyleProps & ContentPaddingInterface, never>;
18
- declare type DialogTitleStyleProps = {
17
+ declare const StyledDialog: import("styled-components").StyledComponent<"div", any, StyledDialogProps & ContentPaddingInterface, never>;
18
+ declare type StyledDialogTitleProps = {
19
19
  showCloseIcon?: boolean;
20
20
  hasSubtitle?: boolean;
21
21
  };
22
- declare const DialogTitleStyle: import("styled-components").StyledComponent<"div", any, DialogTitleStyleProps, never>;
23
- declare const DialogContentStyle: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
24
- declare const DialogInnerContentStyle: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
25
- export { DialogStyle, DialogTitleStyle, DialogContentStyle, DialogInnerContentStyle, };
22
+ declare const StyledDialogTitle: import("styled-components").StyledComponent<"div", any, StyledDialogTitleProps, never>;
23
+ declare const StyledDialogContent: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface & {
24
+ hasStickyFooter: boolean;
25
+ }, never>;
26
+ declare const StyledDialogInnerContent: import("styled-components").StyledComponent<"div", any, ContentPaddingInterface, never>;
27
+ export { StyledDialog, StyledDialogTitle, StyledDialogContent, StyledDialogInnerContent, };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DialogInnerContentStyle = exports.DialogContentStyle = exports.DialogTitleStyle = exports.DialogStyle = void 0;
6
+ exports.StyledDialogInnerContent = exports.StyledDialogContent = exports.StyledDialogTitle = exports.StyledDialog = void 0;
7
7
 
8
8
  var _styledComponents = _interopRequireWildcard(require("styled-components"));
9
9
 
@@ -83,7 +83,7 @@ const calculatePaddingTopInnerContent = ({
83
83
  p
84
84
  }) => [py, p].some(padding => padding !== undefined) ? 0 : `${_dialog.CONTENT_TOP_PADDING}px`;
85
85
 
86
- const DialogStyle = _styledComponents.default.div`
86
+ const StyledDialog = _styledComponents.default.div`
87
87
  background-color: var(--colorsUtilityMajor025);
88
88
  box-shadow: var(--boxShadow300);
89
89
  display: flex;
@@ -105,12 +105,6 @@ const DialogStyle = _styledComponents.default.div`
105
105
  size
106
106
  }) => size && (0, _styledComponents.css)`
107
107
  width: ${dialogSizes[size]};
108
-
109
- // IE10+ fix (caters for scrollbar width)
110
- @media screen and (-ms-high-contrast: active),
111
- screen and (-ms-high-contrast: none) {
112
- width: $size - 16;
113
- }
114
108
  `}
115
109
 
116
110
  ${({
@@ -145,8 +139,8 @@ const DialogStyle = _styledComponents.default.div`
145
139
  }
146
140
  }
147
141
  `;
148
- exports.DialogStyle = DialogStyle;
149
- const DialogTitleStyle = _styledComponents.default.div`
142
+ exports.StyledDialog = StyledDialog;
143
+ const StyledDialogTitle = _styledComponents.default.div`
150
144
  padding: 23px ${_dialog.HORIZONTAL_PADDING}px 0;
151
145
  border-bottom: 1px solid #ccd6db;
152
146
  ${({
@@ -171,27 +165,31 @@ const DialogTitleStyle = _styledComponents.default.div`
171
165
  }
172
166
  }
173
167
  `;
174
- exports.DialogTitleStyle = DialogTitleStyle;
175
- const DialogContentStyle = _styledComponents.default.div`
168
+ exports.StyledDialogTitle = StyledDialogTitle;
169
+ const StyledDialogContent = _styledComponents.default.div`
176
170
  box-sizing: border-box;
177
171
  display: flex;
178
172
  flex-direction: column;
179
- overflow-y: auto;
173
+ ${({
174
+ hasStickyFooter
175
+ }) => !hasStickyFooter && (0, _styledComponents.css)`
176
+ overflow-y: auto;
177
+ `}
180
178
  width: 100%;
181
179
  flex: 1;
182
180
  padding: 0px ${_dialog.HORIZONTAL_PADDING}px ${_dialog.CONTENT_BOTTOM_PADDING}px;
183
181
  ${_styledSystem.padding}
184
182
  `;
185
- exports.DialogContentStyle = DialogContentStyle;
186
- const DialogInnerContentStyle = _styledComponents.default.div`
183
+ exports.StyledDialogContent = StyledDialogContent;
184
+ const StyledDialogInnerContent = _styledComponents.default.div`
187
185
  position: relative;
188
186
  flex: 1;
189
187
  padding-top: ${calculatePaddingTopInnerContent};
190
188
  `;
191
- exports.DialogInnerContentStyle = DialogInnerContentStyle;
192
- DialogStyle.defaultProps = {
189
+ exports.StyledDialogInnerContent = StyledDialogInnerContent;
190
+ StyledDialog.defaultProps = {
193
191
  theme: _base.default
194
192
  };
195
- DialogContentStyle.defaultProps = {
193
+ StyledDialogContent.defaultProps = {
196
194
  theme: _base.default
197
195
  };
@@ -14,7 +14,11 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
14
14
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
15
 
16
16
  const StyledContent = _styledComponents.default.div`
17
- overflow-y: auto;
17
+ ${({
18
+ hasStickyFooter
19
+ }) => !hasStickyFooter && (0, _styledComponents.css)`
20
+ overflow-y: auto;
21
+ `}
18
22
  padding: 0 16px;
19
23
  flex: 1;
20
24
 
@@ -29,6 +29,8 @@ var _icon = _interopRequireDefault(require("../icon"));
29
29
 
30
30
  var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
31
31
 
32
+ var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -68,6 +70,7 @@ const DialogFullScreen = ({
68
70
  const {
69
71
  current: subtitleId
70
72
  } = (0, _react.useRef)((0, _guid.default)());
73
+ const hasStickyFooter = (0, _useIsStickyFooterForm.default)(children);
71
74
 
72
75
  const closeIcon = () => {
73
76
  if (!showCloseIcon || !onCancel) return null;
@@ -81,7 +84,7 @@ const DialogFullScreen = ({
81
84
  };
82
85
 
83
86
  const dialogTitle = () => /*#__PURE__*/_react.default.createElement(_fullScreenHeading.default, {
84
- hasContent: title,
87
+ hasContent: !!title,
85
88
  ref: headingRef
86
89
  }, typeof title === "string" ? /*#__PURE__*/_react.default.createElement(_heading.default, {
87
90
  "data-element": "dialog-title",
@@ -124,7 +127,8 @@ const DialogFullScreen = ({
124
127
  hasHeader: title !== undefined,
125
128
  "data-element": "content",
126
129
  ref: contentRef,
127
- disableContentPadding: disableContentPadding
130
+ disableContentPadding: disableContentPadding,
131
+ hasStickyFooter: hasStickyFooter
128
132
  }, children))));
129
133
  };
130
134
 
@@ -0,0 +1,14 @@
1
+ export default FormSummary;
2
+ declare function FormSummary({ fullWidth, ...props }: {
3
+ [x: string]: any;
4
+ fullWidth: any;
5
+ }): JSX.Element;
6
+ declare namespace FormSummary {
7
+ namespace propTypes {
8
+ const children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
9
+ const errors: PropTypes.Requireable<number>;
10
+ const warnings: PropTypes.Requireable<number>;
11
+ const fullWidth: PropTypes.Requireable<boolean>;
12
+ }
13
+ }
14
+ import PropTypes from "prop-types";
@@ -0,0 +1,3 @@
1
+ export const StyledFormSummary: import("styled-components").StyledComponent<"div", any, {}, never>;
2
+ export const StyledMessagePrefix: import("styled-components").StyledComponent<"div", any, {}, never>;
3
+ export const StyledInternalSummary: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,21 @@
1
+ export default Form;
2
+ declare function Form({ children, saveButton, leftSideButtons, rightSideButtons, errorCount, warningCount, onSubmit, buttonAlignment, stickyFooter, fieldSpacing, noValidate, height, fullWidthButtons, ...rest }: {
3
+ [x: string]: any;
4
+ children: any;
5
+ saveButton: any;
6
+ leftSideButtons: any;
7
+ rightSideButtons: any;
8
+ errorCount: any;
9
+ warningCount: any;
10
+ onSubmit: any;
11
+ buttonAlignment?: string | undefined;
12
+ stickyFooter: any;
13
+ fieldSpacing?: number | undefined;
14
+ noValidate?: boolean | undefined;
15
+ height: any;
16
+ fullWidthButtons?: boolean | undefined;
17
+ }): JSX.Element;
18
+ declare namespace Form {
19
+ const propTypes: any;
20
+ const displayName: string;
21
+ }
@@ -11,10 +11,10 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
12
  var _propTypes2 = _interopRequireDefault(require("@styled-system/prop-types"));
13
13
 
14
- var _modal = require("../modal/modal.component");
15
-
16
14
  var _sidebar = require("../sidebar/sidebar.component");
17
15
 
16
+ var _modal = require("../modal/modal.component");
17
+
18
18
  var _formSummary = _interopRequireDefault(require("./__internal__/form-summary.component"));
19
19
 
20
20
  var _form = require("./form.style");
@@ -60,7 +60,8 @@ const Form = ({
60
60
  fieldSpacing: fieldSpacing,
61
61
  noValidate: noValidate,
62
62
  isInSidebar: isInSidebar,
63
- height: height
63
+ height: height,
64
+ isInModal: isInModal
64
65
  }, rest), /*#__PURE__*/_react.default.createElement(_form.StyledFormContent, {
65
66
  "data-element": "form-content",
66
67
  className: stickyFooter ? "sticky" : "",
@@ -71,7 +72,8 @@ const Form = ({
71
72
  className: stickyFooter ? "sticky" : "",
72
73
  ref: formFooterRef,
73
74
  stickyFooter: stickyFooter,
74
- buttonAlignment: buttonAlignment
75
+ buttonAlignment: buttonAlignment,
76
+ isInModal: isInModal
75
77
  }, leftSideButtons && /*#__PURE__*/_react.default.createElement(_form.StyledLeftButtons, {
76
78
  buttonAlignment: buttonAlignment
77
79
  }, leftSideButtons), /*#__PURE__*/_react.default.createElement(_formSummary.default, {
@@ -138,5 +140,6 @@ Form.propTypes = { ..._propTypes2.default.space,
138
140
  /** Applies styling for full width buttons. Please note that you will still need to pass the `fullWidth` prop to the button you compose */
139
141
  fullWidthButtons: _propTypes.default.bool
140
142
  };
143
+ Form.displayName = "Form";
141
144
  var _default = Form;
142
145
  exports.default = _default;
@@ -41,7 +41,7 @@ const StyledFormContent = _styledComponents.default.div`
41
41
  isInModal
42
42
  }) => (0, _styledComponents.css)`
43
43
  ${stickyFooter && (0, _styledComponents.css)`
44
- overflow-y: ${isInModal ? "visible" : "inherit"};
44
+ overflow-y: ${isInModal ? "auto" : "inherit"};
45
45
  flex: 1;
46
46
  `}
47
47
  `}
@@ -59,7 +59,8 @@ const StyledFormFooter = _styledComponents.default.div`
59
59
 
60
60
  ${({
61
61
  stickyFooter,
62
- fullWidthButtons
62
+ fullWidthButtons,
63
+ isInModal
63
64
  }) => (0, _styledComponents.css)`
64
65
  ${!stickyFooter && (0, _styledComponents.css)`
65
66
  margin-top: 48px;
@@ -72,7 +73,9 @@ const StyledFormFooter = _styledComponents.default.div`
72
73
  padding: 16px 32px;
73
74
  width: 100%;
74
75
  z-index: 1000;
75
- position: sticky;
76
+ ${!isInModal && (0, _styledComponents.css)`
77
+ position: sticky;
78
+ `}
76
79
  bottom: 0;
77
80
  `}
78
81
 
@@ -92,8 +95,10 @@ const formBottomMargins = fieldSpacing => ({
92
95
  4: "var(--spacing400)",
93
96
  5: "var(--spacing500)",
94
97
  7: "var(--spacing700)"
95
- })[fieldSpacing];
98
+ })[fieldSpacing]; // Accounts for height of the header of Modal parent, the height form footer and some additional spacing
96
99
 
100
+
101
+ const HEIGHT_SPACING = 216;
97
102
  const StyledForm = _styledComponents.default.form`
98
103
  ${_styledSystem.space}
99
104
 
@@ -136,12 +141,17 @@ const StyledForm = _styledComponents.default.form`
136
141
 
137
142
  ${({
138
143
  stickyFooter,
144
+ isInModal,
139
145
  isInSidebar
140
146
  }) => stickyFooter && (0, _styledComponents.css)`
141
147
  display: flex;
142
148
  flex-direction: column;
143
149
  position: relative;
144
150
 
151
+ ${isInModal && (0, _styledComponents.css)`
152
+ max-height: calc(100vh - ${HEIGHT_SPACING}px);
153
+ `}
154
+
145
155
  ${isInSidebar && (0, _styledComponents.css)`
146
156
  min-height: 100%;
147
157
  ${StyledFormContent}.sticky {
@@ -29,6 +29,8 @@ var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLoc
29
29
 
30
30
  var _utils = require("../../style/utils");
31
31
 
32
+ var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -61,6 +63,7 @@ const Sidebar = /*#__PURE__*/_react.default.forwardRef(({
61
63
  const {
62
64
  current: titleId
63
65
  } = (0, _react.useRef)((0, _guid.default)());
66
+ const hasStickyFooter = (0, _useIsStickyFooterForm.default)(children);
64
67
  const sidebarRef = (0, _react.useRef)(null);
65
68
  const setRefs = (0, _react.useCallback)(reference => {
66
69
  sidebarRef.current = reference;
@@ -106,7 +109,7 @@ const Sidebar = /*#__PURE__*/_react.default.forwardRef(({
106
109
  px: "var(--spacing400)"
107
110
  }, (0, _utils.filterStyledSystemPaddingProps)(rest), {
108
111
  scrollVariant: "light",
109
- overflow: "auto",
112
+ overflow: hasStickyFooter ? undefined : "auto",
110
113
  flex: "1"
111
114
  }), /*#__PURE__*/_react.default.createElement(SidebarContext.Provider, {
112
115
  value: {
@@ -0,0 +1 @@
1
+ export { default } from "./useIsStickyFooterForm";
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _useIsStickyFooterForm.default;
10
+ }
11
+ });
12
+
13
+ var _useIsStickyFooterForm = _interopRequireDefault(require("./useIsStickyFooterForm"));
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../../../../esm/hooks/__internal__/useIsStickyFooterForm/index.js",
4
+ "main": "./index.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const _default: (children?: React.ReactNode) => boolean;
3
+ export default _default;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _form = _interopRequireDefault(require("../../../components/form/form.component"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
15
+
16
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+
18
+ var _default = children => {
19
+ const isStickyFooterForm = (0, _react.useMemo)(() => _react.default.Children.toArray(children).some(child => {
20
+ var _child$type;
21
+
22
+ return /*#__PURE__*/_react.default.isValidElement(child) && ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type.displayName) === _form.default.displayName && child.props.stickyFooter;
23
+ }), [children]);
24
+ return isStickyFooterForm;
25
+ };
26
+
27
+ exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "110.10.0",
3
+ "version": "110.10.1",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",
@@ -64,8 +64,6 @@
64
64
  "@babel/types": "^7.16.0",
65
65
  "@commitlint/cli": "^11.0.0",
66
66
  "@commitlint/config-conventional": "^11.0.0",
67
- "@cypress/react": "^5.12.0",
68
- "@cypress/webpack-dev-server": "^1.8.4",
69
67
  "@sage/design-tokens": "^2.41.0",
70
68
  "@semantic-release/changelog": "^6.0.1",
71
69
  "@semantic-release/exec": "^6.0.2",
@@ -112,7 +110,7 @@
112
110
  "core-js": "^3.20.3",
113
111
  "cross-env": "^5.2.0",
114
112
  "css-loader": "4.0.0",
115
- "cypress": "10.7.0",
113
+ "cypress": "10.8.0",
116
114
  "cypress-axe": "^1.0.0",
117
115
  "cypress-each": "^1.11.0",
118
116
  "cypress-plugin-tab": "^1.0.5",