@madie/madie-design-system 1.2.62 → 2.0.0

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 (118) hide show
  1. package/.eslintrc.js +1 -1
  2. package/.storybook/.babelrc +2 -1
  3. package/.storybook/main.js +3 -11
  4. package/components/AutoComplete/AutoComplete.jsx +1 -1
  5. package/components/Button/Button.stories.js +0 -2
  6. package/components/DateField/DateField.jsx +1 -1
  7. package/components/DateField/DateField.stories.jsx +23 -10
  8. package/components/DateTimeField/DateTimeField.jsx +6 -2
  9. package/components/DateTimeField/DateTimeField.stories.jsx +29 -19
  10. package/components/Instant/Instant.stories.js +14 -6
  11. package/components/MadieAlert/MadieAlert.stories.js +35 -29
  12. package/components/MadieAlert/index.jsx +5 -5
  13. package/components/MadieConfirmDialog/MadieConfirmDialog.stories.js +17 -27
  14. package/components/MadieDeleteDialog/MadieDeleteDialog.stories.js +9 -18
  15. package/components/MadieDialog/MadieDialog.stories.js +45 -116
  16. package/components/MadieDialog/index.jsx +4 -2
  17. package/components/MadieDiscardDialog/MadieDiscardDialog.stories.js +5 -7
  18. package/components/MadieSpinner/MadieSpinner.stories.js +1 -3
  19. package/components/MadieTooltip/MadieTooltip.stories.js +7 -2
  20. package/components/Modal/Modal.stories.js +18 -89
  21. package/components/NotificationBanner/NotificationBanner.stories.js +17 -11
  22. package/components/NotificationBanner/index.js +3 -3
  23. package/components/NumberInput/NumberInput.stories.js +51 -63
  24. package/components/Popover/Popover.stories.js +6 -14
  25. package/components/Popover/index.js +2 -2
  26. package/components/RadioButton/RadioButton.jsx +4 -2
  27. package/components/RadioButton/RadioButton.stories.jsx +6 -2
  28. package/components/ReadOnlyTextField/ReadOnlyTextField.stories.js +4 -3
  29. package/components/ReadOnlyTextField/index.jsx +1 -1
  30. package/components/RichTextEditor/RichTextEditor.stories.js +10 -8
  31. package/components/RichTextEditor/index.jsx +14 -15
  32. package/components/Search/Search.stories.js +2 -4
  33. package/components/Select/Select.stories.js +59 -160
  34. package/components/Select/index.jsx +1 -1
  35. package/components/Tabs/Tabs.stories.js +78 -210
  36. package/components/TextArea/TextArea.stories.js +88 -108
  37. package/components/TextArea/index.jsx +1 -1
  38. package/components/TextField/TextField.stories.js +101 -124
  39. package/components/TextField/index.jsx +1 -1
  40. package/components/TimeField/TimeField.stories.js +18 -8
  41. package/components/Toast/Toast.stories.js +42 -102
  42. package/components/TruncateText/TruncateText.stories.js +22 -17
  43. package/components/hooks/useGetConfig.js +2 -2
  44. package/components/index.js +0 -24
  45. package/dist/browser.js +1 -1
  46. package/dist/index.js +1 -1
  47. package/dist/react/index.js +182 -51
  48. package/dist/react/index.js.LICENSE.txt +27 -24
  49. package/dist/react/index.js.map +1 -1
  50. package/eslint.config.js +56 -0
  51. package/index.js +7 -9
  52. package/package.json +43 -75
  53. package/test/components/Accordion.test.js +1 -1
  54. package/test/components/AutoComplete.test.js +11 -6
  55. package/test/components/Button.test.js +7 -3
  56. package/test/components/DateField.test.js +25 -29
  57. package/test/components/DateTimeField.test.js +21 -25
  58. package/test/components/Instant.test.js +1 -1
  59. package/test/components/MadieAlert.test.js +22 -22
  60. package/test/components/MadieConfirmDialog.test.js +42 -64
  61. package/test/components/MadieDeleteDialog.test.js +51 -69
  62. package/test/components/MadieDialog.test.js +13 -13
  63. package/test/components/MadieDiscardDialog.test.js +28 -45
  64. package/test/components/MadieSpinner.test.js +12 -17
  65. package/test/components/Modal.test.js +115 -0
  66. package/test/components/Pagination.test.js +2 -2
  67. package/test/components/RadioButton.test.js +7 -7
  68. package/test/components/ReadOnlyTextField.test.js +4 -2
  69. package/test/components/RichTextEditor.test.js +90 -6
  70. package/test/components/Search.test.js +75 -0
  71. package/test/components/Select.test.js +97 -107
  72. package/test/components/Tabs.test.js +22 -24
  73. package/test/components/TextArea.test.js +78 -92
  74. package/test/components/TextField.test.js +128 -147
  75. package/test/components/Toast.test.js +67 -78
  76. package/test/components/TruncateText.test.js +75 -0
  77. package/test/components/index.test.js +23 -0
  78. package/webpack.config.js +0 -1
  79. package/.eslintignore +0 -5
  80. package/components/Alert/Alert.stories.js +0 -70
  81. package/components/Alert/index.js +0 -55
  82. package/components/Breadcrumb/Breadcrumb.md +0 -28
  83. package/components/Breadcrumb/Breadcrumb.stories.js +0 -76
  84. package/components/Breadcrumb/index.js +0 -92
  85. package/components/CalloutBox/CalloutBox.stories.js +0 -94
  86. package/components/CalloutBox/index.js +0 -109
  87. package/components/Card/Card.stories.js +0 -163
  88. package/components/Card/index.js +0 -144
  89. package/components/Dropdown/Dropdown.stories.js +0 -94
  90. package/components/Dropdown/index.js +0 -85
  91. package/components/Error/Collapsible.jsx +0 -93
  92. package/components/Error/ErrorUI.jsx +0 -31
  93. package/components/Error/error.js +0 -26
  94. package/components/FlashNotification/FlashNotificationUI.jsx +0 -91
  95. package/components/FlashNotification/index.js +0 -30
  96. package/components/Footer/Footer.stories.js +0 -20
  97. package/components/Footer/FooterUI.jsx +0 -137
  98. package/components/Footer/LegacyFooterUI.jsx +0 -204
  99. package/components/Footer/SocialLinks.jsx +0 -63
  100. package/components/Footer/Subscribe.jsx +0 -34
  101. package/components/Footer/footer.js +0 -30
  102. package/components/Infotip/Infotip.jsx +0 -75
  103. package/components/Infotip/Infotip.stories.js +0 -52
  104. package/components/Infotip/InfotipIcon.jsx +0 -41
  105. package/components/Infotip/index.js +0 -3
  106. package/components/Link/Link.stories.js +0 -82
  107. package/components/Link/index.js +0 -61
  108. package/components/Spinner/index.js +0 -9
  109. package/components/TextInput/TextInput.stories.js +0 -118
  110. package/components/TextInput/index.js +0 -137
  111. package/components/Tooltip/Tooltip.jsx +0 -88
  112. package/components/Tooltip/Tooltip.stories.js +0 -80
  113. package/components/Tooltip/index.js +0 -3
  114. package/components/Tooltip/position.js +0 -76
  115. package/test/components/ErrorUI.test.js +0 -32
  116. package/test/components/FooterUI.test.js +0 -122
  117. package/test/components/Infotip.test.js +0 -76
  118. package/test/components/Tooltip.test.js +0 -147
