@atlaskit/flag 14.4.1 → 14.5.2

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 (51) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/__perf__/withFlagGroup.tsx +7 -1
  3. package/dist/cjs/auto-dismiss-flag.js +4 -4
  4. package/dist/cjs/flag-actions.js +50 -6
  5. package/dist/cjs/flag-group.js +57 -19
  6. package/dist/cjs/flag-provider.js +6 -4
  7. package/dist/cjs/flag.js +85 -107
  8. package/dist/cjs/index.js +12 -12
  9. package/dist/cjs/internal/description.js +32 -0
  10. package/dist/cjs/internal/dismiss-button.js +83 -0
  11. package/dist/cjs/{expander.js → internal/expander.js} +15 -7
  12. package/dist/cjs/internal/index.js +39 -0
  13. package/dist/cjs/internal/title.js +32 -0
  14. package/dist/cjs/theme.js +84 -60
  15. package/dist/cjs/version.json +1 -1
  16. package/dist/es2019/auto-dismiss-flag.js +2 -3
  17. package/dist/es2019/flag-actions.js +50 -32
  18. package/dist/es2019/flag-group.js +48 -65
  19. package/dist/es2019/flag.js +77 -162
  20. package/dist/es2019/internal/description.js +22 -0
  21. package/dist/es2019/internal/dismiss-button.js +63 -0
  22. package/dist/es2019/{expander.js → internal/expander.js} +14 -10
  23. package/dist/es2019/internal/index.js +4 -0
  24. package/dist/es2019/internal/title.js +22 -0
  25. package/dist/es2019/theme.js +78 -53
  26. package/dist/es2019/version.json +1 -1
  27. package/dist/esm/auto-dismiss-flag.js +2 -3
  28. package/dist/esm/flag-actions.js +49 -6
  29. package/dist/esm/flag-group.js +52 -16
  30. package/dist/esm/flag-provider.js +4 -3
  31. package/dist/esm/flag.js +81 -102
  32. package/dist/esm/internal/description.js +23 -0
  33. package/dist/esm/internal/dismiss-button.js +63 -0
  34. package/dist/esm/{expander.js → internal/expander.js} +14 -5
  35. package/dist/esm/internal/index.js +4 -0
  36. package/dist/esm/internal/title.js +23 -0
  37. package/dist/esm/theme.js +80 -53
  38. package/dist/esm/version.json +1 -1
  39. package/dist/types/auto-dismiss-flag.d.ts +1 -0
  40. package/dist/types/flag-actions.d.ts +4 -4
  41. package/dist/types/flag-group.d.ts +2 -2
  42. package/dist/types/flag.d.ts +2 -1
  43. package/dist/types/internal/description.d.ts +7 -0
  44. package/dist/types/internal/dismiss-button.d.ts +11 -0
  45. package/dist/types/internal/expander.d.ts +8 -0
  46. package/dist/types/internal/index.d.ts +4 -0
  47. package/dist/types/internal/title.d.ts +6 -0
  48. package/dist/types/theme.d.ts +2 -1
  49. package/package.json +14 -10
  50. package/dist/types/expander.d.ts +0 -9
  51. package/expander/package.json +0 -7
@@ -4,6 +4,8 @@ import _extends from "@babel/runtime/helpers/extends";
4
4
  import { Children, createContext, useContext, useMemo } from 'react';
5
5
  import { css, jsx } from '@emotion/core';
6
6
  import { easeIn, ExitingPersistence, SlideIn } from '@atlaskit/motion';
7
+ import VisuallyHidden from '@atlaskit/visually-hidden';
8
+ import noop from '@atlaskit/ds-lib/noop';
7
9
  import Portal from '@atlaskit/portal';
8
10
  import { gridSize as getGridSize, layers } from '@atlaskit/theme/constants';
9
11
  const gridSize = getGridSize();
@@ -11,9 +13,6 @@ export const flagWidth = gridSize * 50;
11
13
  export const flagAnimationTime = 400;
12
14
  const flagBottom = gridSize * 6;
13
15
  const flagLeft = gridSize * 10;
