@transferwise/components 46.76.0 → 46.78.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.
- package/build/alert/Alert.js +17 -13
- package/build/alert/Alert.js.map +1 -1
- package/build/alert/Alert.mjs +17 -13
- package/build/alert/Alert.mjs.map +1 -1
- package/build/avatar/Avatar.js +2 -7
- package/build/avatar/Avatar.js.map +1 -1
- package/build/avatar/Avatar.mjs +2 -7
- package/build/avatar/Avatar.mjs.map +1 -1
- package/build/badge/Badge.js +1 -10
- package/build/badge/Badge.js.map +1 -1
- package/build/badge/Badge.mjs +1 -10
- package/build/badge/Badge.mjs.map +1 -1
- package/build/circularButton/CircularButton.js +1 -1
- package/build/circularButton/CircularButton.js.map +1 -1
- package/build/circularButton/CircularButton.mjs +1 -1
- package/build/circularButton/CircularButton.mjs.map +1 -1
- package/build/common/circle/Circle.js +15 -2
- package/build/common/circle/Circle.js.map +1 -1
- package/build/common/circle/Circle.mjs +15 -2
- package/build/common/circle/Circle.mjs.map +1 -1
- package/build/i18n/de.json +5 -0
- package/build/i18n/de.json.js +5 -0
- package/build/i18n/de.json.js.map +1 -1
- package/build/i18n/de.json.mjs +5 -0
- package/build/i18n/de.json.mjs.map +1 -1
- package/build/i18n/es.json +5 -0
- package/build/i18n/es.json.js +5 -0
- package/build/i18n/es.json.js.map +1 -1
- package/build/i18n/es.json.mjs +5 -0
- package/build/i18n/es.json.mjs.map +1 -1
- package/build/i18n/fr.json +5 -0
- package/build/i18n/fr.json.js +5 -0
- package/build/i18n/fr.json.js.map +1 -1
- package/build/i18n/fr.json.mjs +5 -0
- package/build/i18n/fr.json.mjs.map +1 -1
- package/build/i18n/hu.json +5 -0
- package/build/i18n/hu.json.js +5 -0
- package/build/i18n/hu.json.js.map +1 -1
- package/build/i18n/hu.json.mjs +5 -0
- package/build/i18n/hu.json.mjs.map +1 -1
- package/build/i18n/id.json +5 -0
- package/build/i18n/id.json.js +5 -0
- package/build/i18n/id.json.js.map +1 -1
- package/build/i18n/id.json.mjs +5 -0
- package/build/i18n/id.json.mjs.map +1 -1
- package/build/i18n/it.json +5 -0
- package/build/i18n/it.json.js +5 -0
- package/build/i18n/it.json.js.map +1 -1
- package/build/i18n/it.json.mjs +5 -0
- package/build/i18n/it.json.mjs.map +1 -1
- package/build/i18n/ja.json +5 -0
- package/build/i18n/ja.json.js +5 -0
- package/build/i18n/ja.json.js.map +1 -1
- package/build/i18n/ja.json.mjs +5 -0
- package/build/i18n/ja.json.mjs.map +1 -1
- package/build/i18n/pl.json +5 -0
- package/build/i18n/pl.json.js +5 -0
- package/build/i18n/pl.json.js.map +1 -1
- package/build/i18n/pl.json.mjs +5 -0
- package/build/i18n/pl.json.mjs.map +1 -1
- package/build/i18n/pt.json +5 -0
- package/build/i18n/pt.json.js +5 -0
- package/build/i18n/pt.json.js.map +1 -1
- package/build/i18n/pt.json.mjs +5 -0
- package/build/i18n/pt.json.mjs.map +1 -1
- package/build/i18n/ro.json +5 -0
- package/build/i18n/ro.json.js +5 -0
- package/build/i18n/ro.json.js.map +1 -1
- package/build/i18n/ro.json.mjs +5 -0
- package/build/i18n/ro.json.mjs.map +1 -1
- package/build/i18n/ru.json +5 -0
- package/build/i18n/ru.json.js +5 -0
- package/build/i18n/ru.json.js.map +1 -1
- package/build/i18n/ru.json.mjs +5 -0
- package/build/i18n/ru.json.mjs.map +1 -1
- package/build/i18n/tr.json +5 -0
- package/build/i18n/tr.json.js +5 -0
- package/build/i18n/tr.json.js.map +1 -1
- package/build/i18n/tr.json.mjs +5 -0
- package/build/i18n/tr.json.mjs.map +1 -1
- package/build/main.css +46 -22
- package/build/statusIcon/StatusIcon.js +4 -4
- package/build/statusIcon/StatusIcon.js.map +1 -1
- package/build/statusIcon/StatusIcon.mjs +4 -4
- package/build/statusIcon/StatusIcon.mjs.map +1 -1
- package/build/styles/avatar/Avatar.css +29 -0
- package/build/styles/badge/Badge.css +6 -0
- package/build/styles/circularButton/CircularButton.css +2 -2
- package/build/styles/common/circle/Circle.css +4 -0
- package/build/styles/main.css +46 -22
- package/build/styles/statusIcon/StatusIcon.css +0 -20
- package/build/types/alert/Alert.d.ts +3 -11
- package/build/types/alert/Alert.d.ts.map +1 -1
- package/build/types/avatar/Avatar.d.ts.map +1 -1
- package/build/types/badge/Badge.d.ts.map +1 -1
- package/build/types/common/circle/Circle.d.ts +1 -1
- package/build/types/common/circle/Circle.d.ts.map +1 -1
- package/build/types/statusIcon/StatusIcon.d.ts +7 -3
- package/build/types/statusIcon/StatusIcon.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/alert/Alert.spec.story.tsx +85 -4
- package/src/alert/Alert.spec.tsx +36 -14
- package/src/alert/Alert.story.tsx +50 -35
- package/src/alert/Alert.tsx +22 -23
- package/src/avatar/Avatar.css +29 -0
- package/src/avatar/Avatar.less +12 -0
- package/src/avatar/Avatar.tsx +4 -8
- package/src/avatarWrapper/__snapshots__/AvatarWrapper.spec.tsx.snap +11 -22
- package/src/badge/Badge.css +6 -0
- package/src/badge/Badge.less +6 -0
- package/src/badge/Badge.tsx +1 -11
- package/src/circularButton/CircularButton.css +2 -2
- package/src/circularButton/CircularButton.less +1 -1
- package/src/circularButton/CircularButton.story.tsx +3 -0
- package/src/circularButton/CircularButton.tsx +1 -1
- package/src/circularButton/__snapshots__/CircularButton.spec.tsx.snap +10 -10
- package/src/common/circle/Circle.css +4 -0
- package/src/common/circle/Circle.less +6 -0
- package/src/common/circle/Circle.story.tsx +2 -2
- package/src/common/circle/Circle.tsx +25 -2
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +4 -8
- package/src/i18n/de.json +5 -0
- package/src/i18n/es.json +5 -0
- package/src/i18n/fr.json +5 -0
- package/src/i18n/hu.json +5 -0
- package/src/i18n/id.json +5 -0
- package/src/i18n/it.json +5 -0
- package/src/i18n/ja.json +5 -0
- package/src/i18n/pl.json +5 -0
- package/src/i18n/pt.json +5 -0
- package/src/i18n/ro.json +5 -0
- package/src/i18n/ru.json +5 -0
- package/src/i18n/tr.json +5 -0
- package/src/main.css +46 -22
- package/src/overlayHeader/__snapshots__/OverlayHeader.spec.tsx.snap +2 -4
- package/src/promoCard/PromoCard.spec.tsx +1 -1
- package/src/radio/__snapshots__/Radio.rtl.spec.tsx.snap +2 -4
- package/src/statusIcon/StatusIcon.css +0 -20
- package/src/statusIcon/StatusIcon.less +0 -17
- package/src/statusIcon/StatusIcon.spec.tsx +2 -21
- package/src/statusIcon/StatusIcon.story.tsx +32 -1
- package/src/statusIcon/StatusIcon.tsx +11 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/Avatar.tsx"],"names":[],"mappings":"AAOA,KAAK,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEhD,KAAK,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkBD,QAAA,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/Avatar.tsx"],"names":[],"mappings":"AAOA,KAAK,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEhD,KAAK,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkBD,QAAA,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAwCjC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/badge/Badge.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/badge/Badge.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,KAAK,eAAe,GAAG,UAAU,CAAC;AAElC,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,eAAe,GAAG,SAAS,CAAC;IAC/C,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,WAAW,CAAC;AAEhB,QAAA,MAAM,KAAK,qFAOR,UAAU,gCAkBZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Circle.d.ts","sourceRoot":"","sources":["../../../../src/common/circle/Circle.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Circle.d.ts","sourceRoot":"","sources":["../../../../src/common/circle/Circle.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,OAAO,CAAC;AAKnD,MAAM,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEzD,MAAM,MAAM,KAAK,GAAG;IAClB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IACvB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;AAenC,QAAA,MAAM,MAAM;IA5BV;;OAEG;SACE,KAAK,CAAC,WAAW;IACtB;;OAEG;WACI,SAAS;IAChB;;;OAGG;gBACS,OAAO;4EA8CnB,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { SizeSmall, SizeMedium, SizeLarge, Sentiment } from '../common';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated use `16 | 24 | 32 | 40 | 48 | 56 | 72` component instead
|
|
4
|
+
*/
|
|
5
|
+
type LegacySizes = SizeSmall | SizeMedium | SizeLarge;
|
|
2
6
|
export type StatusIconProps = {
|
|
3
|
-
sentiment
|
|
4
|
-
size
|
|
7
|
+
sentiment?: `${Sentiment}`;
|
|
8
|
+
size?: LegacySizes | 16 | 24 | 32 | 40 | 48 | 56 | 72;
|
|
5
9
|
/**
|
|
6
10
|
* Override for the sentiment's-derived, default, accessible
|
|
7
11
|
* name announced by the screen readers. <br />
|
|
@@ -9,6 +13,6 @@ export type StatusIconProps = {
|
|
|
9
13
|
* */
|
|
10
14
|
iconLabel?: string | null;
|
|
11
15
|
};
|
|
12
|
-
declare const StatusIcon: ({ sentiment, size: sizeProp, iconLabel
|
|
16
|
+
declare const StatusIcon: ({ sentiment, size: sizeProp, iconLabel }: StatusIconProps) => import("react").JSX.Element;
|
|
13
17
|
export default StatusIcon;
|
|
14
18
|
//# sourceMappingURL=StatusIcon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusIcon.d.ts","sourceRoot":"","sources":["../../../src/statusIcon/StatusIcon.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,WAAW,CAAC;AAM1F,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"StatusIcon.d.ts","sourceRoot":"","sources":["../../../src/statusIcon/StatusIcon.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,WAAW,CAAC;AAM1F;;GAEG;AACH,KAAK,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACtD;;;;SAIK;IACL,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAQF,QAAA,MAAM,UAAU,6CAA+D,eAAe,gCA8D7F,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/components",
|
|
3
|
-
"version": "46.
|
|
3
|
+
"version": "46.78.0",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -91,9 +91,9 @@
|
|
|
91
91
|
"rollup": "^4.18.1",
|
|
92
92
|
"rollup-preserve-directives": "^1.1.1",
|
|
93
93
|
"storybook": "^8.2.2",
|
|
94
|
+
"@transferwise/less-config": "3.1.0",
|
|
94
95
|
"@transferwise/neptune-css": "14.19.1",
|
|
95
|
-
"@wise/components-theming": "1.6.1"
|
|
96
|
-
"@transferwise/less-config": "3.1.0"
|
|
96
|
+
"@wise/components-theming": "1.6.1"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
99
|
"@transferwise/icons": "^3.13.1",
|
|
@@ -42,7 +42,7 @@ export const SimpleTrigger: Story = {
|
|
|
42
42
|
Trigger Alert
|
|
43
43
|
</Button>
|
|
44
44
|
|
|
45
|
-
{isActive && <Alert {...args}
|
|
45
|
+
{isActive && <Alert {...args} className="m-t-4" />}
|
|
46
46
|
</>
|
|
47
47
|
);
|
|
48
48
|
},
|
|
@@ -79,13 +79,13 @@ export const ComplexTrigger: Story = {
|
|
|
79
79
|
/>
|
|
80
80
|
</Field>
|
|
81
81
|
|
|
82
|
-
{isActive && <Alert
|
|
82
|
+
{isActive && <Alert {...args} className="m-t-2" />}
|
|
83
83
|
</>
|
|
84
84
|
);
|
|
85
85
|
},
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
export const
|
|
88
|
+
export const MultipleDynamicAlerts: Story = {
|
|
89
89
|
play: async ({ canvasElement }) => {
|
|
90
90
|
const canvas = within(canvasElement);
|
|
91
91
|
await expect(canvas.queryAllByRole('status')).toHaveLength(0);
|
|
@@ -125,9 +125,90 @@ export const BackendForFrontend: Story = {
|
|
|
125
125
|
</Button>
|
|
126
126
|
|
|
127
127
|
{alerts.map((props) => (
|
|
128
|
-
<Alert
|
|
128
|
+
<Alert {...props} key={props.title} className="m-t-3" />
|
|
129
129
|
))}
|
|
130
130
|
</>
|
|
131
131
|
);
|
|
132
132
|
},
|
|
133
133
|
};
|
|
134
|
+
|
|
135
|
+
/** Making sure using `active` is non-breaking **/
|
|
136
|
+
export const SimpleTriggerDeprecated: Story = {
|
|
137
|
+
name: 'Deprecated: Simple Trigger',
|
|
138
|
+
play: async ({ args, canvasElement }) => {
|
|
139
|
+
const canvas = within(canvasElement);
|
|
140
|
+
await wait();
|
|
141
|
+
await userEvent.tab();
|
|
142
|
+
await wait();
|
|
143
|
+
await userEvent.keyboard('{Enter}');
|
|
144
|
+
|
|
145
|
+
await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
|
|
146
|
+
await wait(1000);
|
|
147
|
+
await userEvent.keyboard('{Enter}');
|
|
148
|
+
await wait();
|
|
149
|
+
await waitFor(async () =>
|
|
150
|
+
expect(canvas.queryByText(args.message || '')).not.toBeInTheDocument(),
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
render: function Render(args) {
|
|
154
|
+
const [isActive, setIsActive] = useState(false);
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<>
|
|
158
|
+
<Button htmlType="button" onClick={() => setIsActive((current) => !current)}>
|
|
159
|
+
Trigger Alert
|
|
160
|
+
</Button>
|
|
161
|
+
|
|
162
|
+
<Alert {...args} active={isActive} className="m-t-4" />
|
|
163
|
+
</>
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/** Making sure using `active` is non-breaking **/
|
|
169
|
+
export const ComplexTriggerDeprecated: Story = {
|
|
170
|
+
name: 'Deprecated: Complex Trigger',
|
|
171
|
+
play: async ({ args, canvasElement }) => {
|
|
172
|
+
const canvas = within(canvasElement);
|
|
173
|
+
await wait();
|
|
174
|
+
await userEvent.tab();
|
|
175
|
+
await wait();
|
|
176
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
177
|
+
await wait();
|
|
178
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
179
|
+
await wait();
|
|
180
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
181
|
+
await wait();
|
|
182
|
+
await userEvent.keyboard('{Enter}');
|
|
183
|
+
|
|
184
|
+
await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
|
|
185
|
+
await wait(1000);
|
|
186
|
+
await userEvent.keyboard('{Enter}');
|
|
187
|
+
await wait();
|
|
188
|
+
await userEvent.keyboard('{ArrowUp}');
|
|
189
|
+
await wait();
|
|
190
|
+
await userEvent.keyboard('{Enter}');
|
|
191
|
+
// await waitFor(async () => expect(canvas.queryByText(args.message || '')).not.toBeInTheDocument());
|
|
192
|
+
},
|
|
193
|
+
render: function Render(args) {
|
|
194
|
+
const [isActive, setIsActive] = useState(false);
|
|
195
|
+
const [value, setValue] = useState<string>();
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<>
|
|
199
|
+
<Field label="Select option to triger Alert">
|
|
200
|
+
<SelectInput
|
|
201
|
+
items={[
|
|
202
|
+
{ type: 'option', value: 'one' },
|
|
203
|
+
{ type: 'option', value: 'two' },
|
|
204
|
+
]}
|
|
205
|
+
onChange={setValue}
|
|
206
|
+
onClose={() => setIsActive(Boolean(value === 'two'))}
|
|
207
|
+
/>
|
|
208
|
+
</Field>
|
|
209
|
+
|
|
210
|
+
<Alert {...args} active={isActive} className="m-t-2" />
|
|
211
|
+
</>
|
|
212
|
+
);
|
|
213
|
+
},
|
|
214
|
+
};
|
package/src/alert/Alert.spec.tsx
CHANGED
|
@@ -4,7 +4,14 @@ import { ThemeProvider } from '@wise/components-theming';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
|
|
6
6
|
import { Sentiment, Size, Theme, Variant } from '../common';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
render,
|
|
9
|
+
cleanup,
|
|
10
|
+
screen,
|
|
11
|
+
userEvent as user,
|
|
12
|
+
fireEvent,
|
|
13
|
+
mockMatchMedia,
|
|
14
|
+
} from '../test-utils';
|
|
8
15
|
|
|
9
16
|
import Alert, { AlertAction, AlertArrowPosition, AlertType } from './Alert';
|
|
10
17
|
|
|
@@ -25,6 +32,9 @@ describe('Alert', () => {
|
|
|
25
32
|
let alert: HTMLElement;
|
|
26
33
|
let closeButton: HTMLElement;
|
|
27
34
|
let action: AlertAction;
|
|
35
|
+
const userEvent = user.setup({
|
|
36
|
+
advanceTimers: jest.advanceTimersByTimeAsync,
|
|
37
|
+
});
|
|
28
38
|
|
|
29
39
|
const classForType = (type: AlertType) => `alert-${type}`;
|
|
30
40
|
|
|
@@ -39,7 +49,6 @@ describe('Alert', () => {
|
|
|
39
49
|
});
|
|
40
50
|
|
|
41
51
|
afterEach(() => {
|
|
42
|
-
cleanup();
|
|
43
52
|
jest.clearAllMocks();
|
|
44
53
|
});
|
|
45
54
|
|
|
@@ -100,6 +109,24 @@ describe('Alert', () => {
|
|
|
100
109
|
);
|
|
101
110
|
});
|
|
102
111
|
|
|
112
|
+
it('active is ignored and a warning is logged', () => {
|
|
113
|
+
render(<Alert active message={message} />);
|
|
114
|
+
|
|
115
|
+
expect(screen.getByText(message)).toBeInTheDocument();
|
|
116
|
+
expect(mockedWarn).toHaveBeenCalledWith(
|
|
117
|
+
expect.stringMatching(/Alert component doesn't support `active`/),
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('dynamicRender is ignored and a warning is logged', () => {
|
|
122
|
+
render(<Alert dynamicRender message={message} />);
|
|
123
|
+
|
|
124
|
+
expect(screen.getByText(message)).toBeInTheDocument();
|
|
125
|
+
expect(mockedWarn).toHaveBeenCalledWith(
|
|
126
|
+
expect.stringMatching(/Alert component doesn't support.*?`dynamicRender`/),
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
|
|
103
130
|
it('dismissible is ignored and a warning is logged', () => {
|
|
104
131
|
({ container } = render(<Alert dismissible message={message} />));
|
|
105
132
|
|
|
@@ -252,18 +279,17 @@ describe('Alert', () => {
|
|
|
252
279
|
});
|
|
253
280
|
|
|
254
281
|
describe('onDismiss', () => {
|
|
255
|
-
it('renders the close button if onDismiss is provided', () => {
|
|
282
|
+
it('renders the close button if onDismiss is provided', async () => {
|
|
256
283
|
render(<Alert message={message} onDismiss={jest.fn()} />);
|
|
257
|
-
|
|
258
|
-
expect(
|
|
284
|
+
const button = await screen.findByRole('button', { name: 'Close' });
|
|
285
|
+
expect(button).toBeEnabled();
|
|
259
286
|
});
|
|
260
287
|
|
|
261
288
|
it('calls onDismiss when the close button is clicked', async () => {
|
|
262
289
|
const onDismiss = jest.fn();
|
|
263
|
-
|
|
264
290
|
render(<Alert message={message} onDismiss={onDismiss} />);
|
|
265
|
-
|
|
266
|
-
await userEvent.click(
|
|
291
|
+
const button = await screen.findByRole('button', { name: 'Close' });
|
|
292
|
+
await userEvent.click(button);
|
|
267
293
|
|
|
268
294
|
expect(onDismiss).toHaveBeenCalledTimes(1);
|
|
269
295
|
});
|
|
@@ -478,7 +504,7 @@ describe('Alert', () => {
|
|
|
478
504
|
});
|
|
479
505
|
});
|
|
480
506
|
|
|
481
|
-
describe('`active` prop', () => {
|
|
507
|
+
describe('`active` prop backward compatibility', () => {
|
|
482
508
|
it('should render wrapper and alert if `active` is unset', () => {
|
|
483
509
|
render(<Alert message={message} />);
|
|
484
510
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
@@ -492,13 +518,9 @@ describe('Alert', () => {
|
|
|
492
518
|
});
|
|
493
519
|
|
|
494
520
|
it('should render wrapper and alert if `active` is set', () => {
|
|
495
|
-
render(<Alert message={message} />);
|
|
521
|
+
render(<Alert message={message} active />);
|
|
496
522
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
497
523
|
expect(screen.getByText(message)).toBeInTheDocument();
|
|
498
524
|
});
|
|
499
525
|
});
|
|
500
|
-
|
|
501
|
-
describe('dynamicRender', () => {
|
|
502
|
-
it('should', () => {});
|
|
503
|
-
});
|
|
504
526
|
});
|
|
@@ -12,10 +12,8 @@ export default {
|
|
|
12
12
|
title: 'Feedback/Alert',
|
|
13
13
|
args: {
|
|
14
14
|
type: Sentiment.POSITIVE,
|
|
15
|
-
dynamicRender: false,
|
|
16
15
|
message:
|
|
17
16
|
'Payments sent to your bank details **today** might not arrive in time for the holidays.',
|
|
18
|
-
active: true,
|
|
19
17
|
},
|
|
20
18
|
argTypes: {
|
|
21
19
|
arrow: {
|
|
@@ -107,35 +105,43 @@ export const WithTitle: Story = {
|
|
|
107
105
|
};
|
|
108
106
|
|
|
109
107
|
/**
|
|
110
|
-
* For ARIA live region to function correctly with screen readers,
|
|
108
|
+
* For ARIA live region to function correctly with screen readers (SR),
|
|
111
109
|
* the container with an appropriate ARIA role (in the case of this
|
|
112
110
|
* component, it's `status` or `alert`) must be rendered first.
|
|
113
111
|
* Once present in the accessibility tree (AT), its dynamic contents
|
|
114
112
|
* will be announced correctly.
|
|
115
113
|
*
|
|
116
114
|
* It's not a problem if your page includes an Alert that is initially
|
|
117
|
-
* visible
|
|
118
|
-
*
|
|
119
|
-
*
|
|
115
|
+
* visible at the very first render, but if it appears as a result of
|
|
116
|
+
* user interaction or is async, e.g. BE-driven, then the screen reader
|
|
117
|
+
* might not announce it correctly. It becomes even more tricky if an
|
|
118
|
+
* Alert is triggerred by a component that causes refocusing or introduces
|
|
119
|
+
* many modifications to the AT, such as MoneyInput, for example, as that
|
|
120
|
+
* entirely hijacks screen-reader's attention and prevents it from
|
|
121
|
+
* announcing live region changes.
|
|
120
122
|
*
|
|
121
|
-
* In order for this to work, we've introduced a
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
123
|
+
* In order for this to work, we've introduced a simple mechanism which
|
|
124
|
+
* overcomes all of the above:
|
|
125
|
+
* 1. On the component mount, we render the live region wrapper.
|
|
126
|
+
* 2. We also render the actual Alert but set `aria-hidden` on it.
|
|
127
|
+
* 3. After 175ms, which has been confirmed as sufficient delay for
|
|
128
|
+
* the SRs to become responsive after trigger's activity, we remove the
|
|
129
|
+
* `aria-hidden` attribute, which, in turn, initiates the announcements.
|
|
128
130
|
*
|
|
129
|
-
*
|
|
131
|
+
* **NB:** While this approach has no visual side-effects (e.g. layout
|
|
132
|
+
* shift), it makes the Alert hidden from the assistive tech for 175ms.
|
|
133
|
+
* It's our belief that such short pause between announcements is
|
|
134
|
+
* negligible for the user.
|
|
130
135
|
*/
|
|
131
136
|
export const DynamicRender: Story = {
|
|
132
137
|
render: function Render(args) {
|
|
133
|
-
const [
|
|
138
|
+
const [isOneActive, setIsOneActive] = useState(false);
|
|
139
|
+
const [isTwoActive, setIsTwoActive] = useState(false);
|
|
134
140
|
const [value, setValue] = useState<string>();
|
|
135
141
|
|
|
136
142
|
return (
|
|
137
143
|
<>
|
|
138
|
-
<Button htmlType="button" onClick={() =>
|
|
144
|
+
<Button htmlType="button" onClick={() => setIsOneActive(true)}>
|
|
139
145
|
Trigger Alert
|
|
140
146
|
</Button>
|
|
141
147
|
|
|
@@ -146,11 +152,16 @@ export const DynamicRender: Story = {
|
|
|
146
152
|
{ type: 'option', value: 'two' },
|
|
147
153
|
]}
|
|
148
154
|
onChange={setValue}
|
|
149
|
-
onClose={() =>
|
|
155
|
+
onClose={() => setIsTwoActive(value === 'two')}
|
|
150
156
|
/>
|
|
151
157
|
</Field>
|
|
152
158
|
|
|
153
|
-
{
|
|
159
|
+
{isOneActive && <Alert {...args}>This Alert has a simple trigger.</Alert>}
|
|
160
|
+
{isTwoActive && (
|
|
161
|
+
<Alert {...args} type={Sentiment.WARNING}>
|
|
162
|
+
This Alert has a complex trigger.
|
|
163
|
+
</Alert>
|
|
164
|
+
)}
|
|
154
165
|
</>
|
|
155
166
|
);
|
|
156
167
|
},
|
|
@@ -159,27 +170,33 @@ export const DynamicRender: Story = {
|
|
|
159
170
|
source: {
|
|
160
171
|
code: `
|
|
161
172
|
function Render(args) {
|
|
162
|
-
|
|
163
|
-
|
|
173
|
+
const [isOneActive, setIsOneActive] = useState(false);
|
|
174
|
+
const [isTwoActive, setIsTwoActive] = useState(false);
|
|
175
|
+
const [value, setValue] = useState<string>();
|
|
164
176
|
|
|
165
177
|
return (
|
|
166
178
|
<>
|
|
167
|
-
<Button htmlType="button" onClick={() =>
|
|
179
|
+
<Button htmlType="button" onClick={() => setIsOneActive(true)}>
|
|
168
180
|
Trigger Alert
|
|
169
181
|
</Button>
|
|
170
182
|
|
|
171
|
-
<Field label="Select
|
|
183
|
+
<Field label="Select \`two\` to triger Alert" className="m-t-3">
|
|
172
184
|
<SelectInput
|
|
173
185
|
items={[
|
|
174
186
|
{ type: 'option', value: 'one' },
|
|
175
187
|
{ type: 'option', value: 'two' },
|
|
176
188
|
]}
|
|
177
189
|
onChange={setValue}
|
|
178
|
-
onClose={() =>
|
|
190
|
+
onClose={() => setIsTwoActive(value === 'two')}
|
|
179
191
|
/>
|
|
180
192
|
</Field>
|
|
181
|
-
|
|
182
|
-
{
|
|
193
|
+
|
|
194
|
+
{isOneActive && <Alert {...args}>This Alert has a simple trigger.</Alert>}
|
|
195
|
+
{isTwoActive && (
|
|
196
|
+
<Alert {...args} type={Sentiment.WARNING}>
|
|
197
|
+
This Alert has a complex trigger.
|
|
198
|
+
</Alert>
|
|
199
|
+
)}
|
|
183
200
|
</>
|
|
184
201
|
);
|
|
185
202
|
}`,
|
|
@@ -210,16 +227,15 @@ const getAlerts = () => {
|
|
|
210
227
|
};
|
|
211
228
|
|
|
212
229
|
/**
|
|
213
|
-
*
|
|
214
|
-
* just about conditional rendering but also the fact
|
|
215
|
-
* know how many `Alert`s you'
|
|
216
|
-
*
|
|
217
|
-
* `dynamicRender` prop will work with those scenarios as well.
|
|
230
|
+
* Sometimes, especially when dealing with Backend for Frontend (BFF),
|
|
231
|
+
* it's not just about conditional rendering but also the fact that
|
|
232
|
+
* you don't know how many `Alert`s you'll need to render.
|
|
218
233
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
234
|
+
* If you have to inject multiple Alerts simultaneously into the page,
|
|
235
|
+
* please note that we currently have no means of guaranteeing the order
|
|
236
|
+
* in which they screen reader will read them out.
|
|
221
237
|
*/
|
|
222
|
-
export const
|
|
238
|
+
export const MultipleDynamicAlerts: Story = {
|
|
223
239
|
render: function Render() {
|
|
224
240
|
const [isActive, setIsActive] = useState(false);
|
|
225
241
|
const [alerts, setAlerts] = useState<AlertProps[]>([]);
|
|
@@ -237,7 +253,7 @@ export const BackendForFrontend: Story = {
|
|
|
237
253
|
</Button>
|
|
238
254
|
|
|
239
255
|
{alerts.map((props) => (
|
|
240
|
-
<Alert {...props} key={props.title}
|
|
256
|
+
<Alert {...props} key={props.title} className="m-t-3" />
|
|
241
257
|
))}
|
|
242
258
|
</>
|
|
243
259
|
);
|
|
@@ -267,7 +283,6 @@ function Render() {
|
|
|
267
283
|
{...props}
|
|
268
284
|
key={props.title}
|
|
269
285
|
className="m-t-3"
|
|
270
|
-
dynamicRender
|
|
271
286
|
/>
|
|
272
287
|
))}
|
|
273
288
|
</>
|
package/src/alert/Alert.tsx
CHANGED
|
@@ -64,17 +64,9 @@ export interface AlertProps {
|
|
|
64
64
|
/** The type dictates which icon and colour will be used */
|
|
65
65
|
type?: AlertType;
|
|
66
66
|
variant?: `${Variant}`;
|
|
67
|
-
/**
|
|
68
|
-
* Controls rendering of the Alert component. <br />
|
|
69
|
-
* Toggle this prop instead using conditional rendering and logical AND (&&)
|
|
70
|
-
* operator, to make the component work with screen readers.
|
|
71
|
-
* @deprecated use `dynamicRender`
|
|
72
|
-
* */
|
|
67
|
+
/** @deprecated Safe to remove */
|
|
73
68
|
active?: boolean;
|
|
74
|
-
/**
|
|
75
|
-
* Toggle this prop when dealing with multiple, dynamic Alerts, to make them
|
|
76
|
-
* work with screen readers. This is especially helpful for the BFF use cases.
|
|
77
|
-
* */
|
|
69
|
+
/** @deprecated Safe to remove */
|
|
78
70
|
dynamicRender?: boolean;
|
|
79
71
|
/** @deprecated Use `InlineAlert` instead. */
|
|
80
72
|
arrow?: `${AlertArrowPosition}`;
|
|
@@ -100,22 +92,30 @@ function resolveType(type: AlertType): AlertTypeResolved {
|
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
export default function Alert({
|
|
103
|
-
arrow,
|
|
104
95
|
action,
|
|
105
|
-
children,
|
|
106
96
|
className,
|
|
107
|
-
dismissible,
|
|
108
97
|
icon,
|
|
109
98
|
statusIconLabel,
|
|
110
99
|
onDismiss,
|
|
111
100
|
message,
|
|
112
|
-
size,
|
|
113
101
|
title,
|
|
114
102
|
type = 'neutral',
|
|
115
103
|
variant = 'desktop',
|
|
104
|
+
arrow,
|
|
105
|
+
children,
|
|
106
|
+
size,
|
|
107
|
+
dismissible,
|
|
116
108
|
active = true,
|
|
117
|
-
dynamicRender
|
|
109
|
+
dynamicRender,
|
|
118
110
|
}: AlertProps) {
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (active !== undefined || dynamicRender !== undefined) {
|
|
113
|
+
logActionRequired(
|
|
114
|
+
"Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.",
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}, [active, dynamicRender]);
|
|
118
|
+
|
|
119
119
|
useEffect(() => {
|
|
120
120
|
if (arrow !== undefined) {
|
|
121
121
|
logActionRequired(
|
|
@@ -157,14 +157,12 @@ export default function Alert({
|
|
|
157
157
|
|
|
158
158
|
const [shouldFire, setShouldFire] = useState<boolean>();
|
|
159
159
|
|
|
160
|
-
const [
|
|
160
|
+
const [shouldAnnounce, setShouldAnnounce] = useState<boolean>(false);
|
|
161
161
|
useEffect(() => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
}, [active, shouldShow, dynamicRender]);
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
setShouldAnnounce(true);
|
|
164
|
+
}, WDS_LIVE_REGION_DELAY_MS);
|
|
165
|
+
}, []);
|
|
168
166
|
|
|
169
167
|
const closeButtonReference = useRef<HTMLButtonElement>(null);
|
|
170
168
|
|
|
@@ -173,8 +171,9 @@ export default function Alert({
|
|
|
173
171
|
role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}
|
|
174
172
|
className="wds-alert__liveRegion"
|
|
175
173
|
>
|
|
176
|
-
{
|
|
174
|
+
{active && (
|
|
177
175
|
<div
|
|
176
|
+
aria-hidden={shouldAnnounce ? undefined : 'true'}
|
|
178
177
|
className={clsx(
|
|
179
178
|
'alert d-flex',
|
|
180
179
|
`alert-${resolvedType}`,
|
package/src/avatar/Avatar.css
CHANGED
|
@@ -2,17 +2,26 @@
|
|
|
2
2
|
}@media (min-width: 768px) {
|
|
3
3
|
}.tw-avatar {
|
|
4
4
|
position: relative;
|
|
5
|
+
border-radius: 50%;
|
|
5
6
|
-webkit-user-select: none;
|
|
6
7
|
-moz-user-select: none;
|
|
7
8
|
user-select: none;
|
|
8
9
|
box-sizing: border-box;
|
|
9
10
|
}.tw-avatar .tw-avatar__content {
|
|
11
|
+
align-items: center;
|
|
10
12
|
background-color: rgba(134,167,189,0.10196);
|
|
11
13
|
background-color: #86a7bd1a;
|
|
12
14
|
background-color: var(--color-background-neutral);
|
|
15
|
+
border-radius: 50%;
|
|
16
|
+
color: #37517e;
|
|
17
|
+
color: var(--color-content-primary);
|
|
18
|
+
display: flex;
|
|
19
|
+
height: 100%;
|
|
20
|
+
justify-content: center;
|
|
13
21
|
max-height: 100%;
|
|
14
22
|
max-width: 100%;
|
|
15
23
|
overflow: hidden;
|
|
24
|
+
width: 100%;
|
|
16
25
|
}.tw-avatar--outlined {
|
|
17
26
|
border: 1px solid #00a2dd;
|
|
18
27
|
border: 1px solid var(--color-interactive-accent);
|
|
@@ -46,6 +55,10 @@
|
|
|
46
55
|
font-feature-settings: "ss01";
|
|
47
56
|
color: var(--color-dark-charcoal);
|
|
48
57
|
line-height: 1;
|
|
58
|
+
}.tw-avatar--24 {
|
|
59
|
+
min-width: 24px;
|
|
60
|
+
width: 24px;
|
|
61
|
+
height: 24px;
|
|
49
62
|
}.tw-avatar--24.tw-avatar--emoji,
|
|
50
63
|
.tw-avatar--24.tw-avatar--icon {
|
|
51
64
|
font-size: 12px;
|
|
@@ -70,6 +83,10 @@
|
|
|
70
83
|
border: 1px solid var(--color-border-overlay);
|
|
71
84
|
content: "";
|
|
72
85
|
border-radius: 50%;
|
|
86
|
+
}.tw-avatar--40 {
|
|
87
|
+
min-width: 40px;
|
|
88
|
+
width: 40px;
|
|
89
|
+
height: 40px;
|
|
73
90
|
}.tw-avatar--40.tw-avatar--emoji,
|
|
74
91
|
.tw-avatar--40.tw-avatar--icon {
|
|
75
92
|
font-size: 20px;
|
|
@@ -94,6 +111,10 @@
|
|
|
94
111
|
border: 1px solid var(--color-border-overlay);
|
|
95
112
|
content: "";
|
|
96
113
|
border-radius: 50%;
|
|
114
|
+
}.tw-avatar--48 {
|
|
115
|
+
min-width: 48px;
|
|
116
|
+
width: 48px;
|
|
117
|
+
height: 48px;
|
|
97
118
|
}.tw-avatar--48.tw-avatar--emoji,
|
|
98
119
|
.tw-avatar--48.tw-avatar--icon {
|
|
99
120
|
font-size: 24px;
|
|
@@ -118,6 +139,10 @@
|
|
|
118
139
|
border: 1px solid var(--color-border-overlay);
|
|
119
140
|
content: "";
|
|
120
141
|
border-radius: 50%;
|
|
142
|
+
}.tw-avatar--56 {
|
|
143
|
+
min-width: 56px;
|
|
144
|
+
width: 56px;
|
|
145
|
+
height: 56px;
|
|
121
146
|
}.tw-avatar--56.tw-avatar--emoji,
|
|
122
147
|
.tw-avatar--56.tw-avatar--icon {
|
|
123
148
|
font-size: 28px;
|
|
@@ -142,6 +167,10 @@
|
|
|
142
167
|
border: 1px solid var(--color-border-overlay);
|
|
143
168
|
content: "";
|
|
144
169
|
border-radius: 50%;
|
|
170
|
+
}.tw-avatar--72 {
|
|
171
|
+
min-width: 72px;
|
|
172
|
+
width: 72px;
|
|
173
|
+
height: 72px;
|
|
145
174
|
}.tw-avatar--72.tw-avatar--emoji,
|
|
146
175
|
.tw-avatar--72.tw-avatar--icon {
|
|
147
176
|
font-size: 36px;
|
package/src/avatar/Avatar.less
CHANGED
|
@@ -10,15 +10,23 @@
|
|
|
10
10
|
|
|
11
11
|
.tw-avatar {
|
|
12
12
|
position: relative;
|
|
13
|
+
border-radius: 50%;
|
|
13
14
|
user-select: none;
|
|
14
15
|
box-sizing: border-box;
|
|
15
16
|
|
|
16
17
|
& &__content {
|
|
18
|
+
align-items: center;
|
|
17
19
|
background-color: #86a7bd1a;
|
|
18
20
|
background-color: var(--color-background-neutral);
|
|
21
|
+
border-radius: 50%;
|
|
22
|
+
color: var(--color-content-primary);
|
|
23
|
+
display: flex;
|
|
24
|
+
height: 100%;
|
|
25
|
+
justify-content: center;
|
|
19
26
|
max-height: 100%;
|
|
20
27
|
max-width: 100%;
|
|
21
28
|
overflow: hidden;
|
|
29
|
+
width: 100%;
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
&--outlined {
|
|
@@ -109,6 +117,10 @@
|
|
|
109
117
|
.avatar-dimension(@avatar-size) {
|
|
110
118
|
@mask-size: 2px;
|
|
111
119
|
|
|
120
|
+
min-width: @avatar-size;
|
|
121
|
+
width: @avatar-size;
|
|
122
|
+
height: @avatar-size;
|
|
123
|
+
|
|
112
124
|
&.tw-avatar--emoji,
|
|
113
125
|
&.tw-avatar--icon {
|
|
114
126
|
font-size: @avatar-size * 0.5;
|