@@ -1,82 +0,0 @@
1
- import React from "react";
2
- import DSLink from "./index";
3
- import { withKnobs } from "@storybook/addon-knobs";
4
- import OpenInNewIcon from "@mui/icons-material/OpenInNew";
5
-
6
- export default {
7
- title: "Link",
8
- component: DSLink,
9
- decorators: [withKnobs],
10
- };
11
-
12
- export const LinkLabel = () => <DSLink href="#">Link Label</DSLink>;
13
-
14
- export const LinkColorVariants = () => (
15
- <>
16
- <div className=" qpp-dark-background qpp-u-padding--16">
17
- <DSLink href="#" variant="white">
18
- Link Label
19
- </DSLink>
20
- </div>
21
- <p>
22
- <DSLink href="#" variant="gray">
23
- Link Label
24
- </DSLink>
25
- </p>
26
- </>
27
- );
28
-
29
- export const inlineLinks = () => (
30
- <div className="qpp-u-padding--16">
31
- <p className="qpp-u-width--60">
32
- Aenean lacinia <DSLink href="#">inline link</DSLink> nulla sed{" "}
33
- <DSLink href="#">inline link</DSLink>. Integer posuere erat a ante
34
- venenatis dapibus posuere velit aliquet. Integer posuere erat a ante
35
- venenatis <DSLink href="#">inline link</DSLink> dapibus posuere
36
- velit aliquet.
37
- </p>
38
- </div>
39
- );
40
-
41
- export const inlineLinksDarkBackground = () => (
42
- <div className="qpp-dark-background qpp-u-padding--16">
43
- Aenean lacinia{" "}
44
- <DSLink href="#" variant="white">
45
- inline link
46
- </DSLink>{" "}
47
- nulla sed{" "}
48
- <DSLink href="#" variant="white">
49
- inline link
50
- </DSLink>
51
- . Integer posuere erat a ante venenatis dapibus posuere velit aliquet.
52
- Integer posuere erat a ante venenatis{" "}
53
- <DSLink href="#" variant="white">
54
- inline link
55
- </DSLink>{" "}
56
- dapibus posuere velit aliquet.
57
- </div>
58
- );
59
-
60
- export const linkWithIcon = () => {
61
- const icon = <OpenInNewIcon classes={{ root: "qpp-icon-mat" }} />;
62
- return (
63
- <div className="qpp-u-padding--16">
64
- <DSLink href="#">
65
- Standalone Link With Icon
66
- {icon}
67
- </DSLink>{" "}
68
- <p className=" qpp-u-width--60">
69
- Aenean lacinia{" "}
70
- <DSLink href="#">
71
- inline link
72
- {icon}
73
- </DSLink>{" "}
74
- nulla sed <DSLink href="#">inline link {icon}</DSLink>. Integer
75
- posuere erat a ante venenatis dapibus posuere velit aliquet.
76
- Integer posuere erat a ante venenatis{" "}
77
- <DSLink href="#">inline link {icon}</DSLink> dapibus posuere
78
- velit aliquet.
79
- </p>
80
- </div>
81
- );
82
- };
@@ -1,61 +0,0 @@
1
- import React from "react";
2
- import PropTypes from "prop-types";
3
-
4
- const VARIANTS = ["white", "gray"];
5
-
6
- const DSLink = ({
7
- className,
8
- href,
9
- download,
10
- ariaLabel,
11
- onClick,
12
- children,
13
- variant,
14
- ...rest
15
- }) => {
16
- let linkClass = "qpp-c-link";
17
- if (VARIANTS.includes(variant)) {
18
- variant === "gray"
19
- ? (linkClass = linkClass.concat(" ", "qpp-u-color--gray-60"))
20
- : (linkClass = linkClass.concat(" ", `qpp-u-color--${variant}`));
21
- }
22
-
23
- if (className) {
24
- linkClass = linkClass.concat(" ", className);
25
- }
26
-
27
- return (
28
- <a
29
- aria-label={ariaLabel}
30
- className={linkClass || ""}
31
- href={href}
32
- download={download}
33
- onClick={onClick}
34
- {...rest}
35
- >
36
- {children}
37
- </a>
38
- );
39
- };
40
-
41
- DSLink.propTypes = {
42
- children: PropTypes.node,
43
- className: PropTypes.string,
44
- href: PropTypes.string,
45
- ariaLabel: PropTypes.string,
46
- onClick: PropTypes.func,
47
- download: PropTypes.bool,
48
- variant: PropTypes.oneOf(VARIANTS),
49
- };
50
-
51
- DSLink.defaultProps = {
52
- children: null,
53
- className: "",
54
- href: "",
55
- ariaLabel: null,
56
- onClick: () => null,
57
- download: false,
58
- variant: null,
59
- };
60
-
61
- export default DSLink;
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- import { render } from "react-dom";
3
- import DSSpinner from "@cmsgov/design-system/dist/components/Spinner/Spinner";
4
-
5
- export default class Spinner {
6
- constructor(options) {
7
- render(<DSSpinner />, options.rootElement);
8
- }
9
- }
@@ -1,118 +0,0 @@
1
- import React from "react";
2
- import PropTypes from "prop-types";
3
- import TextInput from "./index";
4
- import { withKnobs } from "@storybook/addon-knobs";
5
-
6
- export default {
7
- title: "Text Input",
8
- component: TextInput,
9
- decorators: [withKnobs],
10
- };
11
-
12
- const optionalProps = {
13
- "aria-label": "example label",
14
- };
15
-
16
- const Wrapper = ({ children }) => (
17
- <div className="qpp-u-padding--16">{children}</div>
18
- );
19
- Wrapper.propTypes = {
20
- children: PropTypes.node,
21
- };
22
-
23
- export const InputField = () => (
24
- <Wrapper>
25
- <TextInput
26
- style={{ width: "auto" }}
27
- id="example"
28
- name="single-example"
29
- value="Example value"
30
- label="Input Field"
31
- {...optionalProps}
32
- />
33
- </Wrapper>
34
- );
35
-
36
- export const InputFieldWithPlaceholder = () => (
37
- <Wrapper>
38
- <TextInput
39
- id="placeholder-example"
40
- name="placheholder"
41
- label="Placeholder Example"
42
- placeholder="Placeholder value"
43
- />
44
- </Wrapper>
45
- );
46
- export const DisabledInputField = () => (
47
- <Wrapper>
48
- <TextInput
49
- disabled={true}
50
- id="disabled-example"
51
- name="disabled_example"
52
- value="Example value"
53
- label="Disabled Example"
54
- />
55
- </Wrapper>
56
- );
57
-
58
- export const FocusedInputField = () => (
59
- <Wrapper>
60
- <TextInput
61
- id="focused-example"
62
- name="focused_example"
63
- value="Example value"
64
- label="Focused Example"
65
- className="qpp-c-text-input--focus"
66
- />
67
- </Wrapper>
68
- );
69
-
70
- export const ErrorInputField = () => (
71
- <Wrapper>
72
- <TextInput
73
- className="qpp-u-margin-bottom--8"
74
- id="error-example"
75
- name="error_example"
76
- value="Example value"
77
- error="Error Message"
78
- label="Error Example"
79
- />
80
- </Wrapper>
81
- );
82
-
83
- export const SuccessInputField = () => (
84
- <Wrapper>
85
- <TextInput
86
- variant="success"
87
- id="success-example"
88
- name="success"
89
- value="Example value"
90
- label="Success Example"
91
- />
92
- </Wrapper>
93
- );
94
-
95
- export const InputFieldWithHint = () => (
96
- <Wrapper>
97
- <TextInput
98
- className="qpp-u-margin-bottom--8"
99
- id="hint-example"
100
- name="hint"
101
- value="Example value"
102
- label="Hint Example"
103
- hint="Hint Message"
104
- />
105
- </Wrapper>
106
- );
107
-
108
- export const BigInput = () => (
109
- <Wrapper>
110
- <TextInput
111
- id="big-example"
112
- name="hint"
113
- value="Example value"
114
- label="Big Example"
115
- size="big"
116
- />
117
- </Wrapper>
118
- );
@@ -1,137 +0,0 @@
1
- import React from "react";
2
- import PropTypes from "prop-types";
3
-
4
- const TextInput = ({
5
- id,
6
- name,
7
- placeholder,
8
- disabled,
9
- required,
10
- size,
11
- className,
12
- label,
13
- minLength,
14
- maxLength,
15
- hint,
16
- errorLabel,
17
- error,
18
- autoComplete,
19
- onChange,
20
- onKeyPress,
21
- style,
22
- dataTestId,
23
- type,
24
- innerRef,
25
- number,
26
- variant,
27
- parentElement,
28
- ...props
29
- }) => {
30
- const ContainerElement = parentElement || "span";
31
- const numberProps = {
32
- pattern: "[0-9]*",
33
- };
34
-
35
- const textInputClass = [
36
- "qpp-c-text-input",
37
- variant === "success" && !error && "qpp-c-text-input--success",
38
- error && "qpp-c-text-input--error",
39
- size === "big" && "qpp-c-text-input--big",
40
- className,
41
- ]
42
- .filter(Boolean)
43
- .join(" ");
44
-
45
- return (
46
- <ContainerElement className="qppds ds-text-input-container">
47
- {label && (
48
- <label className="qpp-u-margin-bottom--8" htmlFor={id}>
49
- {label}
50
- </label>
51
- )}
52
- <input
53
- {...(number ? numberProps : {})}
54
- style={style}
55
- data-testid={dataTestId}
56
- type={type}
57
- className={textInputClass || ""}
58
- id={id}
59
- name={name}
60
- placeholder={placeholder}
61
- disabled={disabled}
62
- minLength={minLength}
63
- maxLength={maxLength}
64
- required={required}
65
- autoComplete={autoComplete}
66
- onChange={onChange}
67
- onKeyPress={onKeyPress}
68
- ref={innerRef}
69
- {...props}
70
- />
71
- {hint && <span className="qpp-hint-message">{hint}</span>}
72
- {error && (
73
- <span
74
- aria-label={errorLabel}
75
- role="alert"
76
- className="qpp-error-message"
77
- >
78
- {error}
79
- </span>
80
- )}
81
- </ContainerElement>
82
- );
83
- };
84
-
85
- TextInput.propTypes = {
86
- id: PropTypes.string,
87
- name: PropTypes.string,
88
- placeholder: PropTypes.string,
89
- disabled: PropTypes.bool,
90
- required: PropTypes.bool,
91
- className: PropTypes.string,
92
- minLength: PropTypes.string,
93
- maxLength: PropTypes.string,
94
- hint: PropTypes.string,
95
- errorLabel: PropTypes.string,
96
- error: PropTypes.string,
97
- autoComplete: PropTypes.string,
98
- onChange: PropTypes.func,
99
- onKeyPress: PropTypes.func,
100
- style: PropTypes.object,
101
- dataTestId: PropTypes.string,
102
- type: PropTypes.string,
103
- innerRef: PropTypes.string,
104
- number: PropTypes.bool,
105
- variant: PropTypes.oneOf(["success"]),
106
- parentElement: PropTypes.string,
107
- label: PropTypes.string,
108
- size: PropTypes.oneOf(["big"]),
109
- };
110
-
111
- TextInput.defaultProps = {
112
- id: "",
113
- name: "",
114
- placeholder: null,
115
- disabled: false,
116
- required: false,
117
- className: "",
118
- minLength: "",
119
- maxLength: "",
120
- error: null,
121
- errorLabel: null,
122
- hint: null,
123
- autoComplete: "on",
124
- onChange: () => null,
125
- onKeyPress: () => null,
126
- style: null,
127
- dataTestId: "",
128
- type: "text",
129
- innerRef: null,
130
- number: false,
131
- variant: null,
132
- parentElement: "span",
133
- label: null,
134
- size: null,
135
- };
136
-
137
- export default TextInput;
@@ -1,88 +0,0 @@
1
- import React, { cloneElement, useLayoutEffect, useRef } from "react";
2
- import PropTypes from "prop-types";
3
- import positionTip, { positionTriangle } from "./position";
4
- import { useTooltip, TooltipPopup } from "@reach/tooltip";
5
- import Portal from "@reach/portal";
6
-
7
- // TODO: investigate ways to allow more styling via css? the triangle
8
- // positioning effect issue may need to be resolved to allow for this.
9
- const TEXT_COLOR = "#FFF";
10
- const BACKGROUND_COLOR = "#333";
11
-
12
- /**
13
- * Generic styled tooltip component.
14
- * Corresponding styles: /styles/components/_tooltip.scss
15
- *
16
- * Extends implementation from @reach/tooltip:
17
- * https://reacttraining.com/reach-ui/tooltip
18
- */
19
- const Tooltip = ({ children, label, ariaLabel, DEBUG_STYLE }) => {
20
- const [trigger, tooltip] = useTooltip({ DEBUG_STYLE });
21
- const { isVisible, triggerRect } = tooltip;
22
- const tooltipPopupRef = useRef();
23
- const triangleRef = useRef();
24
-
25
- useLayoutEffect(() => {
26
- // For some reason, the forwardRef for the tooltipPopup points to an undefined
27
- // dom element when we first render the portal containing the triangle. Using
28
- // an effect here will ensure that the ref is available when applying styles.
29
- // TODO: investigate and make issue for @reach-ui/tooltip?
30
- if (isVisible && tooltipPopupRef.current && triggerRect) {
31
- const tooltipRect = tooltipPopupRef.current.getBoundingClientRect();
32
- const positionCssText = positionTriangle(triggerRect, tooltipRect);
33
- const cssText = `
34
- position: absolute;
35
- width: 0;
36
- height: 0;
37
- ${positionCssText}
38
- border-top-color: ${BACKGROUND_COLOR};
39
- border-bottom-color: ${BACKGROUND_COLOR};
40
- z-index: 1;
41
- `;
42
- triangleRef.current.style.cssText = cssText;
43
- }
44
- });
45
-
46
- return (
47
- <>
48
- {cloneElement(children, trigger)}
49
- <TooltipPopup
50
- {...tooltip}
51
- label={label}
52
- ariaLabel={ariaLabel}
53
- style={{
54
- background: BACKGROUND_COLOR,
55
- color: TEXT_COLOR,
56
- }}
57
- ref={tooltipPopupRef}
58
- position={positionTip}
59
- />
60
- {isVisible && (
61
- <Portal>
62
- <div
63
- ref={triangleRef}
64
- style={{
65
- position: "absolute",
66
- width: 0,
67
- height: 0,
68
- }}
69
- />
70
- </Portal>
71
- )}
72
- </>
73
- );
74
- };
75
-
76
- Tooltip.propTypes = {
77
- children: PropTypes.node.isRequired,
78
- label: PropTypes.node.isRequired,
79
- ariaLabel: PropTypes.string,
80
- DEBUG_STYLE: PropTypes.bool,
81
- };
82
-
83
- Tooltip.defaultProps = {
84
- ariaLabel: undefined,
85
- DEBUG_STYLE: undefined,
86
- };
87
-
88
- export default Tooltip;
@@ -1,80 +0,0 @@
1
- import React from "react";
2
- import Tooltip from "./index";
3
-
4
- const offsetDecorator = (storyFn) => (
5
- <div style={{ margin: "80px" }}>{storyFn()}</div>
6
- );
7
-
8
- export default {
9
- title: "Tooltip",
10
- component: Tooltip,
11
- };
12
-
13
- export const ExampleTooltip = () => (
14
- <Tooltip label="FOOBAR">
15
- <button>
16
- <span>Tooltip Trigger</span>
17
- </button>
18
- </Tooltip>
19
- );
20
-
21
- ExampleTooltip.storyName = "example Tooltip";
22
- ExampleTooltip.decorators = [offsetDecorator];
23
-
24
- export const AriaLabelTooltip = () => (
25
- <Tooltip label="FOOBAR" ariaLabel="foobar">
26
- <button>
27
- <span>Tooltip Trigger</span>
28
- </button>
29
- </Tooltip>
30
- );
31
-
32
- AriaLabelTooltip.storyName = "using ariaLabel";
33
- AriaLabelTooltip.decorators = [offsetDecorator];
34
-
35
- export const MultipleTooltip = () => (
36
- <>
37
- <Tooltip label="Tooltip 1">
38
- <button>
39
- <span>Tooltip 1 Trigger</span>
40
- </button>
41
- </Tooltip>
42
- <Tooltip label="Tooltip 2">
43
- <button>
44
- <span>Tooltip 2 Trigger</span>
45
- </button>
46
- </Tooltip>
47
- <Tooltip label="Tooltip 3">
48
- <button>
49
- <span>Tooltip 3 Trigger</span>
50
- </button>
51
- </Tooltip>
52
- </>
53
- );
54
-
55
- MultipleTooltip.storyName = "multiple Tooltips";
56
- MultipleTooltip.decorators = [offsetDecorator];
57
-
58
- export const InputElementTooltip = () => (
59
- <form>
60
- <label htmlFor="foobar" style={{ marginRight: "5px " }}>
61
- Text Input
62
- </label>
63
- <Tooltip label="example input label tooltip">
64
- <input type="text" name="foobar" />
65
- </Tooltip>
66
- </form>
67
- );
68
-
69
- InputElementTooltip.storyName = "on text input";
70
- InputElementTooltip.decorators = [offsetDecorator];
71
-
72
- export const PositionedBelowTargetTooltip = () => (
73
- <Tooltip label="FOOBAR">
74
- <button>
75
- <span>Tooltip Trigger</span>
76
- </button>
77
- </Tooltip>
78
- );
79
-
80
- PositionedBelowTargetTooltip.storyName = "positioned below trigger";
@@ -1,3 +0,0 @@
1
- import Tooltip from "./Tooltip";
2
-
3
- export default Tooltip;
@@ -1,76 +0,0 @@
1
- const OFFSET = 12; // modified from reach-ui/tooltip OFFSET value
2
- const TRIANGLE_SCALE_X = 6;
3
- const TRIANGLE_SCALE_Y = 8;
4
-
5
- const isDirectionUp = (triggerRect, tooltipRect) => {
6
- const collisions = {
7
- top: triggerRect.top - tooltipRect.height < 0,
8
- bottom:
9
- window.innerHeight <
10
- triggerRect.bottom + tooltipRect.height + OFFSET,
11
- };
12
-
13
- return !collisions.top || collisions.bottom;
14
- };
15
-
16
- // modified from @reach/tooltip default positioning function
17
- // positions Tooltip relative to trigger
18
- // https://github.com/reach/reach-ui/blob/master/packages/tooltip/src/index.tsx#L532
19
- const positionTip = (triggerRect, tooltipRect) => {
20
- if (!triggerRect || !tooltipRect) {
21
- return {};
22
- }
23
-
24
- const triggerCenter = triggerRect.left + triggerRect.width / 2;
25
- const left = triggerCenter - tooltipRect.width / 2;
26
- const maxLeft = window.innerWidth - tooltipRect.width - 2;
27
- const centerLeft =
28
- Math.min(Math.max(2, left), maxLeft) + window.pageXOffset;
29
-
30
- const directionUp = isDirectionUp(triggerRect, tooltipRect);
31
-
32
- return {
33
- left: `${centerLeft}px`,
34
- top: directionUp
35
- ? `${
36
- triggerRect.top -
37
- OFFSET -
38
- tooltipRect.height +
39
- window.pageYOffset
40
- }px`
41
- : `${
42
- triggerRect.top +
43
- OFFSET +
44
- triggerRect.height +
45
- window.pageYOffset
46
- }px`,
47
- };
48
- };
49
-
50
- export default positionTip;
51
-
52
- // position triangle relative to tooltip position
53
- // TODO: figure out a better way to render these updates from within react
54
- // rendering. This method causes an additional repaint after the Tooltip
55
- // has been rendered. may require changes to @reach/tooltip.
56
- export const positionTriangle = (triggerRect, tooltipRect) => {
57
- const directionUp = isDirectionUp(triggerRect, tooltipRect);
58
- const triangleTop = directionUp
59
- ? triggerRect.top + window.pageYOffset - OFFSET
60
- : triggerRect.bottom + window.pageYOffset + OFFSET - TRIANGLE_SCALE_Y;
61
-
62
- const triangleLeft =
63
- triggerRect.left - TRIANGLE_SCALE_X + triggerRect.width / 2;
64
-
65
- const triangleBorder = directionUp
66
- ? `border-top: ${TRIANGLE_SCALE_Y}px solid;`
67
- : `border-bottom: ${TRIANGLE_SCALE_Y}px solid;`;
68
-
69
- return `
70
- border-left: ${TRIANGLE_SCALE_X}px solid transparent;
71
- border-right: ${TRIANGLE_SCALE_X}px solid transparent;
72
- left: ${triangleLeft}px;
73
- top: ${triangleTop}px;
74
- ${triangleBorder}
75
- `;
76
- };
@@ -1,32 +0,0 @@
1
- import React from "react";
2
- import { render } from "@testing-library/react";
3
- import ErrorUI from "../../components/Error/ErrorUI";
4
-
5
- describe("ErrorUI", () => {
6
- it("renders a list of errors in HTML", () => {
7
- const code = "404";
8
- const type = "Bad thing happened";
9
- const message = [
10
- { contentTitle: "Not found", content: "test" },
11
- { contentTitle: "Image not found", content: "test number 2" },
12
- ];
13
- const { debug, container } = render(
14
- <ErrorUI type={type} code={code} message={message} />
15
- );
16
- expect(container.querySelector(".page-error")).toBeTruthy();
17
- expect(container.querySelector(".collapsible-details")).toBeTruthy();
18
- expect(container.querySelectorAll(".items li").length).toBe(2);
19
- });
20
-
21
- it("renders a string instead of an array", () => {
22
- const code = "404";
23
- const type = "Bad thing happened";
24
- const message = "Not found";
25
- const { getByText, container } = render(
26
- <ErrorUI type={type} code={code} message={message} />
27
- );
28
- expect(container.querySelector(".page-error")).toBeTruthy();
29
- expect(container.querySelector(".collapsible-details")).toBeTruthy();
30
- expect(getByText(/not found/i)).toBeTruthy();
31
- });
32
- });