14
-
15
- function noop() {}
16
-
17
16
  const defaultFlagGroupContext = {
18
17
  onDismissed: () => {},
19
18
  isDismissAllowed: false
@@ -24,38 +23,51 @@ export function useFlagGroup() {
24
23
  } // transition: none is set on first-of-type to prevent a bug in Firefox
25
24
  // that causes a broken transition
26
25
 
27
- const baseStyles = `
28
- bottom: 0;
29
- position: absolute;
30
- width: ${flagWidth}px;
31
- transition: transform ${flagAnimationTime}ms ease-in-out;
32
-
33
- @media (max-width: 560px) {
34
- width: 100vw;
35
- }
36
-
37
- &:first-of-type {
38
- transition: none;
39
- transform: translate(0,0);
26
+ const baseStyles = css({
27
+ width: flagWidth,
28
+ position: 'absolute',
29
+ bottom: 0,
30
+ transition: `transform ${flagAnimationTime}ms ease-in-out`,
31
+ '@media (max-width: 560px)': {
32
+ width: '100vw'
33
+ },
34
+ ':first-of-type': {
35
+ transform: `translate(0,0)`,
36
+ transition: 'none'
37
+ },
38
+ ':nth-of-type(n + 2)': {
39
+ animationDuration: '0ms',
40
+ transform: `translateX(0) translateY(100%) translateY(${2 * gridSize}px)`
41
+ },
42
+ ':nth-of-type(1)': {
43
+ zIndex: 5
44
+ },
45
+ ':nth-of-type(2)': {
46
+ zIndex: 4
47
+ },
48
+ '&:nth-of-type(n + 4)': {
49
+ visibility: 'hidden'
40
50
  }
51
+ }); // Transform needed to push up while 1st flag is leaving
52
+ // Exiting time should match the exiting time of motion so is halved
41
53
 
42
- &:nth-of-type(n + 2) {
43
- animation-duration: 0ms;
44
- transform: translateX(0) translateY(100%) translateY(${2 * gridSize}px);
54
+ const dismissAllowedStyles = css({
55
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
56
+ '&& + *': {
57
+ transform: `translate(0, 0)`,
58
+ transitionDuration: `${flagAnimationTime / 2}ms`
45
59
  }
46
-
47
- /* Layer the 'primary' flag above the 'secondary' flag */
48
- &:nth-of-type(1) {
49
- z-index: 5;
50
- }
51
- &:nth-of-type(2) {
52
- z-index: 4;
53
- }
54
-
55
- &:nth-of-type(n + 4) {
56
- visibility: hidden;
60
+ });
61
+ const flagGroupContainerStyles = css({
62
+ position: 'fixed',
63
+ zIndex: layers.flag(),
64
+ bottom: flagBottom,
65
+ left: flagLeft,
66
+ '@media (max-width: 560px)': {
67
+ bottom: 0,
68
+ left: 0
57
69
  }
58
- `;
70
+ });
59
71
 
