@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.
- package/CHANGELOG.md +47 -0
- package/__perf__/withFlagGroup.tsx +7 -1
- package/dist/cjs/auto-dismiss-flag.js +4 -4
- package/dist/cjs/flag-actions.js +50 -6
- package/dist/cjs/flag-group.js +57 -19
- package/dist/cjs/flag-provider.js +6 -4
- package/dist/cjs/flag.js +85 -107
- package/dist/cjs/index.js +12 -12
- package/dist/cjs/internal/description.js +32 -0
- package/dist/cjs/internal/dismiss-button.js +83 -0
- package/dist/cjs/{expander.js → internal/expander.js} +15 -7
- package/dist/cjs/internal/index.js +39 -0
- package/dist/cjs/internal/title.js +32 -0
- package/dist/cjs/theme.js +84 -60
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/auto-dismiss-flag.js +2 -3
- package/dist/es2019/flag-actions.js +50 -32
- package/dist/es2019/flag-group.js +48 -65
- package/dist/es2019/flag.js +77 -162
- package/dist/es2019/internal/description.js +22 -0
- package/dist/es2019/internal/dismiss-button.js +63 -0
- package/dist/es2019/{expander.js → internal/expander.js} +14 -10
- package/dist/es2019/internal/index.js +4 -0
- package/dist/es2019/internal/title.js +22 -0
- package/dist/es2019/theme.js +78 -53
- package/dist/es2019/version.json +1 -1
- package/dist/esm/auto-dismiss-flag.js +2 -3
- package/dist/esm/flag-actions.js +49 -6
- package/dist/esm/flag-group.js +52 -16
- package/dist/esm/flag-provider.js +4 -3
- package/dist/esm/flag.js +81 -102
- package/dist/esm/internal/description.js +23 -0
- package/dist/esm/internal/dismiss-button.js +63 -0
- package/dist/esm/{expander.js → internal/expander.js} +14 -5
- package/dist/esm/internal/index.js +4 -0
- package/dist/esm/internal/title.js +23 -0
- package/dist/esm/theme.js +80 -53
- package/dist/esm/version.json +1 -1
- package/dist/types/auto-dismiss-flag.d.ts +1 -0
- package/dist/types/flag-actions.d.ts +4 -4
- package/dist/types/flag-group.d.ts +2 -2
- package/dist/types/flag.d.ts +2 -1
- package/dist/types/internal/description.d.ts +7 -0
- package/dist/types/internal/dismiss-button.d.ts +11 -0
- package/dist/types/internal/expander.d.ts +8 -0
- package/dist/types/internal/index.d.ts +4 -0
- package/dist/types/internal/title.d.ts +6 -0
- package/dist/types/theme.d.ts +2 -1
- package/package.json +14 -10
- package/dist/types/expander.d.ts +0 -9
- 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
|
-
|
|
29
|
-
position: absolute
|
|
30
|
-
|
|
31
|
-
transition: transform ${flagAnimationTime}ms ease-in-out
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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:
|
|
79
|
-
fade:
|
|
90
|
+
enterFrom: "left",
|
|
91
|
+
fade: "inout",
|
|
80
92
|
duration: flagAnimationTime,
|
|
81
93
|
animationTimingFunction: () => easeIn
|
|
82
94
|
}, props => jsx("div", _extends({}, props, {
|
|
83
|
-
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:
|
|
105
|
-
|
|
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
|
};
|
package/dist/es2019/flag.js
CHANGED
|
@@ -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
|
|
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,
|
|
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.
|
|
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
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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:
|
|
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,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;
|