60
72
  const FlagGroup = props => {
61
73
  const {
@@ -75,21 +87,12 @@ const FlagGroup = props => {
75
87
  return children && typeof children === 'object' ? Children.map(children, (flag, index) => {
76
88
  const isDismissAllowed = index === 0;
77
89
  return jsx(SlideIn, {
78
- enterFrom: 'left',
79
- fade: 'inout',
90
+ enterFrom: "left",
91
+ fade: "inout",
80
92
  duration: flagAnimationTime,
81
93
  animationTimingFunction: () => easeIn
82
94
  }, props => jsx("div", _extends({}, props, {
83
- css: css`
84
- ${baseStyles}
85
- ${isDismissAllowed ? // Transform needed to push up while 1st flag is leaving
86
- // Exiting time should match the exiting time of motion so is halved
87
- `
88
- && + * {
89
- transform: translate(0, 0);
90
- transition-duration: ${flagAnimationTime / 2}ms
91
- }` : ''}
92
- `
95
+ css: [baseStyles, isDismissAllowed && dismissAllowedStyles]
93
96
  }), jsx(FlagGroupContext.Provider, {
94
97
  value: // Only the first flag should be able to be dismissed.
95
98
  isDismissAllowed ? dismissFlagContext : defaultFlagGroupContext
@@ -101,28 +104,8 @@ const FlagGroup = props => {
101
104
  zIndex: layers.flag()
102
105
  }, jsx("div", {
103
106
  id: id,
104
- css: css`
105
- bottom: ${flagBottom}px;
106
- left: ${flagLeft}px;
107
- position: fixed;
108
- z-index: ${layers.flag()};
109
- @media (max-width: 560px) {
110
- bottom: 0;
111
- left: 0;
112
- }
113
- `
114
- }, hasFlags ? jsx(LabelTag, {
115
- css: css`
116
- border: 0;
117
- clip: rect(1px, 1px, 1px, 1px);
118
- height: 1px;
119
- overflow: hidden;
120
- padding: 0;
121
- position: absolute;
122
- white-space: nowrap;
123
- width: 1px;
124
- `
125
- }, label) : null, jsx(ExitingPersistence, {
107
+ css: flagGroupContainerStyles
108
+ }, hasFlags ? jsx(VisuallyHidden, null, jsx(LabelTag, null, label)) : null, jsx(ExitingPersistence, {
126
109
  appear: false
127
110
  }, renderChildren())));
128
111
  };
@@ -3,28 +3,41 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  /** @jsx jsx */
4
4
  import { useCallback, useEffect, useState } from 'react';
5
5
  import { css, jsx } from '@emotion/core';
6
- import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
7
- import ChevronUpIcon from '@atlaskit/icon/glyph/chevron-up';
8
- import CrossIcon from '@atlaskit/icon/glyph/cross';
9
- import GlobalTheme from '@atlaskit/theme/components';
6
+ import { useGlobalTheme } from '@atlaskit/theme/components';
10
7
  import { borderRadius, gridSize as getGridSize, layers } from '@atlaskit/theme/constants';
11
8
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatformLeafEventHandler';
9
+ import noop from '@atlaskit/ds-lib/noop';
10
+ import FocusRing from '@atlaskit/focus-ring';
12
11
  import { DEFAULT_APPEARANCE } from './constants';
13
- import { flagBorderColor, flagShadowColor, getFlagBackgroundColor, getFlagFocusRingColor, getFlagTextColor } from './theme';
14
- import Expander from './expander';
12
+ import { flagBorderColor, flagShadowColor, getFlagBackgroundColor, getFlagTextColor, getFlagIconColor } from './theme';
15
13
  import Actions from './flag-actions';
16
14
  import { useFlagGroup } from './flag-group';
17
-
18
- function noop() {}
19
-
15
+ import { Title, Description, Expander, DismissButton } from './internal';
20
16
  const analyticsAttributes = {
21
17
  componentName: 'flag',
22
18
  packageName: "@atlaskit/flag",
23
- packageVersion: "14.4.1"
19
+ packageVersion: "14.5.2"
24
20
  };
25
21
  const gridSize = getGridSize();
26
22
  const doubleGridSize = gridSize * 2;
27
23
  const headerHeight = gridSize * 4;
24
+ const iconStyles = css({
25
+ display: 'flex',
26
+ height: headerHeight,
27
+ alignItems: 'center'
28
+ });
29
+ const flagHeaderStyles = css({
30
+ boxSizing: 'border-box',
31
+ width: '100%',
32
+ padding: doubleGridSize,
33
+ borderRadius: borderRadius()
34
+ });
35
+ const flagContainerStyles = css({
36
+ width: '100%',
37
+ zIndex: layers.flag(),
38
+ borderRadius: borderRadius(),
39
+ transition: 'background-color 200ms'
40
+ });
28
41
 
29
42
  const Flag = props => {
30
43
  const {
@@ -59,74 +72,14 @@ const Flag = props => {
59
72
  ...analyticsAttributes
60
73
  });
61
74
  const isBold = appearance !== DEFAULT_APPEARANCE;
62
- const renderToggleOrDismissButton = useCallback(({
63
- mode
64
- }) => {
65
- // If it is normal appearance a toggle button cannot be rendered
66
- // Ensure onDismissed is defined and isDismissAllowed is true to render
67
- // the dismiss button
68
- if (!isBold && !isDismissAllowed) {
69
- return null;
70
- } // If it is bold then ensure there is a description or actions to render
71
- // the toggle button
72
-
73
-
74
- if (isBold && !description && !actions.length) {
75
- return null;
75
+ const toggleExpand = useCallback(() => {
76
+ setIsExpanded(previous => !previous);
77
+ }, []);
78
+ const buttonActionCallback = useCallback(() => {
79
+ if (isDismissAllowed) {
80
+ onDismissedAnalytics(id);
76
81
  }
77
-
78
- let ButtonIcon = CrossIcon;
79
- let buttonLabel = 'Dismiss';
80
-
81
- let buttonAction = () => {
82
- if (isDismissAllowed) {
83
- onDismissedAnalytics(id);
84
- }
85
- };
86
-
87
- let size = 'small';
88
- let buttonTestId = testId && `${testId}-dismiss`;
89
- let a11yProps = {};
90
-
91
- if (isBold) {
92
- ButtonIcon = isExpanded ? ChevronUpIcon : ChevronDownIcon;
93
- buttonLabel = isExpanded ? 'Collapse' : 'Expand';
94
-
95
- buttonAction = () => setIsExpanded(!isExpanded);
96
-
97
- size = 'large';
98
- buttonTestId = testId && `${testId}-toggle`;
99
- a11yProps = {
100
- 'aria-expanded': isExpanded
101
- };
102
- }
103
-
104
- return jsx("button", _extends({
105
- css: css`
106
- appearance: none;
107
- background: none;
108
- border: none;
109
- border-radius: ${borderRadius()}px;
110
- color: ${getFlagTextColor(appearance, mode)};
111
- cursor: pointer;
112
- flex: 0 0 auto;
113
- line-height: 1;
114
- margin-left: ${gridSize}px;
115
- padding: 0;
116
- white-space: nowrap;
117
- &:focus {
118
- outline: none;
119
- box-shadow: 0 0 0 2px ${getFlagFocusRingColor(appearance, mode)};
120
- }
121
- `,
122
- onClick: buttonAction,
123
- "data-testid": buttonTestId,
124
- type: "button"
125
- }, a11yProps), jsx(ButtonIcon, {
126
- label: buttonLabel,
127
- size: size
128
- }));
129
- }, [actions.length, appearance, description, id, isBold, isDismissAllowed, isExpanded, onDismissedAnalytics, testId]);
82
+ }, [onDismissedAnalytics, id, isDismissAllowed]);
130
83
  useEffect(() => {
131
84
  // If buttons are removed as a prop, update isExpanded to be false
132
85
  if (isBold && isExpanded && !description && !actions.length) {
@@ -151,95 +104,57 @@ const Flag = props => {
151
104
  onMouseOut,
152
105
  onBlur: onBlurAnalytics
153
106
  };
154
- const OptionalDismissButton = renderToggleOrDismissButton;
155
- let boxShadow = `0 20px 32px -8px ${flagShadowColor}`;
107
+ let boxShadow = `var(--ds-shadow-overlay, ${`0 20px 32px -8px ${flagShadowColor}`})`;
156
108
 
157
109
  if (!isBold) {
158
- boxShadow = `0 0 1px ${flagBorderColor}, ${boxShadow}`;
110
+ boxShadow = `var(--ds-shadow-overlay, ${`0 0 1px ${flagBorderColor}, ${boxShadow}`})`;
159
111
  }
160
112
 
161
- return jsx(GlobalTheme.Consumer, null, tokens => {
162
- const mode = tokens.mode;
163
- const textColour = getFlagTextColor(appearance, mode);
164
- return jsx("div", _extends({
165
- css: css`
166
- background-color: ${getFlagBackgroundColor(appearance, mode)};
167
- border-radius: ${borderRadius()}px;
168
- box-shadow: ${boxShadow};
169
- color: ${textColour};
170
- transition: background-color 200ms;
171
- width: 100%;
172
- z-index: ${layers.flag()};
173
- `,
174
- role: "alert",
175
- "data-testid": testId
176
- }, autoDismissProps), jsx("div", {
177
- css: css`
178
- width: 100%;
179
- padding: ${doubleGridSize}px;
180
- box-sizing: border-box;
181
- border-radius: ${borderRadius()}px;
182
-
183
- &:focus-visible {
184
- outline: none;
185
- box-shadow: 0 0 0 2px
186
- ${getFlagFocusRingColor(appearance, mode)};
187
- }
188
-
189
- @supports not selector(*:focus-visible) {
190
- &:focus {
191
- outline: none;
192
- box-shadow: 0 0 0 2px
193
- ${getFlagFocusRingColor(appearance, mode)};
194
- }
195
- }
196
-
197
- @media screen and (forced-colors: active),
198
- screen and (-ms-high-contrast: active) {
199
- &:focus-visible {
200
- outline: 1px solid;
201
- }
202
- }
203
- ` // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
204
- ,
205
- tabIndex: 0
206
- }, jsx("div", {
207
- css: css`
208
- display: flex;
209
- align-items: center;
210
- height: ${headerHeight}px;
211
- `
212
- }, icon, jsx("span", {
213
- css: css`
214
- color: ${textColour};
215
- font-weight: 600;
216
- flex: 1;
217
- overflow: hidden;
218
- text-overflow: ellipsis;
219
- white-space: nowrap;
220
- padding: 0 0 0 ${doubleGridSize}px;
221
- `
222
- }, title), jsx(OptionalDismissButton, {
223
- mode: mode
224
- })), jsx(Expander, {
225
- isExpanded: !isBold || isExpanded,
226
- testId: testId
227
- }, description && jsx("div", {
228
- css: css`
229
- color: ${textColour};
230
- word-wrap: break-word;
231
- overflow: auto;
232
- max-height: 100px; /* height is defined as 5 lines maximum by design */
233
- `,
234
- "data-testid": testId && `${testId}-description`
235
- }, description), jsx(Actions, {
236
- actions: actions,
237
- appearance: appearance,
238
- linkComponent: linkComponent,
239
- testId: testId,
240
- mode: mode
241
- }))));
242
- });
113
+ const {
114
+ mode
115
+ } = useGlobalTheme();
116
+ const textColor = getFlagTextColor(appearance, mode);
117
+ const iconColor = getFlagIconColor(appearance, mode);
118
+ const isDismissable = isBold || isDismissAllowed;
119
+ return jsx("div", _extends({
120
+ style: {
121
+ color: textColor,
122
+ backgroundColor: getFlagBackgroundColor(appearance, mode),
123
+ boxShadow
124
+ },
125
+ css: flagContainerStyles,
126
+ role: "alert",
127
+ "data-testid": testId
128
+ }, autoDismissProps), jsx(FocusRing, null, jsx("div", {
129
+ css: flagHeaderStyles // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
130
+ ,
131
+ tabIndex: 0
132
+ }, jsx("div", {
133
+ style: {
134
+ color: iconColor
135
+ },
136
+ css: iconStyles
137
+ }, icon, jsx(Title, {
138
+ color: textColor
139
+ }, title), isDismissable ? !(isBold && !description && !actions.length) && jsx(DismissButton, {
140
+ testId: testId,
141
+ appearance: appearance,
142
+ isBold: isBold,
143
+ isExpanded: isExpanded,
144
+ onClick: isBold ? toggleExpand : buttonActionCallback
145
+ }) : null), jsx(Expander, {
146
+ isExpanded: !isBold || isExpanded,
147
+ testId: testId
148
+ }, description && jsx(Description, {
149
+ testId: testId && `${testId}-description`,
150
+ color: textColor
151
+ }, description), jsx(Actions, {
152
+ actions: actions,
153
+ appearance: appearance,
154
+ linkComponent: linkComponent,
155
+ testId: testId,
156
+ mode: mode
157
+ })))));
243
158
  };
244
159
 
245
160
  export default Flag;
@@ -0,0 +1,22 @@
1
+ /** @jsx jsx */
2
+ import { jsx, css } from '@emotion/core';
3
+ const descriptionStyles = css({
4
+ /* height is defined as 5 lines maximum by design */
5
+ maxHeight: 100,
6
+ overflow: 'auto',
7
+ wordWrap: 'break-word'
8
+ });
9
+
10
+ const Description = ({
11
+ color,
12
+ testId,
13
+ children
14
+ }) => jsx("div", {
15
+ style: {
16
+ color
17
+ },
18
+ css: descriptionStyles,
19
+ "data-testid": testId
20
+ }, children);
21
+
22
+ export default Description;
@@ -0,0 +1,63 @@
1
+ /** @jsx jsx */
2
+ import { memo } from 'react';
3
+ import { jsx, css } from '@emotion/core';
4
+ import FocusRing from '@atlaskit/focus-ring';
5
+ import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
6
+ import ChevronUpIcon from '@atlaskit/icon/glyph/chevron-up';
7
+ import CrossIcon from '@atlaskit/icon/glyph/cross';
8
+ import { borderRadius as getBorderRadius, gridSize as getGridSize } from '@atlaskit/theme/constants';
9
+ import { useGlobalTheme } from '@atlaskit/theme/components';
10
+ import { getFlagTextColor } from '../theme';
11
+ const gridSize = getGridSize();
12
+ const borderRadius = getBorderRadius();
13
+ const dismissButtonStyles = css({
14
+ marginLeft: gridSize,
15
+ padding: 0,
16
+ flex: '0 0 auto',
17
+ appearance: 'none',
18
+ background: 'none',
19
+ border: 'none',
20
+ borderRadius,
21
+ cursor: 'pointer',
22
+ lineHeight: '1',
23
+ whiteSpace: 'nowrap'
24
+ });
25
+
26
+ const DismissButton = ({
27
+ appearance,
28
+ onClick,
29
+ isBold,
30
+ isExpanded,
31
+ testId
32
+ }) => {
33
+ const {
34
+ mode
35
+ } = useGlobalTheme();
36
+ let ButtonIcon = CrossIcon;
37
+ let buttonLabel = 'Dismiss';
38
+ let size = 'small';
39
+ let buttonTestId = testId && `${testId}-dismiss`;
40
+
41
+ if (isBold) {
42
+ ButtonIcon = isExpanded ? ChevronUpIcon : ChevronDownIcon;
43
+ buttonLabel = isExpanded ? 'Collapse' : 'Expand';
44
+ size = 'large';
45
+ buttonTestId = testId && `${testId}-toggle`;
46
+ }
47
+
48
+ return jsx(FocusRing, null, jsx("button", {
49
+ style: {
50
+ color: getFlagTextColor(appearance, mode)
51
+ },
52
+ css: dismissButtonStyles,
53
+ onClick: onClick,
54
+ "data-testid": buttonTestId,
55
+ type: "button",
56
+ "aria-expanded": isBold ? isExpanded : undefined
57
+ }, jsx(ButtonIcon, {
58
+ label: buttonLabel,
59
+ size: size
60
+ })));
61
+ };
62
+
63
+ export default /*#__PURE__*/memo(DismissButton);
@@ -3,6 +3,19 @@ import { css, jsx } from '@emotion/core';
3
3
  import { ExitingPersistence, FadeIn } from '@atlaskit/motion';
4
4
  import { gridSize } from '@atlaskit/theme/constants';
5
5
  const paddingLeft = gridSize() * 5;
6
+ const expanderStyles = css({
7
+ display: 'flex',
8
+ minWidth: 0,
9
+ maxHeight: 0,
10
+ padding: `0 0 0 ${paddingLeft}px`,
11
+ justifyContent: 'center',
12
+ flex: '1 1 100%',
13
+ flexDirection: 'column',
14
+ transition: `max-height 0.3s`
15
+ });
16
+ const expandedStyles = css({
17
+ maxHeight: 150
18
+ });
6
19
 
7
20
  const Expander = ({
8
21
  children,
@@ -14,16 +27,7 @@ const Expander = ({
14
27
  // the the reveal because we don't know the height of the content.
15
28
  return jsx("div", {
16
29
  "aria-hidden": !isExpanded,
17
- css: css`
18
- max-height: ${isExpanded ? 150 : 0}px;
19
- transition: max-height 0.3s;
20
- display: flex;
21
- flex: 1 1 100%;
22
- flex-direction: column;
23
- justify-content: center;
24
- min-width: 0;
25
- padding: 0 0 0 ${paddingLeft}px;
26
- `,
30
+ css: [expanderStyles, isExpanded && expandedStyles],
27
31
  "data-testid": testId && `${testId}-expander`
28
32
  }, jsx(ExitingPersistence, {
29
33
  appear: true
@@ -0,0 +1,4 @@
1
+ export { default as Title } from './title';
2
+ export { default as Description } from './description';
3
+ export { default as Expander } from './expander';
4
+ export { default as DismissButton } from './dismiss-button';
@@ -0,0 +1,22 @@
1
+ /** @jsx jsx */
2
+ import { jsx, css } from '@emotion/core';
3
+ const titleStyles = css({
4
+ padding: `0 0 0 16px`,
5
+ flex: 1,
6
+ fontWeight: 600,
7
+ overflow: 'hidden',
8
+ textOverflow: 'ellipsis',
9
+ whiteSpace: 'nowrap'
10
+ });
11
+
12
+ const Title = ({
13
+ color,
14
+ children
15
+ }) => jsx("span", {
16
+ style: {
17
+ color
18
+ },
19
+ css: titleStyles
20
+ }, children);
21
+
22
+ export default Title;